gdi32: Allow the PutImage entry point to optionally support stretching.
[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     DWORD old_colorwrite;
239
240     float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
241                       0.0f, 1.0f, 0.0f, 0.0f,
242                       0.0f, 0.0f, 1.0f, 0.0f,
243                       0.0f, 0.0f, 0.0f, 1.0f };
244
245     struct vertex unlitquad[] =
246     {
247         {-1.0f, -1.0f,   0.1f,                          0xffff0000},
248         {-1.0f,  0.0f,   0.1f,                          0xffff0000},
249         { 0.0f,  0.0f,   0.1f,                          0xffff0000},
250         { 0.0f, -1.0f,   0.1f,                          0xffff0000},
251     };
252     struct vertex litquad[] =
253     {
254         {-1.0f,  0.0f,   0.1f,                          0xff00ff00},
255         {-1.0f,  1.0f,   0.1f,                          0xff00ff00},
256         { 0.0f,  1.0f,   0.1f,                          0xff00ff00},
257         { 0.0f,  0.0f,   0.1f,                          0xff00ff00},
258     };
259     struct nvertex unlitnquad[] =
260     {
261         { 0.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
262         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
263         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
264         { 1.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
265     };
266     struct nvertex litnquad[] =
267     {
268         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
269         { 0.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
270         { 1.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
271         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
272     };
273     WORD Indices[] = {0, 1, 2, 2, 3, 0};
274
275     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
276     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
277
278     /* Setup some states that may cause issues */
279     hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
280     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
281     hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
282     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
283     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
284     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
285     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
286     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
287     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
288     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
289     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
290     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
291     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
292     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
293     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
294     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
295     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
296     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
297     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
298     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
299     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
300     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
301     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &old_colorwrite);
302     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
303     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
304     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
305
306     hr = IDirect3DDevice9_SetFVF(device, 0);
307     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
308
309     hr = IDirect3DDevice9_SetFVF(device, fvf);
310     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
311
312     hr = IDirect3DDevice9_BeginScene(device);
313     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
314     if(hr == D3D_OK)
315     {
316         /* No lights are defined... That means, lit vertices should be entirely black */
317         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
318         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
319         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
320                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
321         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
322
323         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
324         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
325         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
326                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
327         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
328
329         hr = IDirect3DDevice9_SetFVF(device, nfvf);
330         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
331
332         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
333         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
334         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
335                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
336         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
337
338         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
339         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
340         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
341                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
342         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
343
344         IDirect3DDevice9_EndScene(device);
345         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
346     }
347
348     color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
349     ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
350     color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
351     ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
352     color = getPixelColor(device, 480, 360); /* Lower left quad - unlit with normals */
353     ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
354     color = getPixelColor(device, 480, 120); /* Upper left quad - lit with normals */
355     ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
356
357     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
358
359     hr = IDirect3DDevice9_GetMaterial(device, &old_material);
360     ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
361     memset(&material, 0, sizeof(material));
362     material.Diffuse.r = 0.0;
363     material.Diffuse.g = 0.0;
364     material.Diffuse.b = 0.0;
365     material.Diffuse.a = 1.0;
366     material.Ambient.r = 0.0;
367     material.Ambient.g = 0.0;
368     material.Ambient.b = 0.0;
369     material.Ambient.a = 0.0;
370     material.Specular.r = 0.0;
371     material.Specular.g = 0.0;
372     material.Specular.b = 0.0;
373     material.Specular.a = 0.0;
374     material.Emissive.r = 0.0;
375     material.Emissive.g = 0.0;
376     material.Emissive.b = 0.0;
377     material.Emissive.a = 0.0;
378     material.Power = 0.0;
379     IDirect3DDevice9_SetMaterial(device, &material);
380     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
381
382     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
383     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
384     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
385     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
386
387     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
388     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
389     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
390     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
391     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
392     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
393     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
394     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
395
396     hr = IDirect3DDevice9_BeginScene(device);
397     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
398     if(SUCCEEDED(hr)) {
399         struct vertex lighting_test[] = {
400             {-1.0,   -1.0,   0.1,    0x8000ff00},
401             { 1.0,   -1.0,   0.1,    0x80000000},
402             {-1.0,    1.0,   0.1,    0x8000ff00},
403             { 1.0,    1.0,   0.1,    0x80000000}
404         };
405         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
406         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
407         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
408         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
409
410         hr = IDirect3DDevice9_EndScene(device);
411         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
412     }
413
414     color = getPixelColor(device, 320, 240);
415     ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
416     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
417
418     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
419     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
420     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
421     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
422     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
423     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
424     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
425     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
426     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, old_colorwrite);
427     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
428     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
429     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
430     hr = IDirect3DDevice9_SetMaterial(device, &old_material);
431     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
432 }
433
434 static void clear_test(IDirect3DDevice9 *device)
435 {
436     /* Tests the correctness of clearing parameters */
437     HRESULT hr;
438     D3DRECT rect[2];
439     D3DRECT rect_negneg;
440     DWORD color;
441     D3DVIEWPORT9 old_vp, vp;
442     RECT scissor;
443     DWORD oldColorWrite;
444     BOOL invalid_clear_failed = FALSE;
445
446     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
447     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
448
449     /* Positive x, negative y */
450     rect[0].x1 = 0;
451     rect[0].y1 = 480;
452     rect[0].x2 = 320;
453     rect[0].y2 = 240;
454
455     /* Positive x, positive y */
456     rect[1].x1 = 0;
457     rect[1].y1 = 0;
458     rect[1].x2 = 320;
459     rect[1].y2 = 240;
460     /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
461      * returns D3D_OK, but ignores the rectangle silently
462      */
463     hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
464     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
465     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
466
467     /* negative x, negative y */
468     rect_negneg.x1 = 640;
469     rect_negneg.y1 = 240;
470     rect_negneg.x2 = 320;
471     rect_negneg.y2 = 0;
472     hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
473     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
474     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
475
476     color = getPixelColor(device, 160, 360); /* lower left quad */
477     ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
478     color = getPixelColor(device, 160, 120); /* upper left quad */
479     if(invalid_clear_failed) {
480         /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
481         ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
482     } else {
483         /* If the negative rectangle was dropped silently, the correct ones are cleared */
484         ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
485     }
486     color = getPixelColor(device, 480, 360); /* lower right quad  */
487     ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
488     color = getPixelColor(device, 480, 120); /* upper right quad */
489     ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
490
491     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
492
493     /* Hack to work around a nvidia windows driver bug. The clear below is supposed to
494      * clear the red quad in the top left part of the render target. For some reason it
495      * doesn't work if the clear color is 0xffffffff on some versions of the Nvidia Windows
496      * driver(tested on 8.17.12.5896, Win7). A clear with a different color works around
497      * this bug and fixes the clear with the white color. Even 0xfeffffff works, but let's
498      * pick some obvious value
499      */
500     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbabe, 0.0, 0);
501     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
502
503     /* Test how the viewport affects clears */
504     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
505     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
506     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
507     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
508
509     vp.X = 160;
510     vp.Y = 120;
511     vp.Width = 160;
512     vp.Height = 120;
513     vp.MinZ = 0.0;
514     vp.MaxZ = 1.0;
515     hr = IDirect3DDevice9_SetViewport(device, &vp);
516     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
517     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
518     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
519
520     vp.X = 320;
521     vp.Y = 240;
522     vp.Width = 320;
523     vp.Height = 240;
524     vp.MinZ = 0.0;
525     vp.MaxZ = 1.0;
526     hr = IDirect3DDevice9_SetViewport(device, &vp);
527     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
528     rect[0].x1 = 160;
529     rect[0].y1 = 120;
530     rect[0].x2 = 480;
531     rect[0].y2 = 360;
532     hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
533     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
534
535     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
536     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
537
538     color = getPixelColor(device, 158, 118);
539     ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
540     color = getPixelColor(device, 162, 118);
541     ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
542     color = getPixelColor(device, 158, 122);
543     ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
544     color = getPixelColor(device, 162, 122);
545     ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
546
547     color = getPixelColor(device, 318, 238);
548     ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
549     color = getPixelColor(device, 322, 238);
550     ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
551     color = getPixelColor(device, 318, 242);
552     ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
553     color = getPixelColor(device, 322, 242);
554     ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
555
556     color = getPixelColor(device, 478, 358);
557     ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
558     color = getPixelColor(device, 482, 358);
559     ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
560     color = getPixelColor(device, 478, 362);
561     ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
562     color = getPixelColor(device, 482, 362);
563     ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
564
565     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
566
567     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
568     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
569
570     scissor.left = 160;
571     scissor.right = 480;
572     scissor.top = 120;
573     scissor.bottom = 360;
574     hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
575     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
576     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
577     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
578
579     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
580     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
581     hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
582     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
583
584     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
585     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
586
587     color = getPixelColor(device, 158, 118);
588     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
589     color = getPixelColor(device, 162, 118);
590     ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
591     color = getPixelColor(device, 158, 122);
592     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
593     color = getPixelColor(device, 162, 122);
594     ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
595
596     color = getPixelColor(device, 158, 358);
597     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
598     color = getPixelColor(device, 162, 358);
599     ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
600     color = getPixelColor(device, 158, 358);
601     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
602     color = getPixelColor(device, 162, 362);
603     ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
604
605     color = getPixelColor(device, 478, 118);
606     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
607     color = getPixelColor(device, 478, 122);
608     ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
609     color = getPixelColor(device, 482, 122);
610     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
611     color = getPixelColor(device, 482, 358);
612     ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
613
614     color = getPixelColor(device, 478, 358);
615     ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
616     color = getPixelColor(device, 478, 362);
617     ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
618     color = getPixelColor(device, 482, 358);
619     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
620     color = getPixelColor(device, 482, 362);
621     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
622
623     color = getPixelColor(device, 318, 238);
624     ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
625     color = getPixelColor(device, 318, 242);
626     ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
627     color = getPixelColor(device, 322, 238);
628     ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
629     color = getPixelColor(device, 322, 242);
630     ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
631
632     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
633
634     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
635     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
636     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
637     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
638
639     /* Same nvidia windows driver trouble with white clears as earlier in the same test */
640     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbeef, 0.0, 0);
641     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
642
643     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
644     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
645
646     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
647     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
648
649     /* Colorwriteenable does not affect the clear */
650     color = getPixelColor(device, 320, 240);
651     ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
652
653     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
654 }
655
656 static void color_fill_test(IDirect3DDevice9 *device)
657 {
658     HRESULT hr;
659     IDirect3DSurface9 *backbuffer = NULL;
660     IDirect3DSurface9 *rt_surface = NULL;
661     IDirect3DSurface9 *offscreen_surface = NULL;
662     DWORD fill_color, color;
663
664     /* Test ColorFill on a the backbuffer (should pass) */
665     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
666     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
667     if(backbuffer)
668     {
669         fill_color = 0x112233;
670         hr = IDirect3DDevice9_ColorFill(device, backbuffer, NULL, fill_color);
671         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
672
673         color = getPixelColor(device, 0, 0);
674         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
675
676         IDirect3DSurface9_Release(backbuffer);
677     }
678
679     /* Test ColorFill on a render target surface (should pass) */
680     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt_surface, NULL );
681     ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
682     if(rt_surface)
683     {
684         fill_color = 0x445566;
685         hr = IDirect3DDevice9_ColorFill(device, rt_surface, NULL, fill_color);
686         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
687
688         color = getPixelColorFromSurface(rt_surface, 0, 0);
689         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
690
691         IDirect3DSurface9_Release(rt_surface);
692     }
693
694     /* Test ColorFill on a offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
695     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
696             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen_surface, NULL);
697     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
698     if(offscreen_surface)
699     {
700         fill_color = 0x778899;
701         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, fill_color);
702         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
703
704         color = getPixelColorFromSurface(offscreen_surface, 0, 0);
705         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
706
707         IDirect3DSurface9_Release(offscreen_surface);
708     }
709
710     /* Try ColorFill on a offscreen surface in sysmem (should fail) */
711     offscreen_surface = NULL;
712     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
713             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &offscreen_surface, NULL);
714     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
715     if(offscreen_surface)
716     {
717         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, 0);
718         ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
719
720         IDirect3DSurface9_Release(offscreen_surface);
721     }
722 }
723
724 typedef struct {
725     float in[4];
726     DWORD out;
727 } test_data_t;
728
729 /*
730  *  c7      mova    ARGB            mov     ARGB
731  * -2.4     -2      0x00ffff00      -3      0x00ff0000
732  * -1.6     -2      0x00ffff00      -2      0x00ffff00
733  * -0.4      0      0x0000ffff      -1      0x0000ff00
734  *  0.4      0      0x0000ffff       0      0x0000ffff
735  *  1.6      2      0x00ff00ff       1      0x000000ff
736  *  2.4      2      0x00ff00ff       2      0x00ff00ff
737  */
738 static void test_mova(IDirect3DDevice9 *device)
739 {
740     static const DWORD mova_test[] = {
741         0xfffe0200,                                                             /* vs_2_0                       */
742         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
743         0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
744         0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
745         0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
746         0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
747         0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
748         0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
749         0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
750         0x0200002e, 0xb0010000, 0xa0000007,                                     /* mova a0.x, c7.x              */
751         0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000,                         /* mov oD0, c[a0.x + 3]         */
752         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
753         0x0000ffff                                                              /* END                          */
754     };
755     static const DWORD mov_test[] = {
756         0xfffe0101,                                                             /* vs_1_1                       */
757         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
758         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
759         0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
760         0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
761         0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
762         0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
763         0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
764         0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
765         0x00000001, 0xb0010000, 0xa0000007,                                     /* mov a0.x, c7.x               */
766         0x00000001, 0xd00f0000, 0xa0e42003,                                     /* mov oD0, c[a0.x + 3]         */
767         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
768         0x0000ffff                                                              /* END                          */
769     };
770
771     static const test_data_t test_data[2][6] = {
772         {
773             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
774             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
775             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
776             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
777             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
778             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
779         },
780         {
781             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
782             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
783             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
784             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
785             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
786             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
787         }
788     };
789
790     static const float quad[][3] = {
791         {-1.0f, -1.0f, 0.0f},
792         {-1.0f,  1.0f, 0.0f},
793         { 1.0f, -1.0f, 0.0f},
794         { 1.0f,  1.0f, 0.0f},
795     };
796
797     static const D3DVERTEXELEMENT9 decl_elements[] = {
798         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
799         D3DDECL_END()
800     };
801
802     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
803     IDirect3DVertexShader9 *mova_shader = NULL;
804     IDirect3DVertexShader9 *mov_shader = NULL;
805     HRESULT hr;
806     UINT i, j;
807
808     hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
809     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
810     hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
811     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
812     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
813     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
814     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
815     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
816
817     hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
818     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
819     for(j = 0; j < 2; ++j)
820     {
821         for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
822         {
823             DWORD color;
824
825             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
826             ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
827
828             hr = IDirect3DDevice9_BeginScene(device);
829             ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
830
831             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
832             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
833
834             hr = IDirect3DDevice9_EndScene(device);
835             ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
836
837             color = getPixelColor(device, 320, 240);
838             ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
839                test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
840
841             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
842             ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
843
844             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
845             ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
846         }
847         hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
848         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
849     }
850
851     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
852     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
853
854     IDirect3DVertexDeclaration9_Release(vertex_declaration);
855     IDirect3DVertexShader9_Release(mova_shader);
856     IDirect3DVertexShader9_Release(mov_shader);
857 }
858
859 struct sVertex {
860     float x, y, z;
861     DWORD diffuse;
862     DWORD specular;
863 };
864
865 struct sVertexT {
866     float x, y, z, rhw;
867     DWORD diffuse;
868     DWORD specular;
869 };
870
871 static void fog_test(IDirect3DDevice9 *device)
872 {
873     HRESULT hr;
874     D3DCOLOR color;
875     float start = 0.0f, end = 1.0f;
876     D3DCAPS9 caps;
877     int i;
878
879     /* Gets full z based fog with linear fog, no fog with specular color */
880     struct sVertex unstransformed_1[] = {
881         {-1,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
882         {-1,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
883         { 0,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
884         { 0,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
885     };
886     /* Ok, I am too lazy to deal with transform matrices */
887     struct sVertex unstransformed_2[] = {
888         {-1,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
889         {-1,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
890         { 0,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
891         { 0,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
892     };
893     /* Untransformed ones. Give them a different diffuse color to make the test look
894      * nicer. It also makes making sure that they are drawn correctly easier.
895      */
896     struct sVertexT transformed_1[] = {
897         {320,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
898         {640,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
899         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
900         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
901     };
902     struct sVertexT transformed_2[] = {
903         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
904         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
905         {640,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
906         {320,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
907     };
908     struct vertex rev_fog_quads[] = {
909        {-1.0,   -1.0,   0.1,    0x000000ff},
910        {-1.0,    0.0,   0.1,    0x000000ff},
911        { 0.0,    0.0,   0.1,    0x000000ff},
912        { 0.0,   -1.0,   0.1,    0x000000ff},
913
914        { 0.0,   -1.0,   0.9,    0x000000ff},
915        { 0.0,    0.0,   0.9,    0x000000ff},
916        { 1.0,    0.0,   0.9,    0x000000ff},
917        { 1.0,   -1.0,   0.9,    0x000000ff},
918
919        { 0.0,    0.0,   0.4,    0x000000ff},
920        { 0.0,    1.0,   0.4,    0x000000ff},
921        { 1.0,    1.0,   0.4,    0x000000ff},
922        { 1.0,    0.0,   0.4,    0x000000ff},
923
924        {-1.0,    0.0,   0.7,    0x000000ff},
925        {-1.0,    1.0,   0.7,    0x000000ff},
926        { 0.0,    1.0,   0.7,    0x000000ff},
927        { 0.0,    0.0,   0.7,    0x000000ff},
928     };
929     WORD Indices[] = {0, 1, 2, 2, 3, 0};
930
931     memset(&caps, 0, sizeof(caps));
932     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
933     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
934     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
935     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
936
937     /* Setup initial states: No lighting, fog on, fog color */
938     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
939     ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
940     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
941     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
942     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
943     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
944
945     /* First test: Both table fog and vertex fog off */
946     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
947     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
948     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
949     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
950
951     /* Start = 0, end = 1. Should be default, but set them */
952     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
953     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
954     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
955     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
956
957     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
958     {
959         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
960         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
961         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
962         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
963                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
964                                                      sizeof(unstransformed_1[0]));
965         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
966
967         /* That makes it use the Z value */
968         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
969         ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
970         /* Untransformed, vertex fog != none (or table fog != none):
971          * Use the Z value as input into the equation
972          */
973         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
974                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
975                                                      sizeof(unstransformed_1[0]));
976         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
977
978         /* transformed verts */
979         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
980         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
981         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
982         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
983                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
984                                                      sizeof(transformed_1[0]));
985         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
986
987         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
988         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
989         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
990          * equation
991          */
992         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
993                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
994                                                      sizeof(transformed_2[0]));
995         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
996
997         hr = IDirect3DDevice9_EndScene(device);
998         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
999     }
1000     else
1001     {
1002         ok(FALSE, "BeginScene failed\n");
1003     }
1004
1005     color = getPixelColor(device, 160, 360);
1006     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1007     color = getPixelColor(device, 160, 120);
1008     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
1009     color = getPixelColor(device, 480, 120);
1010     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1011     if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1012     {
1013         color = getPixelColor(device, 480, 360);
1014         ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
1015     }
1016     else
1017     {
1018         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1019          * The settings above result in no fogging with vertex fog
1020          */
1021         color = getPixelColor(device, 480, 120);
1022         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1023         trace("Info: Table fog not supported by this device\n");
1024     }
1025     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1026
1027     /* Now test the special case fogstart == fogend */
1028     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1029     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1030
1031     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1032     {
1033         start = 512;
1034         end = 512;
1035         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1036         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1037         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1038         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1039
1040         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1041         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1042         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1043         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1044         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1045         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1046
1047         /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
1048          * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
1049          * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
1050          * The third transformed quad remains unfogged because the fogcoords are read from the specular
1051          * color and has fixed fogstart and fogend.
1052          */
1053         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1054                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
1055                 sizeof(unstransformed_1[0]));
1056         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1057         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1058                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
1059                 sizeof(unstransformed_1[0]));
1060         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1061
1062         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1063         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1064         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1065         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1066                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1067                 sizeof(transformed_1[0]));
1068         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1069
1070         hr = IDirect3DDevice9_EndScene(device);
1071         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1072     }
1073     else
1074     {
1075         ok(FALSE, "BeginScene failed\n");
1076     }
1077     color = getPixelColor(device, 160, 360);
1078     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1079     color = getPixelColor(device, 160, 120);
1080     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1081     color = getPixelColor(device, 480, 120);
1082     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1083     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1084
1085     /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1086      * but without shaders it seems to work everywhere
1087      */
1088     end = 0.2;
1089     start = 0.8;
1090     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1091     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1092     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1093     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1094     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1095     ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1096
1097     /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1098      * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1099      * so skip this for now
1100      */
1101     for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1102         const char *mode = (i ? "table" : "vertex");
1103         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1104         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1105         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1106         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1107         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1108         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1109         hr = IDirect3DDevice9_BeginScene(device);
1110         ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1111         if(SUCCEEDED(hr)) {
1112             WORD Indices2[] = { 0,  1,  2,  2,  3, 0,
1113                                 4,  5,  6,  6,  7, 4,
1114                                 8,  9, 10, 10, 11, 8,
1115                             12, 13, 14, 14, 15, 12};
1116
1117             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1118                     16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1119                     sizeof(rev_fog_quads[0]));
1120             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1121
1122             hr = IDirect3DDevice9_EndScene(device);
1123             ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1124         }
1125         color = getPixelColor(device, 160, 360);
1126         ok(color_match(color, 0x0000ff00, 1),
1127                 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1128
1129         color = getPixelColor(device, 160, 120);
1130         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1131                 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1132
1133         color = getPixelColor(device, 480, 120);
1134         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1135                 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1136
1137         color = getPixelColor(device, 480, 360);
1138         ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1139
1140         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1141
1142         if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1143             skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1144             break;
1145         }
1146     }
1147     /* Turn off the fog master switch to avoid confusing other tests */
1148     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1149     ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1150     start = 0.0;
1151     end = 1.0;
1152     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1153     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1154     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1155     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1156     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1157     ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1158     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1159     ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1160 }
1161
1162 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1163  * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1164  * regardless of the actual addressing mode set. The way this test works is
1165  * that we sample in one of the corners of the cubemap with filtering enabled,
1166  * and check the interpolated color. There are essentially two reasonable
1167  * things an implementation can do: Either pick one of the faces and
1168  * interpolate the edge texel with itself (i.e., clamp within the face), or
1169  * interpolate between the edge texels of the three involved faces. It should
1170  * never involve the border color or the other side (texcoord wrapping) of a
1171  * face in the interpolation. */
1172 static void test_cube_wrap(IDirect3DDevice9 *device)
1173 {
1174     static const float quad[][6] = {
1175         {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1176         {-1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1177         { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1178         { 1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1179     };
1180
1181     static const D3DVERTEXELEMENT9 decl_elements[] = {
1182         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1183         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1184         D3DDECL_END()
1185     };
1186
1187     static const struct {
1188         D3DTEXTUREADDRESS mode;
1189         const char *name;
1190     } address_modes[] = {
1191         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1192         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1193         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1194         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1195         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1196     };
1197
1198     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1199     IDirect3DCubeTexture9 *texture = NULL;
1200     IDirect3DSurface9 *surface = NULL;
1201     IDirect3DSurface9 *face_surface;
1202     D3DLOCKED_RECT locked_rect;
1203     HRESULT hr;
1204     UINT x;
1205     INT y, face;
1206
1207     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1208     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1209     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1210     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1211
1212     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1213             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1214     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1215
1216     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1217             D3DPOOL_DEFAULT, &texture, NULL);
1218     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1219
1220     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1221     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1222
1223     for (y = 0; y < 128; ++y)
1224     {
1225         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1226         for (x = 0; x < 64; ++x)
1227         {
1228             *ptr++ = 0xff0000ff;
1229         }
1230         for (x = 64; x < 128; ++x)
1231         {
1232             *ptr++ = 0xffff0000;
1233         }
1234     }
1235
1236     hr = IDirect3DSurface9_UnlockRect(surface);
1237     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1238
1239     hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
1240     ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1241
1242     hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1243     ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1244
1245     IDirect3DSurface9_Release(face_surface);
1246
1247     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1248     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1249
1250     for (y = 0; y < 128; ++y)
1251     {
1252         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1253         for (x = 0; x < 64; ++x)
1254         {
1255             *ptr++ = 0xffff0000;
1256         }
1257         for (x = 64; x < 128; ++x)
1258         {
1259             *ptr++ = 0xff0000ff;
1260         }
1261     }
1262
1263     hr = IDirect3DSurface9_UnlockRect(surface);
1264     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1265
1266     /* Create cube faces */
1267     for (face = 1; face < 6; ++face)
1268     {
1269         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1270         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1271
1272         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1273         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1274
1275         IDirect3DSurface9_Release(face_surface);
1276     }
1277
1278     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1279     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1280
1281     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1282     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1283     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1284     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1285     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1286     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1287
1288     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1289     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1290
1291     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1292     {
1293         DWORD color;
1294
1295         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1296         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1297         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1298         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1299
1300         hr = IDirect3DDevice9_BeginScene(device);
1301         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1302
1303         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1304         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1305
1306         hr = IDirect3DDevice9_EndScene(device);
1307         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1308
1309         color = getPixelColor(device, 320, 240);
1310         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1311                 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
1312                 color, address_modes[x].name);
1313
1314         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1315         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1316
1317         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1318         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1319     }
1320
1321     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1322     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1323
1324     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1325     IDirect3DCubeTexture9_Release(texture);
1326     IDirect3DSurface9_Release(surface);
1327 }
1328
1329 static void offscreen_test(IDirect3DDevice9 *device)
1330 {
1331     HRESULT hr;
1332     IDirect3DTexture9 *offscreenTexture = NULL;
1333     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1334     DWORD color;
1335
1336     static const float quad[][5] = {
1337         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1338         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1339         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1340         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1341     };
1342
1343     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1344     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1345
1346     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1347     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1348     if(!offscreenTexture) {
1349         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1350         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1351         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1352         if(!offscreenTexture) {
1353             skip("Cannot create an offscreen render target\n");
1354             goto out;
1355         }
1356     }
1357
1358     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1359     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1360     if(!backbuffer) {
1361         goto out;
1362     }
1363
1364     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1365     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1366     if(!offscreen) {
1367         goto out;
1368     }
1369
1370     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1371     ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1372
1373     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1374     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1375     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1376     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1377     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1378     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1379     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1380     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1381     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1382     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1383
1384     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1385         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1386         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1387         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1388         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1389
1390         /* Draw without textures - Should result in a white quad */
1391         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1392         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1393
1394         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1395         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1396         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1397         ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1398
1399         /* This time with the texture */
1400         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1401         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1402
1403         IDirect3DDevice9_EndScene(device);
1404     }
1405
1406     /* Center quad - should be white */
1407     color = getPixelColor(device, 320, 240);
1408     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1409     /* Some quad in the cleared part of the texture */
1410     color = getPixelColor(device, 170, 240);
1411     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1412     /* Part of the originally cleared back buffer */
1413     color = getPixelColor(device, 10, 10);
1414     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1415     if(0) {
1416         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1417          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1418          * the offscreen rendering mode this test would succeed or fail
1419          */
1420         color = getPixelColor(device, 10, 470);
1421         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1422     }
1423
1424     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1425
1426 out:
1427     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1428     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1429
1430     /* restore things */
1431     if(backbuffer) {
1432         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1433         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1434         IDirect3DSurface9_Release(backbuffer);
1435     }
1436     if(offscreenTexture) {
1437         IDirect3DTexture9_Release(offscreenTexture);
1438     }
1439     if(offscreen) {
1440         IDirect3DSurface9_Release(offscreen);
1441     }
1442 }
1443
1444 /* This test tests fog in combination with shaders.
1445  * What's tested: linear fog (vertex and table) with pixel shader
1446  *                linear table fog with non foggy vertex shader
1447  *                vertex fog with foggy vertex shader, non-linear
1448  *                fog with shader, non-linear fog with foggy shader,
1449  *                linear table fog with foggy shader
1450  */
1451 static void fog_with_shader_test(IDirect3DDevice9 *device)
1452 {
1453     HRESULT hr;
1454     DWORD color;
1455     union {
1456         float f;
1457         DWORD i;
1458     } start, end;
1459     unsigned int i, j;
1460
1461     /* basic vertex shader without fog computation ("non foggy") */
1462     static const DWORD vertex_shader_code1[] = {
1463         0xfffe0101,                                                             /* vs_1_1                       */
1464         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1465         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1466         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1467         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1468         0x0000ffff
1469     };
1470     /* basic vertex shader with reversed fog computation ("foggy") */
1471     static const DWORD vertex_shader_code2[] = {
1472         0xfffe0101,                                                             /* vs_1_1                        */
1473         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1474         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1475         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1476         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1477         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1478         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1479         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1480         0x0000ffff
1481     };
1482     /* basic pixel shader */
1483     static const DWORD pixel_shader_code[] = {
1484         0xffff0101,                                                             /* ps_1_1     */
1485         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, vo */
1486         0x0000ffff
1487     };
1488
1489     static struct vertex quad[] = {
1490         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1491         {-1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1492         { 1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1493         { 1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1494     };
1495
1496     static const D3DVERTEXELEMENT9 decl_elements[] = {
1497         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1498         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1499         D3DDECL_END()
1500     };
1501
1502     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1503     IDirect3DVertexShader9      *vertex_shader[3]   = {NULL, NULL, NULL};
1504     IDirect3DPixelShader9       *pixel_shader[2]    = {NULL, NULL};
1505
1506     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1507     static const struct test_data_t {
1508         int vshader;
1509         int pshader;
1510         D3DFOGMODE vfog;
1511         D3DFOGMODE tfog;
1512         unsigned int color[11];
1513     } test_data[] = {
1514         /* only pixel shader: */
1515         {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1516         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1517         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1518         {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1519         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1520         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1521         {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1522         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1523         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1524         {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1525         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1526         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1527         {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1528         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1529         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1530
1531         /* vertex shader */
1532         {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1533         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1534          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1535         {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1536         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1537         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1538         {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1539         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1540         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1541
1542         {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1543         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1544         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1545         {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1546         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1547         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1548
1549         /* vertex shader and pixel shader */
1550         /* The next 4 tests would read the fog coord output, but it isn't available.
1551          * The result is a fully fogged quad, no matter what the Z coord is. This is on
1552          * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1553          * These tests should be disabled if some other hardware behaves differently
1554          */
1555         {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1556         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1557         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1558         {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1559         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1560         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1561         {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1562         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1563         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1564         {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1565         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1566         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1567
1568         /* These use the Z coordinate with linear table fog */
1569         {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1570         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1571         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1572         {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1573         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1574         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1575         {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1576         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1577         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1578         {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1579         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1580         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1581
1582         /* Non-linear table fog without fog coord */
1583         {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1584         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1585         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1586         {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1587         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1588         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1589
1590 #if 0  /* FIXME: these fail on GeForce 8500 */
1591         /* foggy vertex shader */
1592         {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1593         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1594          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1595         {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1596         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1597          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1598         {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1599         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1600          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1601         {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1602         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1603          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1604 #endif
1605
1606         /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1607          * all using the fixed fog-coord linear fog
1608          */
1609         {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1610         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1611          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1612         {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1613         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1614          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1615         {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1616         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1617          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1618         {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1619         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1620          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1621
1622         /* These use table fog. Here the shader-provided fog coordinate is
1623          * ignored and the z coordinate used instead
1624          */
1625         {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1626         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1627         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1628         {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1629         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1630         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1631         {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1632         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1633         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1634     };
1635
1636     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1637     start.f=0.1f;
1638     end.f=0.9f;
1639
1640     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1641     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1642     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1643     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1644     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1645     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1646     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1647     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1648
1649     /* Setup initial states: No lighting, fog on, fog color */
1650     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1651     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1652     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1653     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1654     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1655     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1656     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1657     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1658
1659     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1660     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1661     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1662     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1663
1664     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1665     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1666     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1667     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1668     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1669
1670     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1671     {
1672         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1673         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1674         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1675         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1676         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1677         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1678         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1679         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1680
1681         for(j=0; j < 11; j++)
1682         {
1683             /* Don't use the whole zrange to prevent rounding errors */
1684             quad[0].z = 0.001f + (float)j / 10.02f;
1685             quad[1].z = 0.001f + (float)j / 10.02f;
1686             quad[2].z = 0.001f + (float)j / 10.02f;
1687             quad[3].z = 0.001f + (float)j / 10.02f;
1688
1689             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1690             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1691
1692             hr = IDirect3DDevice9_BeginScene(device);
1693             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1694
1695             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1696             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1697
1698             hr = IDirect3DDevice9_EndScene(device);
1699             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1700
1701             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1702             color = getPixelColor(device, 128, 240);
1703             ok(color_match(color, test_data[i].color[j], 13),
1704                 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1705                 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1706
1707             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1708         }
1709     }
1710
1711     /* reset states */
1712     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1713     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1714     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1715     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1716     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1717     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1718     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1719     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1720
1721     IDirect3DVertexShader9_Release(vertex_shader[1]);
1722     IDirect3DVertexShader9_Release(vertex_shader[2]);
1723     IDirect3DPixelShader9_Release(pixel_shader[1]);
1724     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1725 }
1726
1727 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1728     unsigned int i, x, y;
1729     HRESULT hr;
1730     IDirect3DTexture9 *texture[2] = {NULL, NULL};
1731     D3DLOCKED_RECT locked_rect;
1732
1733     /* Generate the textures */
1734     for(i=0; i<2; i++)
1735     {
1736         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1737                                             D3DPOOL_MANAGED, &texture[i], NULL);
1738         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1739
1740         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1741         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1742         for (y = 0; y < 128; ++y)
1743         {
1744             if(i)
1745             { /* Set up black texture with 2x2 texel white spot in the middle */
1746                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1747                 for (x = 0; x < 128; ++x)
1748                 {
1749                     if(y>62 && y<66 && x>62 && x<66)
1750                         *ptr++ = 0xffffffff;
1751                     else
1752                         *ptr++ = 0xff000000;
1753                 }
1754             }
1755             else
1756             { /* Set up a displacement map which points away from the center parallel to the closest axis.
1757                * (if multiplied with bumpenvmat)
1758               */
1759                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1760                 for (x = 0; x < 128; ++x)
1761                 {
1762                     if(abs(x-64)>abs(y-64))
1763                     {
1764                         if(x < 64)
1765                             *ptr++ = 0xc000;
1766                         else
1767                             *ptr++ = 0x4000;
1768                     }
1769                     else
1770                     {
1771                         if(y < 64)
1772                             *ptr++ = 0x0040;
1773                         else
1774                             *ptr++ = 0x00c0;
1775                     }
1776                 }
1777             }
1778         }
1779         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1780         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1781
1782         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1783         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1784
1785         /* Disable texture filtering */
1786         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1787         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1788         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1789         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1790
1791         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1792         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1793         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1794         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1795     }
1796 }
1797
1798 /* test the behavior of the texbem instruction
1799  * with normal 2D and projective 2D textures
1800  */
1801 static void texbem_test(IDirect3DDevice9 *device)
1802 {
1803     HRESULT hr;
1804     DWORD color;
1805     int i;
1806
1807     static const DWORD pixel_shader_code[] = {
1808         0xffff0101,                         /* ps_1_1*/
1809         0x00000042, 0xb00f0000,             /* tex t0*/
1810         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1811         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1812         0x0000ffff
1813     };
1814     static const DWORD double_texbem_code[] =  {
1815         0xffff0103,                                         /* ps_1_3           */
1816         0x00000042, 0xb00f0000,                             /* tex t0           */
1817         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
1818         0x00000042, 0xb00f0002,                             /* tex t2           */
1819         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
1820         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
1821         0x0000ffff                                          /* end              */
1822     };
1823
1824
1825     static const float quad[][7] = {
1826         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1827         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1828         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1829         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1830     };
1831     static const float quad_proj[][9] = {
1832         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
1833         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
1834         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
1835         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1836     };
1837
1838     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1839         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1840         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1841         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1842         D3DDECL_END()
1843     },{
1844         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1845         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1846         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1847         D3DDECL_END()
1848     } };
1849
1850     /* use asymmetric matrix to test loading */
1851     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1852
1853     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1854     IDirect3DPixelShader9       *pixel_shader       = NULL;
1855     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
1856     D3DLOCKED_RECT locked_rect;
1857
1858     generate_bumpmap_textures(device);
1859
1860     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1861     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1862     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1863     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1864     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1865
1866     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1867     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1868
1869     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1870     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1871
1872     for(i=0; i<2; i++)
1873     {
1874         if(i)
1875         {
1876             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1877             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1878         }
1879
1880         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1881         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1882         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1883         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1884
1885         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1886         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1887         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1888         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1889
1890         hr = IDirect3DDevice9_BeginScene(device);
1891         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1892
1893         if(!i)
1894             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1895         else
1896             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1897         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1898
1899         hr = IDirect3DDevice9_EndScene(device);
1900         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1901
1902         color = getPixelColor(device, 320-32, 240);
1903         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1904         color = getPixelColor(device, 320+32, 240);
1905         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1906         color = getPixelColor(device, 320, 240-32);
1907         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1908         color = getPixelColor(device, 320, 240+32);
1909         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1910
1911         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1912         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1913
1914         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1915         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1916         IDirect3DPixelShader9_Release(pixel_shader);
1917
1918         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1919         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1920         IDirect3DVertexDeclaration9_Release(vertex_declaration);
1921     }
1922
1923     /* clean up */
1924     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1925     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1926
1927     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1928     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1929
1930     for(i=0; i<2; i++)
1931     {
1932         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1933         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1934         IDirect3DTexture9_Release(texture); /* For the GetTexture */
1935         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1936         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1937         IDirect3DTexture9_Release(texture);
1938     }
1939
1940     /* Test double texbem */
1941     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1942     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1943     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1944     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1945     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1946     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1947     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1948     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1949
1950     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1951     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1952     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1953     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1954
1955     hr = IDirect3DTexture9_UnlockRect(texture, 0);
1956     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1957
1958     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1959     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1960     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1961     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1962     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1963     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1964
1965     {
1966         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1967 #define tex  0x00ff0000
1968 #define tex1 0x0000ff00
1969 #define origin 0x000000ff
1970         static const DWORD pixel_data[] = {
1971             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1972             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1973             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1974             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1975             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
1976             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1977             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1978             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1979         };
1980 #undef tex1
1981 #undef tex2
1982 #undef origin
1983
1984         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1985         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1986         for(i = 0; i < 8; i++) {
1987             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1988         }
1989         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1990         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1991     }
1992
1993     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1994     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1995     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1996     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1997     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1998     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1999     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
2000     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2001     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2002     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2003     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
2004     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2005
2006     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
2007     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
2008     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2009     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2010     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2011     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2012     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2013     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2014     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2015     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2016
2017     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
2018     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
2019     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2020     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2021     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2022     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2023     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2024     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2025     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2026     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2027
2028     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2029     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2030     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2031     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2032     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2033     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2034     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2035     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2036     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2037     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2038     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2039     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2040     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2041     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2042     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2043     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2044
2045     hr = IDirect3DDevice9_BeginScene(device);
2046     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2047     if(SUCCEEDED(hr)) {
2048         static const float double_quad[] = {
2049             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2050              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2051             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2052              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2053         };
2054
2055         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
2056         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2057         hr = IDirect3DDevice9_EndScene(device);
2058         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2059     }
2060     color = getPixelColor(device, 320, 240);
2061     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2062
2063     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2064     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2065     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
2066     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2067     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
2068     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2069     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
2070     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2071     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2072     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2073
2074     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2075     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2076
2077     IDirect3DPixelShader9_Release(pixel_shader);
2078     IDirect3DTexture9_Release(texture);
2079     IDirect3DTexture9_Release(texture1);
2080     IDirect3DTexture9_Release(texture2);
2081 }
2082
2083 static void z_range_test(IDirect3DDevice9 *device)
2084 {
2085     const struct vertex quad[] =
2086     {
2087         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
2088         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
2089         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
2090         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
2091     };
2092     const struct vertex quad2[] =
2093     {
2094         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
2095         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
2096         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
2097         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
2098     };
2099
2100     const struct tvertex quad3[] =
2101     {
2102         {    0,   240,   1.1f,  1.0,                    0xffffff00},
2103         {    0,   480,   1.1f,  1.0,                    0xffffff00},
2104         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
2105         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
2106     };
2107     const struct tvertex quad4[] =
2108     {
2109         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
2110         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
2111         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
2112         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
2113     };
2114     HRESULT hr;
2115     DWORD color;
2116     IDirect3DVertexShader9 *shader;
2117     IDirect3DVertexDeclaration9 *decl;
2118     D3DCAPS9 caps;
2119     const DWORD shader_code[] = {
2120         0xfffe0101,                                     /* vs_1_1           */
2121         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
2122         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
2123         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
2124         0x0000ffff                                      /* end              */
2125     };
2126     static const D3DVERTEXELEMENT9 decl_elements[] = {
2127         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2128         D3DDECL_END()
2129     };
2130
2131     IDirect3DDevice9_GetDeviceCaps(device, &caps);
2132
2133     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2134      * then call Present. Then clear the color buffer to make sure it has some defined content
2135      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2136      * by the depth value.
2137      */
2138     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2139     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2140     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2141     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2142     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2143     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2144
2145     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2146     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2147     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2148     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2149     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2150     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2151     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2152     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2153     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2154     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2155
2156     hr = IDirect3DDevice9_BeginScene(device);
2157     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2158     if(hr == D3D_OK)
2159     {
2160         /* Test the untransformed vertex path */
2161         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2162         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2163         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2164         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2165         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2166         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2167
2168         /* Test the transformed vertex path */
2169         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2170         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2171
2172         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2173         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2174         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2175         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2176         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2177         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2178
2179         hr = IDirect3DDevice9_EndScene(device);
2180         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2181     }
2182
2183     /* Do not test the exact corner pixels, but go pretty close to them */
2184
2185     /* Clipped because z > 1.0 */
2186     color = getPixelColor(device, 28, 238);
2187     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2188     color = getPixelColor(device, 28, 241);
2189     if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2190     {
2191         ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2192     }
2193     else
2194     {
2195         ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2196     }
2197
2198     /* Not clipped, > z buffer clear value(0.75) */
2199     color = getPixelColor(device, 31, 238);
2200     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2201     color = getPixelColor(device, 31, 241);
2202     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2203     color = getPixelColor(device, 100, 238);
2204     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2205     color = getPixelColor(device, 100, 241);
2206     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2207
2208     /* Not clipped, < z buffer clear value */
2209     color = getPixelColor(device, 104, 238);
2210     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2211     color = getPixelColor(device, 104, 241);
2212     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2213     color = getPixelColor(device, 318, 238);
2214     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2215     color = getPixelColor(device, 318, 241);
2216     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2217
2218     /* Clipped because z < 0.0 */
2219     color = getPixelColor(device, 321, 238);
2220     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2221     color = getPixelColor(device, 321, 241);
2222     if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2223     {
2224         ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2225     }
2226     else
2227     {
2228         ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2229     }
2230
2231     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2232     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2233
2234     /* Test the shader path */
2235     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2236         skip("Vertex shaders not supported\n");
2237         goto out;
2238     }
2239     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2240     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2241     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2242     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2243
2244     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2245
2246     IDirect3DDevice9_SetVertexDeclaration(device, decl);
2247     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2248     IDirect3DDevice9_SetVertexShader(device, shader);
2249     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2250
2251     hr = IDirect3DDevice9_BeginScene(device);
2252     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2253     if(hr == D3D_OK)
2254     {
2255         float colorf[] = {1.0, 0.0, 0.0, 1.0};
2256         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2257         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2258         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2259         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2260         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2261         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2262         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2263         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2264         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2265
2266         hr = IDirect3DDevice9_EndScene(device);
2267         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2268     }
2269
2270     IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2271     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2272     IDirect3DDevice9_SetVertexShader(device, NULL);
2273     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2274
2275     IDirect3DVertexDeclaration9_Release(decl);
2276     IDirect3DVertexShader9_Release(shader);
2277
2278     /* Z < 1.0 */
2279     color = getPixelColor(device, 28, 238);
2280     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2281
2282     /* 1.0 < z < 0.75 */
2283     color = getPixelColor(device, 31, 238);
2284     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2285     color = getPixelColor(device, 100, 238);
2286     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2287
2288     /* 0.75 < z < 0.0 */
2289     color = getPixelColor(device, 104, 238);
2290     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2291     color = getPixelColor(device, 318, 238);
2292     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2293
2294     /* 0.0 < z */
2295     color = getPixelColor(device, 321, 238);
2296     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2297
2298     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2299     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2300
2301     out:
2302     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2303     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2304     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2305     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2306     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2307     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2308 }
2309
2310 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2311 {
2312     D3DSURFACE_DESC desc;
2313     D3DLOCKED_RECT l;
2314     HRESULT hr;
2315     unsigned int x, y;
2316     DWORD *mem;
2317
2318     memset(&desc, 0, sizeof(desc));
2319     memset(&l, 0, sizeof(l));
2320     hr = IDirect3DSurface9_GetDesc(surface, &desc);
2321     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2322     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2323     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2324     if(FAILED(hr)) return;
2325
2326     for(y = 0; y < desc.Height; y++)
2327     {
2328         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2329         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2330         {
2331             mem[x] = color;
2332         }
2333     }
2334     hr = IDirect3DSurface9_UnlockRect(surface);
2335     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2336 }
2337
2338 /* This tests a variety of possible StretchRect() situations */
2339 static void stretchrect_test(IDirect3DDevice9 *device)
2340 {
2341     HRESULT hr;
2342     IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL, *tex_rt_dest640_480 = NULL;
2343     IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL, *surf_tex_rt_dest640_480 = NULL;
2344     IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2345     IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2346     IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2347     IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2348     IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2349     IDirect3DSurface9 *orig_rt = NULL;
2350     IDirect3DSurface9 *backbuffer = NULL;
2351     DWORD color;
2352
2353     RECT src_rect64 = {0, 0, 64, 64};
2354     RECT src_rect64_flipy = {0, 64, 64, 0};
2355     RECT dst_rect64 = {0, 0, 64, 64};
2356     RECT dst_rect64_flipy = {0, 64, 64, 0};
2357
2358     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2359     ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2360     if(!orig_rt) {
2361         goto out;
2362     }
2363
2364     /* Create our temporary surfaces in system memory */
2365     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2366     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2367     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2368     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2369
2370     /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2371     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2372     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2373     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2374     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2375     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2376     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2377
2378     /* Create render target surfaces */
2379     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2380     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2381     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2382     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2383     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2384     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2385     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2386     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2387
2388     /* Create render target textures */
2389     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2390     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2391     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2392     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2393     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2394     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2395     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
2396     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2397     if (tex_rt32) {
2398         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2399         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2400     }
2401     if (tex_rt64) {
2402         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2403         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2404     }
2405     if (tex_rt_dest64) {
2406         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2407         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2408     }
2409     if (tex_rt_dest64) {
2410         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
2411         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2412     }
2413
2414     /* Create regular textures in D3DPOOL_DEFAULT */
2415     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2416     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2417     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2418     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2419     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2420     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2421     if (tex32) {
2422         hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2423         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2424     }
2425     if (tex64) {
2426         hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2427         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2428     }
2429     if (tex_dest64) {
2430         hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2431         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2432     }
2433
2434     /*********************************************************************
2435      * Tests for when the source parameter is an offscreen plain surface *
2436      *********************************************************************/
2437
2438     /* Fill the offscreen 64x64 surface with green */
2439     if (surf_offscreen64)
2440         fill_surface(surf_offscreen64, 0xff00ff00);
2441
2442     /* offscreenplain ==> offscreenplain, same size */
2443     if(surf_offscreen64 && surf_offscreen_dest64) {
2444         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2445         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2446
2447         if (hr == D3D_OK) {
2448             color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2449             ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2450         }
2451
2452         /* Blit without scaling */
2453         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64, 0);
2454         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2455
2456         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2457         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_offscreen_dest64, &dst_rect64, 0);
2458         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2459
2460         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2461         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64_flipy, 0);
2462         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2463     }
2464
2465     /* offscreenplain ==> rendertarget texture, same size */
2466     if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2467         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2468         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2469
2470         /* We can't lock rendertarget textures, so copy to our temp surface first */
2471         if (hr == D3D_OK) {
2472             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2473             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2474         }
2475
2476         if (hr == D3D_OK) {
2477             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2478             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2479         }
2480
2481         /* Blit without scaling */
2482         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2483         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2484
2485         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2486         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2487         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2488
2489         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2490         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2491         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2492     }
2493
2494     /* offscreenplain ==> rendertarget surface, same size */
2495     if(surf_offscreen64 && surf_rt_dest64) {
2496         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2497         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2498
2499         if (hr == D3D_OK) {
2500             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2501             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2502         }
2503
2504         /* Blit without scaling */
2505         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2506         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2507
2508         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2509         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2510         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2511
2512         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2513         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2514         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2515     }
2516
2517     /* offscreenplain ==> texture, same size (should fail) */
2518     if(surf_offscreen64 && surf_tex_dest64) {
2519         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2520         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2521     }
2522
2523     /* Fill the smaller offscreen surface with red */
2524     fill_surface(surf_offscreen32, 0xffff0000);
2525
2526     /* offscreenplain ==> offscreenplain, scaling (should fail) */
2527     if(surf_offscreen32 && surf_offscreen64) {
2528         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2529         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2530     }
2531
2532     /* offscreenplain ==> rendertarget texture, scaling */
2533     if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2534         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2535         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2536
2537         /* We can't lock rendertarget textures, so copy to our temp surface first */
2538         if (hr == D3D_OK) {
2539             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2540             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2541         }
2542
2543         if (hr == D3D_OK) {
2544             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2545             ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2546         }
2547     }
2548
2549     /* offscreenplain ==> rendertarget surface, scaling */
2550     if(surf_offscreen32 && surf_rt_dest64) {
2551         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2552         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2553
2554         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2555         ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2556     }
2557
2558     /* offscreenplain ==> texture, scaling (should fail) */
2559     if(surf_offscreen32 && surf_tex_dest64) {
2560         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2561         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2562     }
2563
2564     /************************************************************
2565      * Tests for when the source parameter is a regular texture *
2566      ************************************************************/
2567
2568     /* Fill the surface of the regular texture with blue */
2569     if (surf_tex64 && surf_temp64) {
2570         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2571         fill_surface(surf_temp64, 0xff0000ff);
2572         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2573         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2574     }
2575
2576     /* texture ==> offscreenplain, same size */
2577     if(surf_tex64 && surf_offscreen64) {
2578         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2579         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2580     }
2581
2582     /* texture ==> rendertarget texture, same size */
2583     if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2584         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2585         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2586
2587         /* We can't lock rendertarget textures, so copy to our temp surface first */
2588         if (hr == D3D_OK) {
2589             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2590             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2591         }
2592
2593         if (hr == D3D_OK) {
2594             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2595             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2596         }
2597
2598         /* Blit without scaling */
2599         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2600         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2601
2602         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2603         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2604         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2605
2606         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2607         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2608         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2609     }
2610
2611     /* texture ==> rendertarget surface, same size */
2612     if(surf_tex64 && surf_rt_dest64) {
2613         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2614         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2615
2616         if (hr == D3D_OK) {
2617             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2618             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2619         }
2620
2621         /* Blit without scaling */
2622         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2623         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2624
2625         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2626         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2627         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2628
2629         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2630         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2631         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2632     }
2633
2634     /* texture ==> texture, same size (should fail) */
2635     if(surf_tex64 && surf_tex_dest64) {
2636         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2637         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2638     }
2639
2640     /* Fill the surface of the smaller regular texture with red */
2641     if (surf_tex32 && surf_temp32) {
2642         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2643         fill_surface(surf_temp32, 0xffff0000);
2644         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2645         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2646     }
2647
2648     /* texture ==> offscreenplain, scaling (should fail) */
2649     if(surf_tex32 && surf_offscreen64) {
2650         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2651         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2652     }
2653
2654     /* texture ==> rendertarget texture, scaling */
2655     if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2656         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2657         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2658
2659         /* We can't lock rendertarget textures, so copy to our temp surface first */
2660         if (hr == D3D_OK) {
2661             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2662             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2663         }
2664
2665         if (hr == D3D_OK) {
2666             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2667             ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2668         }
2669     }
2670
2671     /* texture ==> rendertarget surface, scaling */
2672     if(surf_tex32 && surf_rt_dest64) {
2673         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2674         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2675
2676         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2677         ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2678     }
2679
2680     /* texture ==> texture, scaling (should fail) */
2681     if(surf_tex32 && surf_tex_dest64) {
2682         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2683         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2684     }
2685
2686     /*****************************************************************
2687      * Tests for when the source parameter is a rendertarget texture *
2688      *****************************************************************/
2689
2690     /* Fill the surface of the rendertarget texture with white */
2691     if (surf_tex_rt64 && surf_temp64) {
2692         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2693         fill_surface(surf_temp64, 0xffffffff);
2694         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2695         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2696     }
2697
2698     /* rendertarget texture ==> offscreenplain, same size */
2699     if(surf_tex_rt64 && surf_offscreen64) {
2700         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2701         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2702     }
2703
2704     /* rendertarget texture ==> rendertarget texture, same size */
2705     if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2706         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2707         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2708
2709         /* We can't lock rendertarget textures, so copy to our temp surface first */
2710         if (hr == D3D_OK) {
2711             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2712             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2713         }
2714
2715         if (hr == D3D_OK) {
2716             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2717             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2718         }
2719
2720         /* Blit without scaling */
2721         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2722         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2723
2724         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2725         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2726         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2727
2728         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2729         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2730         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2731     }
2732
2733     /* rendertarget texture ==> rendertarget surface, same size */
2734     if(surf_tex_rt64 && surf_rt_dest64) {
2735         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2736         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2737
2738         if (hr == D3D_OK) {
2739             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2740             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2741         }
2742
2743         /* Blit without scaling */
2744         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2745         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2746
2747         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2748         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2749         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2750
2751         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2752         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2753         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2754     }
2755
2756     /* rendertarget texture ==> texture, same size (should fail) */
2757     if(surf_tex_rt64 && surf_tex_dest64) {
2758         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2759         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2760     }
2761
2762     /* Fill the surface of the smaller rendertarget texture with red */
2763     if (surf_tex_rt32 && surf_temp32) {
2764         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2765         fill_surface(surf_temp32, 0xffff0000);
2766         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2767         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2768     }
2769
2770     /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2771     if(surf_tex_rt32 && surf_offscreen64) {
2772         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2773         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2774     }
2775
2776     /* rendertarget texture ==> rendertarget texture, scaling */
2777     if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2778         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2779         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2780
2781         /* We can't lock rendertarget textures, so copy to our temp surface first */
2782         if (hr == D3D_OK) {
2783             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2784             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2785         }
2786
2787         if (hr == D3D_OK) {
2788             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2789             ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2790         }
2791     }
2792
2793     /* rendertarget texture ==> rendertarget surface, scaling */
2794     if(surf_tex_rt32 && surf_rt_dest64) {
2795         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2796         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2797
2798         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2799         ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2800     }
2801
2802     /* rendertarget texture ==> texture, scaling (should fail) */
2803     if(surf_tex_rt32 && surf_tex_dest64) {
2804         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2805         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2806     }
2807
2808     /*****************************************************************
2809      * Tests for when the source parameter is a rendertarget surface *
2810      *****************************************************************/
2811
2812     /* Fill the surface of the rendertarget surface with black */
2813     if (surf_rt64)
2814         fill_surface(surf_rt64, 0xff000000);
2815
2816     /* rendertarget texture ==> offscreenplain, same size */
2817     if(surf_rt64 && surf_offscreen64) {
2818         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2819         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2820     }
2821
2822     /* rendertarget surface ==> rendertarget texture, same size */
2823     if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2824         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2825         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2826
2827         /* We can't lock rendertarget textures, so copy to our temp surface first */
2828         if (hr == D3D_OK) {
2829             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2830             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2831         }
2832
2833         if (hr == D3D_OK) {
2834             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2835             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2836         }
2837
2838         /* Blit without scaling */
2839         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2840         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2841
2842         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2843         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2844         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2845
2846         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2847         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2848         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2849     }
2850
2851     /* rendertarget surface ==> rendertarget surface, same size */
2852     if(surf_rt64 && surf_rt_dest64) {
2853         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2854         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2855
2856         if (hr == D3D_OK) {
2857             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2858             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2859         }
2860
2861         /* Blit without scaling */
2862         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2863         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2864
2865         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2866         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64_flipy, 0);
2867         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2868
2869         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2870         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2871         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2872     }
2873
2874     /* rendertarget surface ==> texture, same size (should fail) */
2875     if(surf_rt64 && surf_tex_dest64) {
2876         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2877         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2878     }
2879
2880     /* Fill the surface of the smaller rendertarget texture with red */
2881     if (surf_rt32)
2882         fill_surface(surf_rt32, 0xffff0000);
2883
2884     /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2885     if(surf_rt32 && surf_offscreen64) {
2886         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2887         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2888     }
2889
2890     /* rendertarget surface ==> rendertarget texture, scaling */
2891     if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2892         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2893         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2894
2895         /* We can't lock rendertarget textures, so copy to our temp surface first */
2896         if (hr == D3D_OK) {
2897             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2898             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2899         }
2900
2901         if (hr == D3D_OK) {
2902             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2903             ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2904         }
2905     }
2906
2907     /* rendertarget surface ==> rendertarget surface, scaling */
2908     if(surf_rt32 && surf_rt_dest64) {
2909         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2910         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2911
2912         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2913         ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2914     }
2915
2916     /* rendertarget surface ==> texture, scaling (should fail) */
2917     if(surf_rt32 && surf_tex_dest64) {
2918         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2919         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2920     }
2921
2922     /* backbuffer ==> surface tests (no scaling) */
2923     if(backbuffer && surf_tex_rt_dest640_480)
2924     {
2925         RECT src_rect = {0, 0, 640, 480};
2926         RECT src_rect_flipy = {0, 480, 640, 0};
2927         RECT dst_rect = {0, 0, 640, 480};
2928         RECT dst_rect_flipy = {0, 480, 640, 0};
2929
2930         /* Blit with NULL rectangles */
2931         hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, 0);
2932         ok( hr == D3D_OK, "StretchRect backbuffer ==> texture same size failed:\n");
2933
2934         /* Blit without scaling */
2935         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect, 0);
2936         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2937
2938         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2939         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy, surf_tex_rt_dest640_480, &dst_rect, 0);
2940         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2941
2942         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2943         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect_flipy, 0);
2944         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2945     }
2946
2947     /* TODO: Test format conversions */
2948
2949
2950 out:
2951     /* Clean up */
2952     if (backbuffer)
2953         IDirect3DSurface9_Release(backbuffer);
2954     if (surf_rt32)
2955         IDirect3DSurface9_Release(surf_rt32);
2956     if (surf_rt64)
2957         IDirect3DSurface9_Release(surf_rt64);
2958     if (surf_rt_dest64)
2959         IDirect3DSurface9_Release(surf_rt_dest64);
2960     if (surf_temp32)
2961         IDirect3DSurface9_Release(surf_temp32);
2962     if (surf_temp64)
2963         IDirect3DSurface9_Release(surf_temp64);
2964     if (surf_offscreen32)
2965         IDirect3DSurface9_Release(surf_offscreen32);
2966     if (surf_offscreen64)
2967         IDirect3DSurface9_Release(surf_offscreen64);
2968     if (surf_offscreen_dest64)
2969         IDirect3DSurface9_Release(surf_offscreen_dest64);
2970
2971     if (tex_rt32) {
2972         if (surf_tex_rt32)
2973             IDirect3DSurface9_Release(surf_tex_rt32);
2974         IDirect3DTexture9_Release(tex_rt32);
2975     }
2976     if (tex_rt64) {
2977         if (surf_tex_rt64)
2978             IDirect3DSurface9_Release(surf_tex_rt64);
2979         IDirect3DTexture9_Release(tex_rt64);
2980     }
2981     if (tex_rt_dest64) {
2982         if (surf_tex_rt_dest64)
2983             IDirect3DSurface9_Release(surf_tex_rt_dest64);
2984         IDirect3DTexture9_Release(tex_rt_dest64);
2985     }
2986     if (tex_rt_dest640_480) {
2987         if (surf_tex_rt_dest640_480)
2988             IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
2989         IDirect3DTexture9_Release(tex_rt_dest640_480);
2990     }
2991     if (tex32) {
2992         if (surf_tex32)
2993             IDirect3DSurface9_Release(surf_tex32);
2994         IDirect3DTexture9_Release(tex32);
2995     }
2996     if (tex64) {
2997         if (surf_tex64)
2998             IDirect3DSurface9_Release(surf_tex64);
2999         IDirect3DTexture9_Release(tex64);
3000     }
3001     if (tex_dest64) {
3002         if (surf_tex_dest64)
3003             IDirect3DSurface9_Release(surf_tex_dest64);
3004         IDirect3DTexture9_Release(tex_dest64);
3005     }
3006
3007     if (orig_rt) {
3008         hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
3009         ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
3010         IDirect3DSurface9_Release(orig_rt);
3011     }
3012 }
3013
3014 static void maxmip_test(IDirect3DDevice9 *device)
3015 {
3016     IDirect3DTexture9 *texture = NULL;
3017     IDirect3DSurface9 *surface = NULL;
3018     HRESULT hr;
3019     DWORD color;
3020     static const struct
3021     {
3022         struct
3023         {
3024             float x, y, z;
3025             float s, t;
3026         }
3027         v[4];
3028     }
3029     quads[] =
3030     {
3031         {{
3032             {-1.0, -1.0,  0.0,  0.0,  0.0},
3033             {-1.0,  0.0,  0.0,  0.0,  1.0},
3034             { 0.0, -1.0,  0.0,  1.0,  0.0},
3035             { 0.0,  0.0,  0.0,  1.0,  1.0},
3036         }},
3037         {{
3038             { 0.0, -1.0,  0.0,  0.0,  0.0},
3039             { 0.0,  0.0,  0.0,  0.0,  1.0},
3040             { 1.0, -1.0,  0.0,  1.0,  0.0},
3041             { 1.0,  0.0,  0.0,  1.0,  1.0},
3042         }},
3043         {{
3044             { 0.0,  0.0,  0.0,  0.0,  0.0},
3045             { 0.0,  1.0,  0.0,  0.0,  1.0},
3046             { 1.0,  0.0,  0.0,  1.0,  0.0},
3047             { 1.0,  1.0,  0.0,  1.0,  1.0},
3048         }},
3049         {{
3050             {-1.0,  0.0,  0.0,  0.0,  0.0},
3051             {-1.0,  1.0,  0.0,  0.0,  1.0},
3052             { 0.0,  0.0,  0.0,  1.0,  0.0},
3053             { 0.0,  1.0,  0.0,  1.0,  1.0},
3054         }},
3055     };
3056
3057     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
3058                                         &texture, NULL);
3059     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3060     if(!texture)
3061     {
3062         skip("Failed to create test texture\n");
3063         return;
3064     }
3065
3066     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3067     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3068     fill_surface(surface, 0xffff0000);
3069     IDirect3DSurface9_Release(surface);
3070     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
3071     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3072     fill_surface(surface, 0xff00ff00);
3073     IDirect3DSurface9_Release(surface);
3074     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3075     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3076     fill_surface(surface, 0xff0000ff);
3077     IDirect3DSurface9_Release(surface);
3078
3079     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3080     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3081     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3082     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3083
3084     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3085     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3086
3087     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3088     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3089
3090     hr = IDirect3DDevice9_BeginScene(device);
3091     if(SUCCEEDED(hr))
3092     {
3093         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3094         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3095         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3096         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3097
3098         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3099         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3100         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3101         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3102
3103         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3104         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3105         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3106         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3107
3108         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3109         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3110         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3111         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3112         hr = IDirect3DDevice9_EndScene(device);
3113         ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
3114     }
3115
3116     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
3117     color = getPixelColor(device, 160, 360);
3118     ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
3119     color = getPixelColor(device, 480, 360);
3120     ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
3121     color = getPixelColor(device, 480, 120);
3122     ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
3123     color = getPixelColor(device, 160, 120);
3124     ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
3125     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3126     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3127
3128     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3129     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3130
3131     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3132     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3133
3134     hr = IDirect3DDevice9_BeginScene(device);
3135     if(SUCCEEDED(hr))
3136     {
3137         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3138         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3139         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3140         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3141
3142         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3143         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3144         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3145         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3146
3147         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3148         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3149         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3150         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3151
3152         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3153         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3154         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3155         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3156         hr = IDirect3DDevice9_EndScene(device);
3157         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
3158     }
3159
3160     /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3161      * level 3 (> levels in texture) samples from the highest level in the
3162      * texture (level 2). */
3163     color = getPixelColor(device, 160, 360);
3164     ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
3165     color = getPixelColor(device, 480, 360);
3166     ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
3167     color = getPixelColor(device, 480, 120);
3168     ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
3169     color = getPixelColor(device, 160, 120);
3170     ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
3171     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3172     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3173
3174     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3175     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3176
3177     hr = IDirect3DDevice9_BeginScene(device);
3178     if(SUCCEEDED(hr))
3179     {
3180         DWORD ret;
3181
3182         /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
3183         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3184         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3185         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3186         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3187         ret = IDirect3DTexture9_SetLOD(texture, 1);
3188         ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
3189         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3190         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3191
3192         /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
3193         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3194         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3195         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3196         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3197         ret = IDirect3DTexture9_SetLOD(texture, 2);
3198         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3199         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3200         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3201
3202         /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
3203         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3204         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3205         ret = IDirect3DTexture9_SetLOD(texture, 1);
3206         ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
3207         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3208         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3209
3210         /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
3211         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3212         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3213         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3214         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3215         ret = IDirect3DTexture9_SetLOD(texture, 1);
3216         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3217         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3218         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3219         hr = IDirect3DDevice9_EndScene(device);
3220         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3221     }
3222
3223     /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3224      * level 3 (> levels in texture) samples from the highest level in the
3225      * texture (level 2). */
3226     color = getPixelColor(device, 160, 360);
3227     ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
3228     color = getPixelColor(device, 480, 360);
3229     ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
3230     color = getPixelColor(device, 480, 120);
3231     ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
3232     color = getPixelColor(device, 160, 120);
3233     ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
3234
3235     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3236     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3237
3238     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3239     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3240     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3241     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3242     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3243     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3244     IDirect3DTexture9_Release(texture);
3245 }
3246
3247 static void release_buffer_test(IDirect3DDevice9 *device)
3248 {
3249     IDirect3DVertexBuffer9 *vb = NULL;
3250     IDirect3DIndexBuffer9 *ib = NULL;
3251     HRESULT hr;
3252     BYTE *data;
3253     LONG ref;
3254
3255     static const struct vertex quad[] = {
3256         {-1.0,      -1.0,       0.1,        0xffff0000},
3257         {-1.0,       1.0,       0.1,        0xffff0000},
3258         { 1.0,       1.0,       0.1,        0xffff0000},
3259
3260         {-1.0,      -1.0,       0.1,        0xff00ff00},
3261         {-1.0,       1.0,       0.1,        0xff00ff00},
3262         { 1.0,       1.0,       0.1,        0xff00ff00}
3263     };
3264     short indices[] = {3, 4, 5};
3265
3266     /* Index and vertex buffers should always be creatable */
3267     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
3268                                               D3DPOOL_MANAGED, &vb, NULL);
3269     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
3270     if(!vb) {
3271         skip("Failed to create a vertex buffer\n");
3272         return;
3273     }
3274     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3275     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
3276     if(!ib) {
3277         skip("Failed to create an index buffer\n");
3278         return;
3279     }
3280
3281     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3282     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3283     memcpy(data, quad, sizeof(quad));
3284     hr = IDirect3DVertexBuffer9_Unlock(vb);
3285     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3286
3287     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3288     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3289     memcpy(data, indices, sizeof(indices));
3290     hr = IDirect3DIndexBuffer9_Unlock(ib);
3291     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3292
3293     hr = IDirect3DDevice9_SetIndices(device, ib);
3294     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3295     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3296     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3297     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3298     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3299
3300     /* Now destroy the bound index buffer and draw again */
3301     ref = IDirect3DIndexBuffer9_Release(ib);
3302     ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3303
3304     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3305     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3306
3307     hr = IDirect3DDevice9_BeginScene(device);
3308     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3309     if(SUCCEEDED(hr))
3310     {
3311         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3312          * making assumptions about the indices or vertices
3313          */
3314         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3315         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3316         hr = IDirect3DDevice9_EndScene(device);
3317         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3318     }
3319
3320     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3321     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3322
3323     hr = IDirect3DDevice9_SetIndices(device, NULL);
3324     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3325     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3326     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3327
3328     /* Index buffer was already destroyed as part of the test */
3329     IDirect3DVertexBuffer9_Release(vb);
3330 }
3331
3332 static void float_texture_test(IDirect3DDevice9 *device)
3333 {
3334     IDirect3D9 *d3d = NULL;
3335     HRESULT hr;
3336     IDirect3DTexture9 *texture = NULL;
3337     D3DLOCKED_RECT lr;
3338     float *data;
3339     DWORD color;
3340     float quad[] = {
3341         -1.0,      -1.0,       0.1,     0.0,    0.0,
3342         -1.0,       1.0,       0.1,     0.0,    1.0,
3343          1.0,      -1.0,       0.1,     1.0,    0.0,
3344          1.0,       1.0,       0.1,     1.0,    1.0,
3345     };
3346
3347     memset(&lr, 0, sizeof(lr));
3348     IDirect3DDevice9_GetDirect3D(device, &d3d);
3349     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3350                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3351         skip("D3DFMT_R32F textures not supported\n");
3352         goto out;
3353     }
3354
3355     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3356                                         D3DPOOL_MANAGED, &texture, NULL);
3357     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3358     if(!texture) {
3359         skip("Failed to create R32F texture\n");
3360         goto out;
3361     }
3362
3363     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3364     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3365     data = lr.pBits;
3366     *data = 0.0;
3367     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3368     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3369
3370     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3371     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3372
3373     hr = IDirect3DDevice9_BeginScene(device);
3374     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3375     if(SUCCEEDED(hr))
3376     {
3377         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3378         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3379
3380         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3381         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3382
3383         hr = IDirect3DDevice9_EndScene(device);
3384         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3385     }
3386     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3387     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3388
3389     color = getPixelColor(device, 240, 320);
3390     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3391
3392     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3393     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3394
3395 out:
3396     if(texture) IDirect3DTexture9_Release(texture);
3397     IDirect3D9_Release(d3d);
3398 }
3399
3400 static void g16r16_texture_test(IDirect3DDevice9 *device)
3401 {
3402     IDirect3D9 *d3d = NULL;
3403     HRESULT hr;
3404     IDirect3DTexture9 *texture = NULL;
3405     D3DLOCKED_RECT lr;
3406     DWORD *data;
3407     DWORD color;
3408     float quad[] = {
3409        -1.0,      -1.0,       0.1,     0.0,    0.0,
3410        -1.0,       1.0,       0.1,     0.0,    1.0,
3411         1.0,      -1.0,       0.1,     1.0,    0.0,
3412         1.0,       1.0,       0.1,     1.0,    1.0,
3413     };
3414
3415     memset(&lr, 0, sizeof(lr));
3416     IDirect3DDevice9_GetDirect3D(device, &d3d);
3417     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3418        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3419            skip("D3DFMT_G16R16 textures not supported\n");
3420            goto out;
3421     }
3422
3423     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3424                                         D3DPOOL_MANAGED, &texture, NULL);
3425     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3426     if(!texture) {
3427         skip("Failed to create D3DFMT_G16R16 texture\n");
3428         goto out;
3429     }
3430
3431     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3432     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3433     data = lr.pBits;
3434     *data = 0x0f00f000;
3435     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3436     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3437
3438     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3439     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3440
3441     hr = IDirect3DDevice9_BeginScene(device);
3442     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3443     if(SUCCEEDED(hr))
3444     {
3445         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3446         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3447
3448         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3449         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3450
3451         hr = IDirect3DDevice9_EndScene(device);
3452         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3453     }
3454     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3455     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3456
3457     color = getPixelColor(device, 240, 320);
3458     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3459        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3460
3461     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3462     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3463
3464 out:
3465     if(texture) IDirect3DTexture9_Release(texture);
3466     IDirect3D9_Release(d3d);
3467 }
3468
3469 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3470 {
3471     HRESULT hr;
3472     IDirect3D9 *d3d;
3473     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3474     D3DCAPS9 caps;
3475     IDirect3DTexture9 *texture = NULL;
3476     IDirect3DVolumeTexture9 *volume = NULL;
3477     unsigned int x, y, z;
3478     D3DLOCKED_RECT lr;
3479     D3DLOCKED_BOX lb;
3480     DWORD color;
3481     UINT w, h;
3482     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3483     float identity[16] = {1.0, 0.0, 0.0, 0.0,
3484                            0.0, 1.0, 0.0, 0.0,
3485                            0.0, 0.0, 1.0, 0.0,
3486                            0.0, 0.0, 0.0, 1.0};
3487     static const D3DVERTEXELEMENT9 decl_elements[] = {
3488         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3489         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3490         D3DDECL_END()
3491     };
3492     static const D3DVERTEXELEMENT9 decl_elements2[] = {
3493         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3494         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3495         D3DDECL_END()
3496     };
3497     static const D3DVERTEXELEMENT9 decl_elements3[] = {
3498         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3499         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3500         D3DDECL_END()
3501     };
3502     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3503                                                  0x00, 0xff, 0x00, 0x00,
3504                                                  0x00, 0x00, 0x00, 0x00,
3505                                                  0x00, 0x00, 0x00, 0x00};
3506
3507     memset(&lr, 0, sizeof(lr));
3508     memset(&lb, 0, sizeof(lb));
3509     IDirect3DDevice9_GetDirect3D(device, &d3d);
3510     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3511                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3512         fmt = D3DFMT_A16B16G16R16;
3513     }
3514     IDirect3D9_Release(d3d);
3515
3516     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3517     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3518     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3519     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3520     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3521     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3522     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3523     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3524     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3525     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3526     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3527     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3528     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3529     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3530     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3531     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3532     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3533     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3534     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3535     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3536     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3537     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3538     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3539     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3540
3541     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3542     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3543     w = min(1024, caps.MaxTextureWidth);
3544     h = min(1024, caps.MaxTextureHeight);
3545     hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3546                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3547     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3548     if(!texture) {
3549         skip("Failed to create the test texture\n");
3550         return;
3551     }
3552
3553     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3554      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3555      * 1.0 in red and green for the x and y coords
3556      */
3557     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3558     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3559     for(y = 0; y < h; y++) {
3560         for(x = 0; x < w; x++) {
3561             double r_f = (double) y / (double) h;
3562             double g_f = (double) x / (double) w;
3563             if(fmt == D3DFMT_A16B16G16R16) {
3564                 unsigned short r, g;
3565                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3566                 r = (unsigned short) (r_f * 65536.0);
3567                 g = (unsigned short) (g_f * 65536.0);
3568                 dst[0] = r;
3569                 dst[1] = g;
3570                 dst[2] = 0;
3571                 dst[3] = 65535;
3572             } else {
3573                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3574                 unsigned char r = (unsigned char) (r_f * 255.0);
3575                 unsigned char g = (unsigned char) (g_f * 255.0);
3576                 dst[0] = 0;
3577                 dst[1] = g;
3578                 dst[2] = r;
3579                 dst[3] = 255;
3580             }
3581         }
3582     }
3583     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3584     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3585     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3586     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3587
3588     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3589     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3590     hr = IDirect3DDevice9_BeginScene(device);
3591     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3592     if(SUCCEEDED(hr))
3593     {
3594         float quad1[] = {
3595             -1.0,      -1.0,       0.1,     1.0,    1.0,
3596             -1.0,       0.0,       0.1,     1.0,    1.0,
3597              0.0,      -1.0,       0.1,     1.0,    1.0,
3598              0.0,       0.0,       0.1,     1.0,    1.0,
3599         };
3600         float quad2[] = {
3601             -1.0,       0.0,       0.1,     1.0,    1.0,
3602             -1.0,       1.0,       0.1,     1.0,    1.0,
3603              0.0,       0.0,       0.1,     1.0,    1.0,
3604              0.0,       1.0,       0.1,     1.0,    1.0,
3605         };
3606         float quad3[] = {
3607              0.0,       0.0,       0.1,     0.5,    0.5,
3608              0.0,       1.0,       0.1,     0.5,    0.5,
3609              1.0,       0.0,       0.1,     0.5,    0.5,
3610              1.0,       1.0,       0.1,     0.5,    0.5,
3611         };
3612         float quad4[] = {
3613              320,       480,       0.1,     1.0,    0.0,    1.0,
3614              320,       240,       0.1,     1.0,    0.0,    1.0,
3615              640,       480,       0.1,     1.0,    0.0,    1.0,
3616              640,       240,       0.1,     1.0,    0.0,    1.0,
3617         };
3618         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3619                           0.0, 0.0, 0.0, 0.0,
3620                           0.0, 0.0, 0.0, 0.0,
3621                           0.0, 0.0, 0.0, 0.0};
3622
3623         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3624         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3625         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3626         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3627         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3628
3629         /* What happens with transforms enabled? */
3630         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3631         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3632         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3633         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3634
3635         /* What happens if 4 coords are used, but only 2 given ?*/
3636         mat[8] = 1.0;
3637         mat[13] = 1.0;
3638         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3639         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3640         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3641         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3642         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3643         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3644
3645         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3646          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3647          * due to the coords in the vertices. (turns out red, indeed)
3648          */
3649         memset(mat, 0, sizeof(mat));
3650         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3651         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3652         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3653         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3654         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3655         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3656         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3657         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3658
3659         hr = IDirect3DDevice9_EndScene(device);
3660         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3661     }
3662     color = getPixelColor(device, 160, 360);
3663     ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3664     color = getPixelColor(device, 160, 120);
3665     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3666     color = getPixelColor(device, 480, 120);
3667     ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
3668     color = getPixelColor(device, 480, 360);
3669     ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
3670     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3671     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3672
3673     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3674     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3675
3676     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3677     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3678     hr = IDirect3DDevice9_BeginScene(device);
3679     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3680     if(SUCCEEDED(hr))
3681     {
3682         float quad1[] = {
3683             -1.0,      -1.0,       0.1,     0.8,    0.2,
3684             -1.0,       0.0,       0.1,     0.8,    0.2,
3685              0.0,      -1.0,       0.1,     0.8,    0.2,
3686              0.0,       0.0,       0.1,     0.8,    0.2,
3687         };
3688         float quad2[] = {
3689             -1.0,       0.0,       0.1,     0.5,    1.0,
3690             -1.0,       1.0,       0.1,     0.5,    1.0,
3691              0.0,       0.0,       0.1,     0.5,    1.0,
3692              0.0,       1.0,       0.1,     0.5,    1.0,
3693         };
3694         float quad3[] = {
3695              0.0,       0.0,       0.1,     0.5,    1.0,
3696              0.0,       1.0,       0.1,     0.5,    1.0,
3697              1.0,       0.0,       0.1,     0.5,    1.0,
3698              1.0,       1.0,       0.1,     0.5,    1.0,
3699         };
3700         float quad4[] = {
3701              0.0,      -1.0,       0.1,     0.8,    0.2,
3702              0.0,       0.0,       0.1,     0.8,    0.2,
3703              1.0,      -1.0,       0.1,     0.8,    0.2,
3704              1.0,       0.0,       0.1,     0.8,    0.2,
3705         };
3706         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3707                           0.0, 0.0, 0.0, 0.0,
3708                           0.0, 1.0, 0.0, 0.0,
3709                           0.0, 0.0, 0.0, 0.0};
3710
3711         /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3712          */
3713         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3714         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3715         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3716         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3717
3718         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3719         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3720
3721         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3722          * it behaves like COUNT2 because normal textures require 2 coords
3723          */
3724         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3725         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3726         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3727         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3728
3729         /* Just to be sure, the same as quad2 above */
3730         memset(mat, 0, sizeof(mat));
3731         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3732         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3733         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3734         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3735         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3736         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3737
3738         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3739          * used? And what happens to the first?
3740          */
3741         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3742         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3743         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3744         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3745
3746         hr = IDirect3DDevice9_EndScene(device);
3747         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3748     }
3749     color = getPixelColor(device, 160, 360);
3750     ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
3751     color = getPixelColor(device, 160, 120);
3752     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3753     color = getPixelColor(device, 480, 120);
3754     ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
3755        "quad 3 has color %08x, expected 0x00ff8000\n", color);
3756     color = getPixelColor(device, 480, 360);
3757     ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
3758        "quad 4 has color %08x, expected 0x0033cc00\n", color);
3759     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3760     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3761
3762     IDirect3DTexture9_Release(texture);
3763
3764     /* Test projected textures, without any fancy matrices */
3765     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3766     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3767     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3768     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3769     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3770     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3771     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3772     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3773
3774     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3775     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3776     for(x = 0; x < 4; x++) {
3777         memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3778     }
3779     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3780     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3781     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3782     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3783
3784     hr = IDirect3DDevice9_BeginScene(device);
3785     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3786     if(SUCCEEDED(hr))
3787     {
3788         const float proj_quads[] = {
3789            -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3790             1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3791            -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3792             1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3793            -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3794             1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3795            -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3796             1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3797         };
3798
3799         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3800         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3801         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3802         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3803
3804         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3805         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3806         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3807         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3808
3809         hr = IDirect3DDevice9_EndScene(device);
3810         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3811     }
3812
3813     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3814     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3815     IDirect3DTexture9_Release(texture);
3816
3817     color = getPixelColor(device, 158, 118);
3818     ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3819     color = getPixelColor(device, 162, 118);
3820     ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3821     color = getPixelColor(device, 158, 122);
3822     ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3823     color = getPixelColor(device, 162, 122);
3824     ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3825
3826     color = getPixelColor(device, 158, 178);
3827     ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3828     color = getPixelColor(device, 162, 178);
3829     ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3830     color = getPixelColor(device, 158, 182);
3831     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3832     color = getPixelColor(device, 162, 182);
3833     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3834
3835     color = getPixelColor(device, 318, 118);
3836     ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3837     color = getPixelColor(device, 322, 118);
3838     ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3839     color = getPixelColor(device, 318, 122);
3840     ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3841     color = getPixelColor(device, 322, 122);
3842     ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3843
3844     color = getPixelColor(device, 318, 178);
3845     ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3846     color = getPixelColor(device, 322, 178);
3847     ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3848     color = getPixelColor(device, 318, 182);
3849     ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3850     color = getPixelColor(device, 322, 182);
3851     ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3852
3853     color = getPixelColor(device, 238, 298);
3854     ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3855     color = getPixelColor(device, 242, 298);
3856     ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3857     color = getPixelColor(device, 238, 302);
3858     ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3859     color = getPixelColor(device, 242, 302);
3860     ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3861
3862     color = getPixelColor(device, 238, 388);
3863     ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3864     color = getPixelColor(device, 242, 388);
3865     ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3866     color = getPixelColor(device, 238, 392);
3867     ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3868     color = getPixelColor(device, 242, 392);
3869     ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3870
3871     color = getPixelColor(device, 478, 298);
3872     ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3873     color = getPixelColor(device, 482, 298);
3874     ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3875     color = getPixelColor(device, 478, 302);
3876     ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3877     color = getPixelColor(device, 482, 302);
3878     ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3879
3880     color = getPixelColor(device, 478, 388);
3881     ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3882     color = getPixelColor(device, 482, 388);
3883     ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3884     color = getPixelColor(device, 478, 392);
3885     ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3886     color = getPixelColor(device, 482, 392);
3887     ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3888
3889     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3890     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3891
3892     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3893     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3894     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3895      * Thus watch out if sampling from texels between 0 and 1.
3896      */
3897     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3898     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3899        "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3900     if(!volume) {
3901         skip("Failed to create a volume texture\n");
3902         goto out;
3903     }
3904
3905     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3906     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3907     for(z = 0; z < 32; z++) {
3908         for(y = 0; y < 32; y++) {
3909             for(x = 0; x < 32; x++) {
3910                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3911                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3912                 float r_f = (float) x / 31.0;
3913                 float g_f = (float) y / 31.0;
3914                 float b_f = (float) z / 31.0;
3915
3916                 if(fmt == D3DFMT_A16B16G16R16) {
3917                     unsigned short *mem_s = mem;
3918                     mem_s[0]  = r_f * 65535.0;
3919                     mem_s[1]  = g_f * 65535.0;
3920                     mem_s[2]  = b_f * 65535.0;
3921                     mem_s[3]  = 65535;
3922                 } else {
3923                     unsigned char *mem_c = mem;
3924                     mem_c[0]  = b_f * 255.0;
3925                     mem_c[1]  = g_f * 255.0;
3926                     mem_c[2]  = r_f * 255.0;
3927                     mem_c[3]  = 255;
3928                 }
3929             }
3930         }
3931     }
3932     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3933     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3934
3935     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3936     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3937
3938     hr = IDirect3DDevice9_BeginScene(device);
3939     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3940     if(SUCCEEDED(hr))
3941     {
3942         float quad1[] = {
3943             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3944             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3945              0.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         };
3948         float quad2[] = {
3949             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3950             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
3951              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3952              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
3953         };
3954         float quad3[] = {
3955              0.0,       0.0,       0.1,     0.0,    0.0,
3956              0.0,       1.0,       0.1,     0.0,    0.0,
3957              1.0,       0.0,       0.1,     0.0,    0.0,
3958              1.0,       1.0,       0.1,     0.0,    0.0
3959         };
3960         float quad4[] = {
3961              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3962              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3963              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3964              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
3965         };
3966         float mat[16] = {1.0, 0.0, 0.0, 0.0,
3967                          0.0, 0.0, 1.0, 0.0,
3968                          0.0, 1.0, 0.0, 0.0,
3969                          0.0, 0.0, 0.0, 1.0};
3970         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3971         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3972
3973         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3974          * values
3975          */
3976         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3977         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3978         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3979         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3980         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3981         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3982
3983         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3984          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3985          * otherwise the w will be missing(blue).
3986          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3987          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3988          */
3989         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3990         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3991         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3992         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3993
3994         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
3995         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3996         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3997         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3998         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3999         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4000         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4001         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4002         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4003
4004         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
4005          * disable. ATI extends it up to the amount of values needed for the volume texture
4006          */
4007         memset(mat, 0, sizeof(mat));
4008         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4009         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4010         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4011         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4012         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4013         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4014         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4015         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4016
4017         hr = IDirect3DDevice9_EndScene(device);
4018         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4019     }
4020
4021     color = getPixelColor(device, 160, 360);
4022     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
4023     color = getPixelColor(device, 160, 120);
4024     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
4025        "quad 2 has color %08x, expected 0x00ffff00\n", color);
4026     color = getPixelColor(device, 480, 120);
4027     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
4028     color = getPixelColor(device, 480, 360);
4029     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
4030
4031     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4032     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4033
4034     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
4035     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4036     hr = IDirect3DDevice9_BeginScene(device);
4037     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4038     if(SUCCEEDED(hr))
4039     {
4040         float quad1[] = {
4041             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4042             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4043              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4044              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
4045         };
4046         float quad2[] = {
4047             -1.0,       0.0,       0.1,
4048             -1.0,       1.0,       0.1,
4049              0.0,       0.0,       0.1,
4050              0.0,       1.0,       0.1,
4051         };
4052         float quad3[] = {
4053              0.0,       0.0,       0.1,     1.0,
4054              0.0,       1.0,       0.1,     1.0,
4055              1.0,       0.0,       0.1,     1.0,
4056              1.0,       1.0,       0.1,     1.0
4057         };
4058         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
4059                            0.0, 0.0, 0.0, 0.0,
4060                            0.0, 0.0, 0.0, 0.0,
4061                            0.0, 1.0, 0.0, 0.0};
4062         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
4063                            1.0, 0.0, 0.0, 0.0,
4064                            0.0, 1.0, 0.0, 0.0,
4065                            0.0, 0.0, 1.0, 0.0};
4066         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4067         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4068
4069         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
4070          * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
4071          * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
4072          * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
4073          * 4th *input* coordinate.
4074          */
4075         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4076         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4077         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4078         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4079         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4080         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4081
4082         /* None passed */
4083         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4084         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4085         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4086         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4087         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4088         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4089
4090         /* 4 used, 1 passed */
4091         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4092         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4093         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
4094         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4095         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4096         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4097
4098         hr = IDirect3DDevice9_EndScene(device);
4099         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4100     }
4101     color = getPixelColor(device, 160, 360);
4102     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4103     color = getPixelColor(device, 160, 120);
4104     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4105     color = getPixelColor(device, 480, 120);
4106     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4107     /* Quad4: unused */
4108
4109     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4110     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4111
4112     IDirect3DVolumeTexture9_Release(volume);
4113
4114     out:
4115     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4116     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4117     IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
4118     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4119     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4120     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4121     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4122     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4123     IDirect3DVertexDeclaration9_Release(decl);
4124     IDirect3DVertexDeclaration9_Release(decl2);
4125     IDirect3DVertexDeclaration9_Release(decl3);
4126 }
4127
4128 static void texdepth_test(IDirect3DDevice9 *device)
4129 {
4130     IDirect3DPixelShader9 *shader;
4131     HRESULT hr;
4132     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
4133     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
4134     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
4135     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
4136     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
4137     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
4138     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
4139     DWORD shader_code[] = {
4140         0xffff0104,                                                                 /* ps_1_4               */
4141         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
4142         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
4143         0x0000fffd,                                                                 /* phase                */
4144         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
4145         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
4146         0x0000ffff                                                                  /* end                  */
4147     };
4148     DWORD color;
4149     float vertex[] = {
4150        -1.0,   -1.0,    0.0,
4151         1.0,   -1.0,    1.0,
4152        -1.0,    1.0,    0.0,
4153         1.0,    1.0,    1.0
4154     };
4155
4156     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4157     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4158
4159     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4160     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4161     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4162     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4163     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4164     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4165     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4166     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4167     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4168     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4169
4170     /* Fill the depth buffer with a gradient */
4171     hr = IDirect3DDevice9_BeginScene(device);
4172     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4173     if(SUCCEEDED(hr))
4174     {
4175         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4176         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4177         hr = IDirect3DDevice9_EndScene(device);
4178         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4179     }
4180
4181     /* Now perform the actual tests. Same geometry, but with the shader */
4182     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4183     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4184     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4185     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4186     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4187     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4188
4189     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4190     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4191     hr = IDirect3DDevice9_BeginScene(device);
4192     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4193     if(SUCCEEDED(hr))
4194     {
4195         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4196         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4197
4198         hr = IDirect3DDevice9_EndScene(device);
4199         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4200     }
4201
4202     color = getPixelColor(device, 158, 240);
4203     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4204     color = getPixelColor(device, 162, 240);
4205     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
4206
4207     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4208     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4209
4210     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4211     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4212
4213     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
4214     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4215     hr = IDirect3DDevice9_BeginScene(device);
4216     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4217     if(SUCCEEDED(hr))
4218     {
4219         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4220         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4221
4222         hr = IDirect3DDevice9_EndScene(device);
4223         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4224     }
4225
4226     color = getPixelColor(device, 318, 240);
4227     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4228     color = getPixelColor(device, 322, 240);
4229     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4230
4231     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4232     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4233
4234     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4235     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4236
4237     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4238     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4239     hr = IDirect3DDevice9_BeginScene(device);
4240     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4241     if(SUCCEEDED(hr))
4242     {
4243         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4244         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4245
4246         hr = IDirect3DDevice9_EndScene(device);
4247         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4248     }
4249
4250     color = getPixelColor(device, 1, 240);
4251     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4252
4253     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4254     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4255
4256     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4257     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4258
4259     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4260     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4261     hr = IDirect3DDevice9_BeginScene(device);
4262     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4263     if(SUCCEEDED(hr))
4264     {
4265         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4266         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4267
4268         hr = IDirect3DDevice9_EndScene(device);
4269         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4270     }
4271     color = getPixelColor(device, 318, 240);
4272     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4273     color = getPixelColor(device, 322, 240);
4274     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
4275
4276     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4277     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4278
4279     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4280     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4281
4282     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
4283     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4284     hr = IDirect3DDevice9_BeginScene(device);
4285     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4286     if(SUCCEEDED(hr))
4287     {
4288         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4289         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4290
4291         hr = IDirect3DDevice9_EndScene(device);
4292         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4293     }
4294
4295     color = getPixelColor(device, 1, 240);
4296     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4297
4298     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4299     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4300
4301     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4302     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4303
4304     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4305     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4306     hr = IDirect3DDevice9_BeginScene(device);
4307     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4308     if(SUCCEEDED(hr))
4309     {
4310         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4311         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4312
4313         hr = IDirect3DDevice9_EndScene(device);
4314         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4315     }
4316
4317     color = getPixelColor(device, 638, 240);
4318     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4319
4320     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4321     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4322
4323     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4324     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4325
4326     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4327     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4328     hr = IDirect3DDevice9_BeginScene(device);
4329     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4330     if(SUCCEEDED(hr))
4331     {
4332         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4333         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4334
4335         hr = IDirect3DDevice9_EndScene(device);
4336         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4337     }
4338
4339     color = getPixelColor(device, 638, 240);
4340     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4341
4342     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4343     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4344
4345     /* Cleanup */
4346     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4347     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4348     IDirect3DPixelShader9_Release(shader);
4349
4350     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4351     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4352     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4353     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4354 }
4355
4356 static void texkill_test(IDirect3DDevice9 *device)
4357 {
4358     IDirect3DPixelShader9 *shader;
4359     HRESULT hr;
4360     DWORD color;
4361
4362     const float vertex[] = {
4363     /*                          bottom  top    right    left */
4364         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
4365          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
4366         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
4367          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
4368     };
4369
4370     DWORD shader_code_11[] = {
4371     0xffff0101,                                                             /* ps_1_1                     */
4372     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4373     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
4374     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
4375     0x0000ffff                                                              /* end                        */
4376     };
4377     DWORD shader_code_20[] = {
4378     0xffff0200,                                                             /* ps_2_0                     */
4379     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
4380     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4381     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
4382     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
4383     0x0000ffff                                                              /* end                        */
4384     };
4385
4386     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4387     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4388     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4389     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4390
4391     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4392     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4393     hr = IDirect3DDevice9_BeginScene(device);
4394     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4395     if(SUCCEEDED(hr))
4396     {
4397         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4398         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4399         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4400         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4401         hr = IDirect3DDevice9_EndScene(device);
4402         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4403     }
4404     color = getPixelColor(device, 63, 46);
4405     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4406     color = getPixelColor(device, 66, 46);
4407     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4408     color = getPixelColor(device, 63, 49);
4409     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4410     color = getPixelColor(device, 66, 49);
4411     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4412
4413     color = getPixelColor(device, 578, 46);
4414     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4415     color = getPixelColor(device, 575, 46);
4416     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4417     color = getPixelColor(device, 578, 49);
4418     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4419     color = getPixelColor(device, 575, 49);
4420     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4421
4422     color = getPixelColor(device, 63, 430);
4423     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4424     color = getPixelColor(device, 63, 433);
4425     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4426     color = getPixelColor(device, 66, 433);
4427     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4428     color = getPixelColor(device, 66, 430);
4429     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4430
4431     color = getPixelColor(device, 578, 430);
4432     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4433     color = getPixelColor(device, 578, 433);
4434     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4435     color = getPixelColor(device, 575, 433);
4436     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4437     color = getPixelColor(device, 575, 430);
4438     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4439
4440     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4441     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4442
4443     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4444     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4445     IDirect3DPixelShader9_Release(shader);
4446
4447     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4448     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4449     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4450     if(FAILED(hr)) {
4451         skip("Failed to create 2.0 test shader, most likely not supported\n");
4452         return;
4453     }
4454
4455     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4456     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4457     hr = IDirect3DDevice9_BeginScene(device);
4458     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4459     if(SUCCEEDED(hr))
4460     {
4461         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4462         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4463         hr = IDirect3DDevice9_EndScene(device);
4464         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4465     }
4466
4467     color = getPixelColor(device, 63, 46);
4468     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4469     color = getPixelColor(device, 66, 46);
4470     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4471     color = getPixelColor(device, 63, 49);
4472     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4473     color = getPixelColor(device, 66, 49);
4474     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4475
4476     color = getPixelColor(device, 578, 46);
4477     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4478     color = getPixelColor(device, 575, 46);
4479     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4480     color = getPixelColor(device, 578, 49);
4481     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4482     color = getPixelColor(device, 575, 49);
4483     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4484
4485     color = getPixelColor(device, 63, 430);
4486     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4487     color = getPixelColor(device, 63, 433);
4488     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4489     color = getPixelColor(device, 66, 433);
4490     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4491     color = getPixelColor(device, 66, 430);
4492     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4493
4494     color = getPixelColor(device, 578, 430);
4495     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4496     color = getPixelColor(device, 578, 433);
4497     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4498     color = getPixelColor(device, 575, 433);
4499     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4500     color = getPixelColor(device, 575, 430);
4501     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4502
4503     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4504     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4505
4506     /* Cleanup */
4507     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4508     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4509     IDirect3DPixelShader9_Release(shader);
4510 }
4511
4512 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4513 {
4514     IDirect3D9 *d3d9;
4515     HRESULT hr;
4516     IDirect3DTexture9 *texture;
4517     IDirect3DPixelShader9 *shader;
4518     IDirect3DPixelShader9 *shader2;
4519     D3DLOCKED_RECT lr;
4520     DWORD color;
4521     DWORD shader_code[] = {
4522         0xffff0101,                             /* ps_1_1       */
4523         0x00000042, 0xb00f0000,                 /* tex t0       */
4524         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
4525         0x0000ffff                              /* end          */
4526     };
4527     DWORD shader_code2[] = {
4528         0xffff0101,                             /* ps_1_1       */
4529         0x00000042, 0xb00f0000,                 /* tex t0       */
4530         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
4531         0x0000ffff                              /* end          */
4532     };
4533
4534     float quad[] = {
4535        -1.0,   -1.0,   0.1,     0.5,    0.5,
4536         1.0,   -1.0,   0.1,     0.5,    0.5,
4537        -1.0,    1.0,   0.1,     0.5,    0.5,
4538         1.0,    1.0,   0.1,     0.5,    0.5,
4539     };
4540
4541     memset(&lr, 0, sizeof(lr));
4542     IDirect3DDevice9_GetDirect3D(device, &d3d9);
4543     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4544                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4545     IDirect3D9_Release(d3d9);
4546     if(FAILED(hr)) {
4547         skip("No D3DFMT_X8L8V8U8 support\n");
4548         return;
4549     };
4550
4551     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4552     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4553
4554     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4555     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4556     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4557     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4558     *((DWORD *) lr.pBits) = 0x11ca3141;
4559     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4560     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4561
4562     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4563     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4564     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4565     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4566
4567     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4568     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4569     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4570     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4571     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4572     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4573
4574     hr = IDirect3DDevice9_BeginScene(device);
4575     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4576     if(SUCCEEDED(hr))
4577     {
4578         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4579         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4580
4581         hr = IDirect3DDevice9_EndScene(device);
4582         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4583     }
4584     color = getPixelColor(device, 578, 430);
4585     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4586        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4587     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4588     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4589
4590     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4591     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4592     hr = IDirect3DDevice9_BeginScene(device);
4593     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4594     if(SUCCEEDED(hr))
4595     {
4596         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4597         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4598
4599         hr = IDirect3DDevice9_EndScene(device);
4600         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4601     }
4602     color = getPixelColor(device, 578, 430);
4603     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4604     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4605     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4606
4607     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4608     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4609     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4610     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4611     IDirect3DPixelShader9_Release(shader);
4612     IDirect3DPixelShader9_Release(shader2);
4613     IDirect3DTexture9_Release(texture);
4614 }
4615
4616 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4617 {
4618     HRESULT hr;
4619     IDirect3D9 *d3d;
4620     IDirect3DTexture9 *texture = NULL;
4621     IDirect3DSurface9 *surface;
4622     DWORD color;
4623     const RECT r1 = {256, 256, 512, 512};
4624     const RECT r2 = {512, 256, 768, 512};
4625     const RECT r3 = {256, 512, 512, 768};
4626     const RECT r4 = {512, 512, 768, 768};
4627     unsigned int x, y;
4628     D3DLOCKED_RECT lr;
4629     memset(&lr, 0, sizeof(lr));
4630
4631     IDirect3DDevice9_GetDirect3D(device, &d3d);
4632     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4633        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4634         skip("No autogenmipmap support\n");
4635         IDirect3D9_Release(d3d);
4636         return;
4637     }
4638     IDirect3D9_Release(d3d);
4639
4640     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4641     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4642
4643     /* Make the mipmap big, so that a smaller mipmap is used
4644      */
4645     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4646                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4647     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4648
4649     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4650     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4651     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4652     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4653     for(y = 0; y < 1024; y++) {
4654         for(x = 0; x < 1024; x++) {
4655             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4656             POINT pt;
4657
4658             pt.x = x;
4659             pt.y = y;
4660             if(PtInRect(&r1, pt)) {
4661                 *dst = 0xffff0000;
4662             } else if(PtInRect(&r2, pt)) {
4663                 *dst = 0xff00ff00;
4664             } else if(PtInRect(&r3, pt)) {
4665                 *dst = 0xff0000ff;
4666             } else if(PtInRect(&r4, pt)) {
4667                 *dst = 0xff000000;
4668             } else {
4669                 *dst = 0xffffffff;
4670             }
4671         }
4672     }
4673     hr = IDirect3DSurface9_UnlockRect(surface);
4674     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4675     IDirect3DSurface9_Release(surface);
4676
4677     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4678     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4679     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4680     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4681
4682     hr = IDirect3DDevice9_BeginScene(device);
4683     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4684     if(SUCCEEDED(hr)) {
4685         const float quad[] =  {
4686            -0.5,   -0.5,    0.1,    0.0,    0.0,
4687            -0.5,    0.5,    0.1,    0.0,    1.0,
4688             0.5,   -0.5,    0.1,    1.0,    0.0,
4689             0.5,    0.5,    0.1,    1.0,    1.0
4690         };
4691
4692         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4693         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4694         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4695         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4696         hr = IDirect3DDevice9_EndScene(device);
4697         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4698     }
4699     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4700     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4701     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4702     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4703     IDirect3DTexture9_Release(texture);
4704
4705     color = getPixelColor(device, 200, 200);
4706     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4707     color = getPixelColor(device, 280, 200);
4708     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4709     color = getPixelColor(device, 360, 200);
4710     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4711     color = getPixelColor(device, 440, 200);
4712     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4713     color = getPixelColor(device, 200, 270);
4714     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4715     color = getPixelColor(device, 280, 270);
4716     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4717     color = getPixelColor(device, 360, 270);
4718     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4719     color = getPixelColor(device, 440, 270);
4720     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4721     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4722     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4723 }
4724
4725 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4726 {
4727     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4728     IDirect3DVertexDeclaration9 *decl;
4729     HRESULT hr;
4730     DWORD color;
4731     DWORD shader_code_11[] =  {
4732         0xfffe0101,                                         /* vs_1_1           */
4733         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4734         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4735         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4736         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4737         0x0000ffff                                          /* end              */
4738     };
4739     DWORD shader_code_11_2[] =  {
4740         0xfffe0101,                                         /* vs_1_1           */
4741         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4742         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4743         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4744         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4745         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4746         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4747         0x0000ffff                                          /* end              */
4748     };
4749     DWORD shader_code_20[] =  {
4750         0xfffe0200,                                         /* vs_2_0           */
4751         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4752         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4753         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4754         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4755         0x0000ffff                                          /* end              */
4756     };
4757     DWORD shader_code_20_2[] =  {
4758         0xfffe0200,                                         /* vs_2_0           */
4759         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4760         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4761         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4762         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4763         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4764         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4765         0x0000ffff                                          /* end              */
4766     };
4767     static const D3DVERTEXELEMENT9 decl_elements[] = {
4768         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4769         D3DDECL_END()
4770     };
4771     float quad1[] = {
4772         -1.0,   -1.0,   0.1,
4773          0.0,   -1.0,   0.1,
4774         -1.0,    0.0,   0.1,
4775          0.0,    0.0,   0.1
4776     };
4777     float quad2[] = {
4778          0.0,   -1.0,   0.1,
4779          1.0,   -1.0,   0.1,
4780          0.0,    0.0,   0.1,
4781          1.0,    0.0,   0.1
4782     };
4783     float quad3[] = {
4784          0.0,    0.0,   0.1,
4785          1.0,    0.0,   0.1,
4786          0.0,    1.0,   0.1,
4787          1.0,    1.0,   0.1
4788     };
4789     float quad4[] = {
4790         -1.0,    0.0,   0.1,
4791          0.0,    0.0,   0.1,
4792         -1.0,    1.0,   0.1,
4793          0.0,    1.0,   0.1
4794     };
4795     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4796     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4797
4798     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4799     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4800
4801     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4802     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4803     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4804     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4805     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4806     if(FAILED(hr)) shader_20 = NULL;
4807     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4808     if(FAILED(hr)) shader_20_2 = NULL;
4809     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4810     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4811
4812     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4813     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4814     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4815     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4816     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4817     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4818
4819     hr = IDirect3DDevice9_BeginScene(device);
4820     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4821     if(SUCCEEDED(hr))
4822     {
4823         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4824         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4825         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4826         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4827
4828         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4829         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4830         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4831         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4832
4833         if(shader_20) {
4834             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4835             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4836             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4837             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4838         }
4839
4840         if(shader_20_2) {
4841             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4842             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4843             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4844             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4845         }
4846
4847         hr = IDirect3DDevice9_EndScene(device);
4848         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4849     }
4850
4851     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4852     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4853     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4854     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4855
4856     color = getPixelColor(device, 160, 360);
4857     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4858        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4859     color = getPixelColor(device, 480, 360);
4860     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4861        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4862     if(shader_20) {
4863         color = getPixelColor(device, 480, 120);
4864         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4865            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4866     }
4867     if(shader_20_2) {
4868         color = getPixelColor(device, 160, 120);
4869         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4870            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4871     }
4872     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4873     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4874
4875     IDirect3DVertexDeclaration9_Release(decl);
4876     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4877     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4878     IDirect3DVertexShader9_Release(shader_11_2);
4879     IDirect3DVertexShader9_Release(shader_11);
4880 }
4881
4882 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4883 {
4884     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4885     HRESULT hr;
4886     DWORD color;
4887     DWORD shader_code_11[] =  {
4888         0xffff0101,                                         /* ps_1_1           */
4889         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4890         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4891         0x0000ffff                                          /* end              */
4892     };
4893     DWORD shader_code_12[] =  {
4894         0xffff0102,                                         /* ps_1_2           */
4895         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4896         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4897         0x0000ffff                                          /* end              */
4898     };
4899     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4900      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4901      * During development of this test, 1.3 shaders were verified too
4902      */
4903     DWORD shader_code_14[] =  {
4904         0xffff0104,                                         /* ps_1_4           */
4905         /* Try to make one constant local. It gets clamped too, although the binary contains
4906          * the bigger numbers
4907          */
4908         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4909         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4910         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4911         0x0000ffff                                          /* end              */
4912     };
4913     DWORD shader_code_20[] =  {
4914         0xffff0200,                                         /* ps_2_0           */
4915         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4916         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4917         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
4918         0x0000ffff                                          /* end              */
4919     };
4920     float quad1[] = {
4921         -1.0,   -1.0,   0.1,
4922          0.0,   -1.0,   0.1,
4923         -1.0,    0.0,   0.1,
4924          0.0,    0.0,   0.1
4925     };
4926     float quad2[] = {
4927          0.0,   -1.0,   0.1,
4928          1.0,   -1.0,   0.1,
4929          0.0,    0.0,   0.1,
4930          1.0,    0.0,   0.1
4931     };
4932     float quad3[] = {
4933          0.0,    0.0,   0.1,
4934          1.0,    0.0,   0.1,
4935          0.0,    1.0,   0.1,
4936          1.0,    1.0,   0.1
4937     };
4938     float quad4[] = {
4939         -1.0,    0.0,   0.1,
4940          0.0,    0.0,   0.1,
4941         -1.0,    1.0,   0.1,
4942          0.0,    1.0,   0.1
4943     };
4944     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4945     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4946
4947     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4948     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4949
4950     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4951     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4952     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4953     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4954     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4955     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4956     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4957     if(FAILED(hr)) shader_20 = NULL;
4958
4959     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4960     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4961     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4962     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4963     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4964     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4965
4966     hr = IDirect3DDevice9_BeginScene(device);
4967     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4968     if(SUCCEEDED(hr))
4969     {
4970         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4971         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4972         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4973         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4974
4975         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4976         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4977         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4978         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4979
4980         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4981         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4982         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4983         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4984
4985         if(shader_20) {
4986             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4987             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4988             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4989             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4990         }
4991
4992         hr = IDirect3DDevice9_EndScene(device);
4993         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4994     }
4995     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4996     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4997
4998     color = getPixelColor(device, 160, 360);
4999     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5000        "quad 1 has color %08x, expected 0x00808000\n", color);
5001     color = getPixelColor(device, 480, 360);
5002     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5003        "quad 2 has color %08x, expected 0x00808000\n", color);
5004     color = getPixelColor(device, 480, 120);
5005     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5006        "quad 3 has color %08x, expected 0x00808000\n", color);
5007     if(shader_20) {
5008         color = getPixelColor(device, 160, 120);
5009         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5010            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5011     }
5012     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5013     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5014
5015     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
5016     IDirect3DPixelShader9_Release(shader_14);
5017     IDirect3DPixelShader9_Release(shader_12);
5018     IDirect3DPixelShader9_Release(shader_11);
5019 }
5020
5021 static void dp2add_ps_test(IDirect3DDevice9 *device)
5022 {
5023     IDirect3DPixelShader9 *shader_dp2add = NULL;
5024     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
5025     HRESULT hr;
5026     DWORD color;
5027
5028     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
5029      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
5030      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
5031      * r0 first.
5032      * The result here for the r,g,b components should be roughly 0.5:
5033      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
5034     static const DWORD shader_code_dp2add[] =  {
5035         0xffff0200,                                                             /* ps_2_0                       */
5036         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
5037
5038         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5039         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
5040
5041         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
5042         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5043         0x0000ffff                                                              /* end                          */
5044     };
5045
5046     /* Test the _sat modifier, too.  Result here should be:
5047      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
5048      *      _SAT: ==> 1.0
5049      *   ADD: (1.0 + -0.5) = 0.5
5050      */
5051     static const DWORD shader_code_dp2add_sat[] =  {
5052         0xffff0200,                                                             /* ps_2_0                           */
5053         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
5054
5055         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
5056         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
5057         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
5058
5059         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
5060         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
5061         0x0000ffff                                                              /* end                              */
5062     };
5063
5064     const float quad[] = {
5065         -1.0,   -1.0,   0.1,
5066          1.0,   -1.0,   0.1,
5067         -1.0,    1.0,   0.1,
5068          1.0,    1.0,   0.1
5069     };
5070
5071
5072     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
5073     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5074
5075     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
5076     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5077
5078     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
5079     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5080
5081     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5082     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5083
5084     if (shader_dp2add) {
5085
5086         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5087         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5088
5089         hr = IDirect3DDevice9_BeginScene(device);
5090         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5091         if(SUCCEEDED(hr))
5092         {
5093             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5094             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5095
5096             hr = IDirect3DDevice9_EndScene(device);
5097             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5098         }
5099
5100         color = getPixelColor(device, 360, 240);
5101         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5102                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5103
5104         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5105         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5106
5107         IDirect3DPixelShader9_Release(shader_dp2add);
5108     } else {
5109         skip("dp2add shader creation failed\n");
5110     }
5111
5112     if (shader_dp2add_sat) {
5113
5114         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5115         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5116
5117         hr = IDirect3DDevice9_BeginScene(device);
5118         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5119         if(SUCCEEDED(hr))
5120         {
5121             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5122             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5123
5124             hr = IDirect3DDevice9_EndScene(device);
5125             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5126         }
5127
5128         color = getPixelColor(device, 360, 240);
5129         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5130                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5131
5132         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5133         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5134
5135         IDirect3DPixelShader9_Release(shader_dp2add_sat);
5136     } else {
5137         skip("dp2add shader creation failed\n");
5138     }
5139
5140     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5141     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5142 }
5143
5144 static void cnd_test(IDirect3DDevice9 *device)
5145 {
5146     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
5147     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
5148     HRESULT hr;
5149     DWORD color;
5150     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
5151      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
5152      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
5153      */
5154     DWORD shader_code_11[] =  {
5155         0xffff0101,                                                                 /* ps_1_1               */
5156         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5157         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5158         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
5159         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5160         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5161         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5162         0x0000ffff                                                                  /* end                  */
5163     };
5164     DWORD shader_code_12[] =  {
5165         0xffff0102,                                                                 /* ps_1_2               */
5166         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5167         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5168         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5169         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5170         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5171         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5172         0x0000ffff                                                                  /* end                  */
5173     };
5174     DWORD shader_code_13[] =  {
5175         0xffff0103,                                                                 /* ps_1_3               */
5176         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5177         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5178         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5179         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
5180         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5181         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5182         0x0000ffff                                                                  /* end                  */
5183     };
5184     DWORD shader_code_14[] =  {
5185         0xffff0104,                                                                 /* ps_1_3               */
5186         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
5187         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
5188         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
5189         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
5190         0x0000ffff                                                                  /* end                  */
5191     };
5192
5193     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
5194      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
5195      * set by the compiler, it was added manually after compilation. Note that the COISSUE
5196      * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
5197      * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
5198      * well enough.
5199      *
5200      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
5201      * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
5202      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
5203      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
5204      */
5205     DWORD shader_code_11_coissue[] =  {
5206         0xffff0101,                                                             /* ps_1_1                   */
5207         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5208         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5209         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5210         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5211         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5212         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5213         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5214         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5215         /* 0x40000000 = D3DSI_COISSUE */
5216         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5217         0x0000ffff                                                              /* end                      */
5218     };
5219     DWORD shader_code_12_coissue[] =  {
5220         0xffff0102,                                                             /* ps_1_2                   */
5221         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5222         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5223         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5224         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5225         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5226         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5227         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5228         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5229         /* 0x40000000 = D3DSI_COISSUE */
5230         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5231         0x0000ffff                                                              /* end                      */
5232     };
5233     DWORD shader_code_13_coissue[] =  {
5234         0xffff0103,                                                             /* ps_1_3                   */
5235         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5236         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5237         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5238         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5239         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5240         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5241         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5242         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5243         /* 0x40000000 = D3DSI_COISSUE */
5244         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5245         0x0000ffff                                                              /* end                      */
5246     };
5247     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
5248      * compare against 0.5
5249      */
5250     DWORD shader_code_14_coissue[] =  {
5251         0xffff0104,                                                             /* ps_1_4                   */
5252         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
5253         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
5254         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
5255         /* 0x40000000 = D3DSI_COISSUE */
5256         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
5257         0x0000ffff                                                              /* end                      */
5258     };
5259     float quad1[] = {
5260         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5261          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5262         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5263          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
5264     };
5265     float quad2[] = {
5266          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5267          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5268          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5269          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
5270     };
5271     float quad3[] = {
5272          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5273          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5274          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5275          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
5276     };
5277     float quad4[] = {
5278         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5279          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5280         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5281          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
5282     };
5283     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
5284     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
5285     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
5286     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
5287
5288     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5289     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5290
5291     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5292     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5293     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5294     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5295     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
5296     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5297     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5298     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5299     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
5300     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5301     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5302     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5303     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5304     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5305     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5306     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5307
5308     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5309     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5310     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5311     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5312     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5313     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5314
5315     hr = IDirect3DDevice9_BeginScene(device);
5316     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5317     if(SUCCEEDED(hr))
5318     {
5319         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5320         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5321         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5322         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5323
5324         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5325         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5326         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5327         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5328
5329         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5330         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5331         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5332         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5333
5334         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5335         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5336         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5337         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5338
5339         hr = IDirect3DDevice9_EndScene(device);
5340         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5341     }
5342
5343     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5344     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5345
5346     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5347     color = getPixelColor(device, 158, 118);
5348     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5349     color = getPixelColor(device, 162, 118);
5350     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5351     color = getPixelColor(device, 158, 122);
5352     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5353     color = getPixelColor(device, 162, 122);
5354     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5355
5356     /* 1.1 shader. All 3 components get set, based on the .w comparison */
5357     color = getPixelColor(device, 158, 358);
5358     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5359     color = getPixelColor(device, 162, 358);
5360     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5361         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5362     color = getPixelColor(device, 158, 362);
5363     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5364     color = getPixelColor(device, 162, 362);
5365     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5366         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5367
5368     /* 1.2 shader */
5369     color = getPixelColor(device, 478, 358);
5370     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5371     color = getPixelColor(device, 482, 358);
5372     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5373         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5374     color = getPixelColor(device, 478, 362);
5375     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5376     color = getPixelColor(device, 482, 362);
5377     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5378         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5379
5380     /* 1.3 shader */
5381     color = getPixelColor(device, 478, 118);
5382     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5383     color = getPixelColor(device, 482, 118);
5384     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5385         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5386     color = getPixelColor(device, 478, 122);
5387     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5388     color = getPixelColor(device, 482, 122);
5389     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5390         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5391
5392     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5393     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5394
5395     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5396     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5397     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5398     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5399     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5400     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5401
5402     hr = IDirect3DDevice9_BeginScene(device);
5403     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5404     if(SUCCEEDED(hr))
5405     {
5406         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5407         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5408         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5409         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5410
5411         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5412         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5413         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5414         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5415
5416         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5417         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5418         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5419         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5420
5421         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5422         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5423         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5424         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5425
5426         hr = IDirect3DDevice9_EndScene(device);
5427         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5428     }
5429
5430     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5431     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5432
5433     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5434      * that we swapped the values in c1 and c2 to make the other tests return some color
5435      */
5436     color = getPixelColor(device, 158, 118);
5437     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5438     color = getPixelColor(device, 162, 118);
5439     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5440     color = getPixelColor(device, 158, 122);
5441     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5442     color = getPixelColor(device, 162, 122);
5443     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5444
5445     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
5446      * (The Win7 nvidia driver always selects c2)
5447      */
5448     color = getPixelColor(device, 158, 358);
5449     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5450         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5451     color = getPixelColor(device, 162, 358);
5452     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5453         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5454     color = getPixelColor(device, 158, 362);
5455     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5456         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5457     color = getPixelColor(device, 162, 362);
5458     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5459         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5460
5461     /* 1.2 shader */
5462     color = getPixelColor(device, 478, 358);
5463     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5464         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5465     color = getPixelColor(device, 482, 358);
5466     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5467         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5468     color = getPixelColor(device, 478, 362);
5469     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5470         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5471     color = getPixelColor(device, 482, 362);
5472     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5473         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5474
5475     /* 1.3 shader */
5476     color = getPixelColor(device, 478, 118);
5477     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5478         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5479     color = getPixelColor(device, 482, 118);
5480     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5481         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5482     color = getPixelColor(device, 478, 122);
5483     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5484         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5485     color = getPixelColor(device, 482, 122);
5486     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5487         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5488
5489     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5490     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5491
5492     IDirect3DPixelShader9_Release(shader_14_coissue);
5493     IDirect3DPixelShader9_Release(shader_13_coissue);
5494     IDirect3DPixelShader9_Release(shader_12_coissue);
5495     IDirect3DPixelShader9_Release(shader_11_coissue);
5496     IDirect3DPixelShader9_Release(shader_14);
5497     IDirect3DPixelShader9_Release(shader_13);
5498     IDirect3DPixelShader9_Release(shader_12);
5499     IDirect3DPixelShader9_Release(shader_11);
5500 }
5501
5502 static void nested_loop_test(IDirect3DDevice9 *device) {
5503     const DWORD shader_code[] = {
5504         0xffff0300,                                                             /* ps_3_0               */
5505         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
5506         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5507         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
5508         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
5509         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5510         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5511         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
5512         0x0000001d,                                                             /* endloop              */
5513         0x0000001d,                                                             /* endloop              */
5514         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
5515         0x0000ffff                                                              /* end                  */
5516     };
5517     const DWORD vshader_code[] = {
5518         0xfffe0300,                                                             /* vs_3_0               */
5519         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
5520         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
5521         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
5522         0x0000ffff                                                              /* end                  */
5523     };
5524     IDirect3DPixelShader9 *shader;
5525     IDirect3DVertexShader9 *vshader;
5526     HRESULT hr;
5527     DWORD color;
5528     const float quad[] = {
5529         -1.0,   -1.0,   0.1,
5530          1.0,   -1.0,   0.1,
5531         -1.0,    1.0,   0.1,
5532          1.0,    1.0,   0.1
5533     };
5534
5535     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5536     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5537     hr = IDirect3DDevice9_SetPixelShader(device, shader);
5538     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5539     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
5540     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
5541     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
5542     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5543     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5544     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5545     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5546     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5547
5548     hr = IDirect3DDevice9_BeginScene(device);
5549     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5550     if(SUCCEEDED(hr))
5551     {
5552         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5553         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5554         hr = IDirect3DDevice9_EndScene(device);
5555         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5556     }
5557
5558     color = getPixelColor(device, 360, 240);
5559     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5560        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5561
5562     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5563     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5564
5565     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5566     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5567     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5568     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5569     IDirect3DPixelShader9_Release(shader);
5570     IDirect3DVertexShader9_Release(vshader);
5571 }
5572
5573 struct varying_test_struct
5574 {
5575     const DWORD             *shader_code;
5576     IDirect3DPixelShader9   *shader;
5577     DWORD                   color, color_rhw;
5578     const char              *name;
5579     BOOL                    todo, todo_rhw;
5580 };
5581
5582 struct hugeVertex
5583 {
5584     float pos_x,        pos_y,      pos_z,      rhw;
5585     float weight_1,     weight_2,   weight_3,   weight_4;
5586     float index_1,      index_2,    index_3,    index_4;
5587     float normal_1,     normal_2,   normal_3,   normal_4;
5588     float fog_1,        fog_2,      fog_3,      fog_4;
5589     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
5590     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
5591     float binormal_1,   binormal_2, binormal_3, binormal_4;
5592     float depth_1,      depth_2,    depth_3,    depth_4;
5593     DWORD diffuse, specular;
5594 };
5595
5596 static void pretransformed_varying_test(IDirect3DDevice9 *device) {
5597     /* dcl_position: fails to compile */
5598     const DWORD blendweight_code[] = {
5599         0xffff0300,                             /* ps_3_0                   */
5600         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
5601         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5602         0x0000ffff                              /* end                      */
5603     };
5604     const DWORD blendindices_code[] = {
5605         0xffff0300,                             /* ps_3_0                   */
5606         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
5607         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5608         0x0000ffff                              /* end                      */
5609     };
5610     const DWORD normal_code[] = {
5611         0xffff0300,                             /* ps_3_0                   */
5612         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
5613         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5614         0x0000ffff                              /* end                      */
5615     };
5616     /* psize: fails? */
5617     const DWORD texcoord0_code[] = {
5618         0xffff0300,                             /* ps_3_0                   */
5619         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
5620         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5621         0x0000ffff                              /* end                      */
5622     };
5623     const DWORD tangent_code[] = {
5624         0xffff0300,                             /* ps_3_0                   */
5625         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
5626         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5627         0x0000ffff                              /* end                      */
5628     };
5629     const DWORD binormal_code[] = {
5630         0xffff0300,                             /* ps_3_0                   */
5631         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
5632         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5633         0x0000ffff                              /* end                      */
5634     };
5635     /* tessfactor: fails */
5636     /* positiont: fails */
5637     const DWORD color_code[] = {
5638         0xffff0300,                             /* ps_3_0                   */
5639         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
5640         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5641         0x0000ffff                              /* end                      */
5642     };
5643     const DWORD fog_code[] = {
5644         0xffff0300,                             /* ps_3_0                   */
5645         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
5646         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5647         0x0000ffff                              /* end                      */
5648     };
5649     const DWORD depth_code[] = {
5650         0xffff0300,                             /* ps_3_0                   */
5651         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
5652         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5653         0x0000ffff                              /* end                      */
5654     };
5655     const DWORD specular_code[] = {
5656         0xffff0300,                             /* ps_3_0                   */
5657         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
5658         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5659         0x0000ffff                              /* end                      */
5660     };
5661     /* sample: fails */
5662
5663     struct varying_test_struct tests[] = {
5664        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
5665        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
5666        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
5667        /* Why does dx not forward the texcoord? */
5668        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
5669        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
5670        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
5671        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
5672        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
5673        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
5674        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
5675     };
5676     /* Declare a monster vertex type :-) */
5677     static const D3DVERTEXELEMENT9 decl_elements[] = {
5678         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
5679         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5680         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5681         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5682         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5683         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5684         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5685         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5686         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5687         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5688         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5689         D3DDECL_END()
5690     };
5691     struct hugeVertex data[4] = {
5692         {
5693             -1.0,   -1.0,   0.1,    1.0,
5694              0.1,    0.1,   0.1,    0.1,
5695              0.2,    0.2,   0.2,    0.2,
5696              0.3,    0.3,   0.3,    0.3,
5697              0.4,    0.4,   0.4,    0.4,
5698              0.50,   0.55,  0.55,   0.55,
5699              0.6,    0.6,   0.6,    0.7,
5700              0.7,    0.7,   0.7,    0.6,
5701              0.8,    0.8,   0.8,    0.8,
5702              0xe6e6e6e6, /* 0.9 * 256 */
5703              0x224488ff  /* Nothing special */
5704         },
5705         {
5706              1.0,   -1.0,   0.1,    1.0,
5707              0.1,    0.1,   0.1,    0.1,
5708              0.2,    0.2,   0.2,    0.2,
5709              0.3,    0.3,   0.3,    0.3,
5710              0.4,    0.4,   0.4,    0.4,
5711              0.50,   0.55,  0.55,   0.55,
5712              0.6,    0.6,   0.6,    0.7,
5713              0.7,    0.7,   0.7,    0.6,
5714              0.8,    0.8,   0.8,    0.8,
5715              0xe6e6e6e6, /* 0.9 * 256 */
5716              0x224488ff /* Nothing special */
5717         },
5718         {
5719             -1.0,    1.0,   0.1,    1.0,
5720              0.1,    0.1,   0.1,    0.1,
5721              0.2,    0.2,   0.2,    0.2,
5722              0.3,    0.3,   0.3,    0.3,
5723              0.4,    0.4,   0.4,    0.4,
5724              0.50,   0.55,  0.55,   0.55,
5725              0.6,    0.6,   0.6,    0.7,
5726              0.7,    0.7,   0.7,    0.6,
5727              0.8,    0.8,   0.8,    0.8,
5728              0xe6e6e6e6, /* 0.9 * 256 */
5729              0x224488ff /* Nothing special */
5730         },
5731         {
5732              1.0,    1.0,   0.1,    1.0,
5733              0.1,    0.1,   0.1,    0.1,
5734              0.2,    0.2,   0.2,    0.2,
5735              0.3,    0.3,   0.3,    0.3,
5736              0.4,    0.4,   0.4,    0.4,
5737              0.50,   0.55,  0.55,   0.55,
5738              0.6,    0.6,   0.6,    0.7,
5739              0.7,    0.7,   0.7,    0.6,
5740              0.8,    0.8,   0.8,    0.8,
5741              0xe6e6e6e6, /* 0.9 * 256 */
5742              0x224488ff /* Nothing special */
5743         },
5744     };
5745     struct hugeVertex data2[4];
5746     IDirect3DVertexDeclaration9 *decl;
5747     HRESULT hr;
5748     unsigned int i;
5749     DWORD color, r, g, b, r_e, g_e, b_e;
5750
5751     memcpy(data2, data, sizeof(data2));
5752     data2[0].pos_x = 0;     data2[0].pos_y = 0;
5753     data2[1].pos_x = 640;   data2[1].pos_y = 0;
5754     data2[2].pos_x = 0;     data2[2].pos_y = 480;
5755     data2[3].pos_x = 640;   data2[3].pos_y = 480;
5756
5757     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5758     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5759     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5760     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5761
5762     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5763     {
5764         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5765         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5766            tests[i].name, hr);
5767     }
5768
5769     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5770     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5771     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5772     {
5773         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5774         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5775
5776         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5777         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5778
5779         hr = IDirect3DDevice9_BeginScene(device);
5780         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5781         if(SUCCEEDED(hr))
5782         {
5783             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5784             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5785             hr = IDirect3DDevice9_EndScene(device);
5786             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5787         }
5788
5789         color = getPixelColor(device, 360, 240);
5790         r = color & 0x00ff0000 >> 16;
5791         g = color & 0x0000ff00 >>  8;
5792         b = color & 0x000000ff;
5793         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5794         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
5795         b_e = tests[i].color_rhw & 0x000000ff;
5796
5797         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5798         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5799
5800         if(tests[i].todo_rhw) {
5801             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5802              * pipeline
5803              */
5804             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5805                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5806                          tests[i].name, color, tests[i].color_rhw);
5807         } else {
5808             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5809                "Test %s returned color 0x%08x, expected 0x%08x\n",
5810                tests[i].name, color, tests[i].color_rhw);
5811         }
5812     }
5813
5814     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5815     {
5816         IDirect3DPixelShader9_Release(tests[i].shader);
5817     }
5818
5819     IDirect3DVertexDeclaration9_Release(decl);
5820 }
5821
5822 static void test_compare_instructions(IDirect3DDevice9 *device)
5823 {
5824     DWORD shader_sge_vec_code[] = {
5825         0xfffe0101,                                         /* vs_1_1                   */
5826         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5827         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5828         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5829         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
5830         0x0000ffff                                          /* end                      */
5831     };
5832     DWORD shader_slt_vec_code[] = {
5833         0xfffe0101,                                         /* vs_1_1                   */
5834         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5835         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5836         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5837         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
5838         0x0000ffff                                          /* end                      */
5839     };
5840     DWORD shader_sge_scalar_code[] = {
5841         0xfffe0101,                                         /* vs_1_1                   */
5842         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5843         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5844         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5845         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
5846         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
5847         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
5848         0x0000ffff                                          /* end                      */
5849     };
5850     DWORD shader_slt_scalar_code[] = {
5851         0xfffe0101,                                         /* vs_1_1                   */
5852         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5853         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5854         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5855         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
5856         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
5857         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
5858         0x0000ffff                                          /* end                      */
5859     };
5860     IDirect3DVertexShader9 *shader_sge_vec;
5861     IDirect3DVertexShader9 *shader_slt_vec;
5862     IDirect3DVertexShader9 *shader_sge_scalar;
5863     IDirect3DVertexShader9 *shader_slt_scalar;
5864     HRESULT hr, color;
5865     float quad1[] =  {
5866         -1.0,   -1.0,   0.1,
5867          0.0,   -1.0,   0.1,
5868         -1.0,    0.0,   0.1,
5869          0.0,    0.0,   0.1
5870     };
5871     float quad2[] =  {
5872          0.0,   -1.0,   0.1,
5873          1.0,   -1.0,   0.1,
5874          0.0,    0.0,   0.1,
5875          1.0,    0.0,   0.1
5876     };
5877     float quad3[] =  {
5878         -1.0,    0.0,   0.1,
5879          0.0,    0.0,   0.1,
5880         -1.0,    1.0,   0.1,
5881          0.0,    1.0,   0.1
5882     };
5883     float quad4[] =  {
5884          0.0,    0.0,   0.1,
5885          1.0,    0.0,   0.1,
5886          0.0,    1.0,   0.1,
5887          1.0,    1.0,   0.1
5888     };
5889     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5890     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5891
5892     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5893     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5894
5895     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5896     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5897     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5898     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5899     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5900     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5901     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5902     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5903     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5904     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5905     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5906     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5907     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5908     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5909
5910     hr = IDirect3DDevice9_BeginScene(device);
5911     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5912     if(SUCCEEDED(hr))
5913     {
5914         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5915         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5916         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5917         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5918
5919         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5920         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5921         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5922         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5923
5924         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5925         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5926         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5927         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5928
5929         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5930         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5931
5932         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5933         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5934         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5935         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5936
5937         hr = IDirect3DDevice9_EndScene(device);
5938         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5939     }
5940
5941     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5942     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5943
5944     color = getPixelColor(device, 160, 360);
5945     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
5946     color = getPixelColor(device, 480, 360);
5947     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
5948     color = getPixelColor(device, 160, 120);
5949     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
5950     color = getPixelColor(device, 480, 160);
5951     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
5952
5953     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5954     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5955
5956     IDirect3DVertexShader9_Release(shader_sge_vec);
5957     IDirect3DVertexShader9_Release(shader_slt_vec);
5958     IDirect3DVertexShader9_Release(shader_sge_scalar);
5959     IDirect3DVertexShader9_Release(shader_slt_scalar);
5960 }
5961
5962 static void test_vshader_input(IDirect3DDevice9 *device)
5963 {
5964     static const DWORD swapped_shader_code_3[] =
5965     {
5966         0xfffe0300,                                         /* vs_3_0               */
5967         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5968         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5969         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5970         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5971         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5972         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5973         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5974         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5975         0x0000ffff                                          /* end                  */
5976     };
5977     static const DWORD swapped_shader_code_1[] =
5978     {
5979         0xfffe0101,                                         /* vs_1_1               */
5980         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5981         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5982         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5983         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
5984         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5985         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5986         0x0000ffff                                          /* end                  */
5987     };
5988     static const DWORD swapped_shader_code_2[] =
5989     {
5990         0xfffe0200,                                         /* vs_2_0               */
5991         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5992         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5993         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5994         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
5995         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5996         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5997         0x0000ffff                                          /* end                  */
5998     };
5999     static const DWORD texcoord_color_shader_code_3[] =
6000     {
6001         0xfffe0300,                                         /* vs_3_0               */
6002         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6003         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6004         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6005         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6006         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6007         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
6008         0x0000ffff                                          /* end                  */
6009     };
6010     static const DWORD texcoord_color_shader_code_2[] =
6011     {
6012         0xfffe0200,                                         /* vs_2_0               */
6013         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6014         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6015         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6016         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6017         0x0000ffff                                          /* end                  */
6018     };
6019     static const DWORD texcoord_color_shader_code_1[] =
6020     {
6021         0xfffe0101,                                         /* vs_1_1               */
6022         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6023         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6024         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6025         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6026         0x0000ffff                                          /* end                  */
6027     };
6028     static const DWORD color_color_shader_code_3[] =
6029     {
6030         0xfffe0300,                                         /* vs_3_0               */
6031         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6032         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6033         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6034         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6035         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6036         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
6037         0x0000ffff                                          /* end                  */
6038     };
6039     static const DWORD color_color_shader_code_2[] =
6040     {
6041         0xfffe0200,                                         /* vs_2_0               */
6042         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6043         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6044         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6045         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1      */
6046         0x0000ffff                                          /* end                  */
6047     };
6048     static const DWORD color_color_shader_code_1[] =
6049     {
6050         0xfffe0101,                                         /* vs_1_1               */
6051         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6052         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6053         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6054         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1      */
6055         0x0000ffff                                          /* end                  */
6056     };
6057     static const DWORD ps3_code[] =
6058     {
6059         0xffff0300,                                         /* ps_3_0               */
6060         0x0200001f, 0x8000000a, 0x900f0000,                 /* dcl_color0 v0        */
6061         0x02000001, 0x800f0800, 0x90e40000,                 /* mov oC0, v0          */
6062         0x0000ffff                                          /* end                  */
6063     };
6064     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6065     IDirect3DPixelShader9 *ps;
6066     HRESULT hr;
6067     DWORD color;
6068     float quad1[] =  {
6069         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6070          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6071         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6072          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6073     };
6074     float quad2[] =  {
6075          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6076          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6077          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6078          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6079     };
6080     float quad3[] =  {
6081         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
6082          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
6083         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
6084          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6085     };
6086     float quad4[] =  {
6087          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6088          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6089          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6090          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6091     };
6092     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6093         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6094         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6095         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6096         D3DDECL_END()
6097     };
6098     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6099         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6100         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6101         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6102         D3DDECL_END()
6103     };
6104     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6105         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6106         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6107         D3DDECL_END()
6108     };
6109     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6110         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6111         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6112         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
6113         D3DDECL_END()
6114     };
6115     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6116         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6117         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6118         D3DDECL_END()
6119     };
6120     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6121         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6122         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6123         D3DDECL_END()
6124     };
6125     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6126         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6127         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6128         D3DDECL_END()
6129     };
6130     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6131         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6132         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6133         D3DDECL_END()
6134     };
6135     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6136     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6137     unsigned int i;
6138     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6139     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6140
6141     struct vertex quad1_color[] =  {
6142        {-1.0,   -1.0,   0.1,    0x00ff8040},
6143        { 0.0,   -1.0,   0.1,    0x00ff8040},
6144        {-1.0,    0.0,   0.1,    0x00ff8040},
6145        { 0.0,    0.0,   0.1,    0x00ff8040}
6146     };
6147     struct vertex quad2_color[] =  {
6148        { 0.0,   -1.0,   0.1,    0x00ff8040},
6149        { 1.0,   -1.0,   0.1,    0x00ff8040},
6150        { 0.0,    0.0,   0.1,    0x00ff8040},
6151        { 1.0,    0.0,   0.1,    0x00ff8040}
6152     };
6153     struct vertex quad3_color[] =  {
6154        {-1.0,    0.0,   0.1,    0x00ff8040},
6155        { 0.0,    0.0,   0.1,    0x00ff8040},
6156        {-1.0,    1.0,   0.1,    0x00ff8040},
6157        { 0.0,    1.0,   0.1,    0x00ff8040}
6158     };
6159     float quad4_color[] =  {
6160          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6161          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6162          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6163          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6164     };
6165
6166     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6167     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6168     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6169     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6170     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6171     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6172     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6173     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6174
6175     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6176     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6177     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6178     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6179     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6180     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6181     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6182     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6183
6184     hr = IDirect3DDevice9_CreatePixelShader(device, ps3_code, &ps);
6185     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6186
6187     for(i = 1; i <= 3; i++) {
6188         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6189         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6190         if(i == 3) {
6191             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6192             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6193             hr = IDirect3DDevice9_SetPixelShader(device, ps);
6194             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6195         } else if(i == 2){
6196             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6197             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6198         } else if(i == 1) {
6199             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6200             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6201         }
6202
6203         hr = IDirect3DDevice9_BeginScene(device);
6204         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6205         if(SUCCEEDED(hr))
6206         {
6207             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6208             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6209
6210             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6211             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6212             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6213             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6214
6215             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6216             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6217             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6218             if(i == 3 || i == 2) {
6219                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6220             } else if(i == 1) {
6221                 /* Succeeds or fails, depending on SW or HW vertex processing */
6222                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6223             }
6224
6225             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6226             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6227             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6228             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6229
6230             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6231             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6232             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6233             if(i == 3 || i == 2) {
6234                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6235             } else if(i == 1) {
6236                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6237             }
6238
6239             hr = IDirect3DDevice9_EndScene(device);
6240             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6241         }
6242
6243         if(i == 3 || i == 2) {
6244             color = getPixelColor(device, 160, 360);
6245             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6246                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6247
6248             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6249             color = getPixelColor(device, 480, 360);
6250             ok(color == 0x00FFFF00 || color ==0x00FF0000,
6251                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6252             color = getPixelColor(device, 160, 120);
6253             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6254             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6255                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6256
6257             color = getPixelColor(device, 480, 160);
6258             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6259         } else if(i == 1) {
6260             color = getPixelColor(device, 160, 360);
6261             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6262                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6263             color = getPixelColor(device, 480, 360);
6264             /* Accept the clear color as well in this case, since SW VP returns an error */
6265             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6266             color = getPixelColor(device, 160, 120);
6267             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6268                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6269             color = getPixelColor(device, 480, 160);
6270             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6271         }
6272
6273         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6274         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6275
6276         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6277         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6278
6279         /* Now find out if the whole streams are re-read, or just the last active value for the
6280          * vertices is used.
6281          */
6282         hr = IDirect3DDevice9_BeginScene(device);
6283         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6284         if(SUCCEEDED(hr))
6285         {
6286             float quad1_modified[] =  {
6287                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6288                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6289                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6290                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6291             };
6292             float quad2_modified[] =  {
6293                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6294                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6295                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6296                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6297             };
6298
6299             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6300             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6301
6302             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6303             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6304             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6305             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6306
6307             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6308             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6309             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6310             if(i == 3 || i == 2) {
6311                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6312             } else if(i == 1) {
6313                 /* Succeeds or fails, depending on SW or HW vertex processing */
6314                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6315             }
6316
6317             hr = IDirect3DDevice9_EndScene(device);
6318             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6319         }
6320
6321         color = getPixelColor(device, 480, 350);
6322         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6323          * as well.
6324          *
6325          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6326          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6327          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6328          * refrast's result.
6329          *
6330          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6331          */
6332         ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6333            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6334
6335         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6336         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6337
6338         IDirect3DDevice9_SetVertexShader(device, NULL);
6339         IDirect3DDevice9_SetPixelShader(device, NULL);
6340         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6341
6342         IDirect3DVertexShader9_Release(swapped_shader);
6343     }
6344
6345     for(i = 1; i <= 3; i++) {
6346         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6347         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6348         if(i == 3) {
6349             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6350             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6351             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6352             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6353             hr = IDirect3DDevice9_SetPixelShader(device, ps);
6354             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6355         } else if(i == 2){
6356             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6357             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6358             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6359             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6360         } else if(i == 1) {
6361             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6362             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6363             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6364             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6365         }
6366
6367         hr = IDirect3DDevice9_BeginScene(device);
6368         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6369         if(SUCCEEDED(hr))
6370         {
6371             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6372             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6373             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6374             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6375             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6376             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6377
6378             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6379             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6380
6381             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6382             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6383             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6384             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6385             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6386             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6387
6388             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6389             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6390             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6391             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6392             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6393             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6394
6395             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6396             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6397             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6398             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6399
6400             hr = IDirect3DDevice9_EndScene(device);
6401             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6402         }
6403         IDirect3DDevice9_SetVertexShader(device, NULL);
6404         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6405         IDirect3DDevice9_SetPixelShader(device, NULL);
6406
6407         color = getPixelColor(device, 160, 360);
6408         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6409            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6410         color = getPixelColor(device, 480, 360);
6411         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6412            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6413         color = getPixelColor(device, 160, 120);
6414         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6415            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6416         color = getPixelColor(device, 480, 160);
6417         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6418            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6419
6420         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6421         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6422
6423         IDirect3DVertexShader9_Release(texcoord_color_shader);
6424         IDirect3DVertexShader9_Release(color_color_shader);
6425     }
6426
6427     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6428     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6429     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6430     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6431
6432     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6433     IDirect3DVertexDeclaration9_Release(decl_color_color);
6434     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6435     IDirect3DVertexDeclaration9_Release(decl_color_float);
6436
6437     IDirect3DPixelShader9_Release(ps);
6438 }
6439
6440 static void srgbtexture_test(IDirect3DDevice9 *device)
6441 {
6442     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6443      * texture stage state to render a quad using that texture.  The resulting
6444      * color components should be 0x36 (~ 0.21), per this formula:
6445      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6446      * This is true where srgb_color > 0.04045.
6447      */
6448     IDirect3D9 *d3d = NULL;
6449     HRESULT hr;
6450     LPDIRECT3DTEXTURE9 texture = NULL;
6451     LPDIRECT3DSURFACE9 surface = NULL;
6452     D3DLOCKED_RECT lr;
6453     DWORD color;
6454     float quad[] = {
6455         -1.0,       1.0,       0.0,     0.0,    0.0,
6456          1.0,       1.0,       0.0,     1.0,    0.0,
6457         -1.0,      -1.0,       0.0,     0.0,    1.0,
6458          1.0,      -1.0,       0.0,     1.0,    1.0,
6459     };
6460
6461
6462     memset(&lr, 0, sizeof(lr));
6463     IDirect3DDevice9_GetDirect3D(device, &d3d);
6464     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6465                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6466                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6467         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6468         goto out;
6469     }
6470
6471     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6472                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6473                                         &texture, NULL);
6474     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6475     if(!texture) {
6476         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6477         goto out;
6478     }
6479     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6480     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6481
6482     fill_surface(surface, 0xff7f7f7f);
6483     IDirect3DSurface9_Release(surface);
6484
6485     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6486     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6487     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6488     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6489
6490     hr = IDirect3DDevice9_BeginScene(device);
6491     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6492     if(SUCCEEDED(hr))
6493     {
6494         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6495         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6496
6497         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6498         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6499
6500
6501         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6502         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6503
6504         hr = IDirect3DDevice9_EndScene(device);
6505         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6506     }
6507
6508     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6509     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6510     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6511     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6512
6513     color = getPixelColor(device, 320, 240);
6514     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6515
6516     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6517     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6518
6519 out:
6520     if(texture) IDirect3DTexture9_Release(texture);
6521     IDirect3D9_Release(d3d);
6522 }
6523
6524 static void shademode_test(IDirect3DDevice9 *device)
6525 {
6526     /* Render a quad and try all of the different fixed function shading models. */
6527     HRESULT hr;
6528     DWORD color0, color1;
6529     DWORD color0_gouraud = 0, color1_gouraud = 0;
6530     DWORD shademode = D3DSHADE_FLAT;
6531     DWORD primtype = D3DPT_TRIANGLESTRIP;
6532     LPVOID data = NULL;
6533     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6534     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6535     UINT i, j;
6536     struct vertex quad_strip[] =
6537     {
6538         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6539         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6540         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6541         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6542     };
6543     struct vertex quad_list[] =
6544     {
6545         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6546         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6547         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6548
6549         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6550         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6551         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6552     };
6553
6554     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6555                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6556     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6557     if (FAILED(hr)) goto bail;
6558
6559     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6560                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6561     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6562     if (FAILED(hr)) goto bail;
6563
6564     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6565     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6566
6567     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6568     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6569
6570     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6571     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6572     memcpy(data, quad_strip, sizeof(quad_strip));
6573     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6574     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6575
6576     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6577     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6578     memcpy(data, quad_list, sizeof(quad_list));
6579     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6580     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6581
6582     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
6583      * the color fixups we have to do for FLAT shading will be dependent on that. */
6584     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6585     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6586
6587     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6588     for (j=0; j<2; j++) {
6589
6590         /* Inner loop just changes the D3DRS_SHADEMODE */
6591         for (i=0; i<3; i++) {
6592             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6593             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6594
6595             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6596             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6597
6598             hr = IDirect3DDevice9_BeginScene(device);
6599             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6600             if(SUCCEEDED(hr))
6601             {
6602                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6603                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6604
6605                 hr = IDirect3DDevice9_EndScene(device);
6606                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6607             }
6608
6609             /* Sample two spots from the output */
6610             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6611             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6612             switch(shademode) {
6613                 case D3DSHADE_FLAT:
6614                     /* Should take the color of the first vertex of each triangle */
6615                     if (0)
6616                     {
6617                         /* This test depends on EXT_provoking_vertex being
6618                          * available. This extension is currently (20090810)
6619                          * not common enough to let the test fail if it isn't
6620                          * present. */
6621                         ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
6622                         ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
6623                     }
6624                     shademode = D3DSHADE_GOURAUD;
6625                     break;
6626                 case D3DSHADE_GOURAUD:
6627                     /* Should be an interpolated blend */
6628
6629                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6630                        "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6631                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6632                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6633
6634                     color0_gouraud = color0;
6635                     color1_gouraud = color1;
6636
6637                     shademode = D3DSHADE_PHONG;
6638                     break;
6639                 case D3DSHADE_PHONG:
6640                     /* Should be the same as GOURAUD, since no hardware implements this */
6641                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6642                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6643                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6644                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6645
6646                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6647                             color0_gouraud, color0);
6648                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6649                             color1_gouraud, color1);
6650                     break;
6651             }
6652         }
6653
6654         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6655         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6656
6657         /* Now, do it all over again with a TRIANGLELIST */
6658         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6659         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6660         primtype = D3DPT_TRIANGLELIST;
6661         shademode = D3DSHADE_FLAT;
6662     }
6663
6664 bail:
6665     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6666     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6667     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6668     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6669
6670     if (vb_strip)
6671         IDirect3DVertexBuffer9_Release(vb_strip);
6672     if (vb_list)
6673         IDirect3DVertexBuffer9_Release(vb_list);
6674 }
6675
6676 static void alpha_test(IDirect3DDevice9 *device)
6677 {
6678     HRESULT hr;
6679     IDirect3DTexture9 *offscreenTexture;
6680     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6681     DWORD color;
6682
6683     struct vertex quad1[] =
6684     {
6685         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
6686         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
6687         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
6688         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
6689     };
6690     struct vertex quad2[] =
6691     {
6692         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
6693         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
6694         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
6695         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
6696     };
6697     static const float composite_quad[][5] = {
6698         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6699         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
6700         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6701         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
6702     };
6703
6704     /* Clear the render target with alpha = 0.5 */
6705     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6706     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6707
6708     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6709     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6710
6711     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6712     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6713     if(!backbuffer) {
6714         goto out;
6715     }
6716
6717     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6718     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6719     if(!offscreen) {
6720         goto out;
6721     }
6722
6723     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6724     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6725
6726     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6727     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6728     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6729     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6730     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6731     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6732     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6733     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6734     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6735     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6736
6737     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6738     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6739     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6740
6741         /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6742         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6743         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6744         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6745         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6746         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6747         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6748
6749         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6750         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6751         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6752         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6753         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6754         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6755
6756         /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6757          * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6758          * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6759         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6760         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6761         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6762         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6763
6764         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6765         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6766         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6767         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6768         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6769         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6770
6771         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6772         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6773         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6774         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6775         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6776         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6777
6778         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6779         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6780
6781         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6782          * Disable alpha blending for the final composition
6783          */
6784         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6785         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6786         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6787         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6788
6789         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6790         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6791         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6792         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6793         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6794         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6795
6796         hr = IDirect3DDevice9_EndScene(device);
6797         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6798     }
6799
6800     color = getPixelColor(device, 160, 360);
6801     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6802        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6803
6804     color = getPixelColor(device, 160, 120);
6805     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
6806        "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
6807
6808     color = getPixelColor(device, 480, 360);
6809     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6810        "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
6811
6812     color = getPixelColor(device, 480, 120);
6813     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
6814        "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
6815
6816     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6817
6818     out:
6819     /* restore things */
6820     if(backbuffer) {
6821         IDirect3DSurface9_Release(backbuffer);
6822     }
6823     if(offscreenTexture) {
6824         IDirect3DTexture9_Release(offscreenTexture);
6825     }
6826     if(offscreen) {
6827         IDirect3DSurface9_Release(offscreen);
6828     }
6829 }
6830
6831 struct vertex_shortcolor {
6832     float x, y, z;
6833     unsigned short r, g, b, a;
6834 };
6835 struct vertex_floatcolor {
6836     float x, y, z;
6837     float r, g, b, a;
6838 };
6839
6840 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6841 {
6842     HRESULT hr;
6843     BOOL s_ok, ub_ok, f_ok;
6844     DWORD color, size, i;
6845     void *data;
6846     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6847         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6848         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6849         D3DDECL_END()
6850     };
6851     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6852         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6853         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6854         D3DDECL_END()
6855     };
6856     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6857         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6858         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6859         D3DDECL_END()
6860     };
6861     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6862         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6863         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6864         D3DDECL_END()
6865     };
6866     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6867         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6868         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6869         D3DDECL_END()
6870     };
6871     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6872         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6873         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6874         D3DDECL_END()
6875     };
6876     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6877         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
6878         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6879         D3DDECL_END()
6880     };
6881     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6882     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6883     IDirect3DVertexBuffer9 *vb, *vb2;
6884     struct vertex quad1[] =                             /* D3DCOLOR */
6885     {
6886         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
6887         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6888         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
6889         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6890     };
6891     struct vertex quad2[] =                             /* UBYTE4N */
6892     {
6893         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6894         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
6895         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6896         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
6897     };
6898     struct vertex_shortcolor quad3[] =                  /* short */
6899     {
6900         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6901         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6902         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6903         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6904     };
6905     struct vertex_floatcolor quad4[] =
6906     {
6907         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6908         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6909         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6910         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6911     };
6912     DWORD colors[] = {
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         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6925         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6926         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6927         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6928         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6929     };
6930     float quads[] = {
6931         -1.0,   -1.0,     0.1,
6932         -1.0,    0.0,     0.1,
6933          0.0,   -1.0,     0.1,
6934          0.0,    0.0,     0.1,
6935
6936          0.0,   -1.0,     0.1,
6937          0.0,    0.0,     0.1,
6938          1.0,   -1.0,     0.1,
6939          1.0,    0.0,     0.1,
6940
6941          0.0,    0.0,     0.1,
6942          0.0,    1.0,     0.1,
6943          1.0,    0.0,     0.1,
6944          1.0,    1.0,     0.1,
6945
6946         -1.0,    0.0,     0.1,
6947         -1.0,    1.0,     0.1,
6948          0.0,    0.0,     0.1,
6949          0.0,    1.0,     0.1
6950     };
6951     struct tvertex quad_transformed[] = {
6952        {  90,    110,     0.1,      2.0,        0x00ffff00},
6953        { 570,    110,     0.1,      2.0,        0x00ffff00},
6954        {  90,    300,     0.1,      2.0,        0x00ffff00},
6955        { 570,    300,     0.1,      2.0,        0x00ffff00}
6956     };
6957     D3DCAPS9 caps;
6958
6959     memset(&caps, 0, sizeof(caps));
6960     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6961     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
6962
6963     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6964     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6965
6966     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
6967     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6968     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
6969     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
6970     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
6971     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6972     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
6973         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
6974         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6975         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
6976         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6977     } else {
6978         trace("D3DDTCAPS_UBYTE4N not supported\n");
6979         dcl_ubyte_2 = NULL;
6980         dcl_ubyte = NULL;
6981     }
6982     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
6983     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6984     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
6985     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6986
6987     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
6988     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
6989                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
6990     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6991
6992     hr = IDirect3DDevice9_BeginScene(device);
6993     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
6994     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
6995     if(SUCCEEDED(hr)) {
6996         if(dcl_color) {
6997             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
6998             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6999             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7000             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7001         }
7002
7003         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7004          * accepts them, the nvidia driver accepts them all. All those differences even though we're
7005          * using software vertex processing. Doh!
7006          */
7007         if(dcl_ubyte) {
7008             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7009             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7010             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7011             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7012             ub_ok = SUCCEEDED(hr);
7013         }
7014
7015         if(dcl_short) {
7016             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7017             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7018             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7019             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7020             s_ok = SUCCEEDED(hr);
7021         }
7022
7023         if(dcl_float) {
7024             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7025             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7026             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7027             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7028             f_ok = SUCCEEDED(hr);
7029         }
7030
7031         hr = IDirect3DDevice9_EndScene(device);
7032         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7033     }
7034
7035     if(dcl_short) {
7036         color = getPixelColor(device, 480, 360);
7037         ok(color == 0x000000ff || !s_ok,
7038            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7039     }
7040     if(dcl_ubyte) {
7041         color = getPixelColor(device, 160, 120);
7042         ok(color == 0x0000ffff || !ub_ok,
7043            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7044     }
7045     if(dcl_color) {
7046         color = getPixelColor(device, 160, 360);
7047         ok(color == 0x00ffff00,
7048            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7049     }
7050     if(dcl_float) {
7051         color = getPixelColor(device, 480, 120);
7052         ok(color == 0x00ff0000 || !f_ok,
7053            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7054     }
7055     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7056
7057     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7058      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7059      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7060      * whether the immediate mode code works
7061      */
7062     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7063     hr = IDirect3DDevice9_BeginScene(device);
7064     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7065     if(SUCCEEDED(hr)) {
7066         if(dcl_color) {
7067             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7068             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7069             memcpy(data, quad1, sizeof(quad1));
7070             hr = IDirect3DVertexBuffer9_Unlock(vb);
7071             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7072             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7073             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7074             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7075             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7076             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7077             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7078         }
7079
7080         if(dcl_ubyte) {
7081             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7082             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7083             memcpy(data, quad2, sizeof(quad2));
7084             hr = IDirect3DVertexBuffer9_Unlock(vb);
7085             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7086             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7087             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7088             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7089             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7090             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7091             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7092                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7093             ub_ok = SUCCEEDED(hr);
7094         }
7095
7096         if(dcl_short) {
7097             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7098             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7099             memcpy(data, quad3, sizeof(quad3));
7100             hr = IDirect3DVertexBuffer9_Unlock(vb);
7101             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7102             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7103             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7104             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7105             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7106             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7107             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7108                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7109             s_ok = SUCCEEDED(hr);
7110         }
7111
7112         if(dcl_float) {
7113             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7114             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7115             memcpy(data, quad4, sizeof(quad4));
7116             hr = IDirect3DVertexBuffer9_Unlock(vb);
7117             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7118             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7119             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7120             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7121             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7122             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7123             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7124                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7125             f_ok = SUCCEEDED(hr);
7126         }
7127
7128         hr = IDirect3DDevice9_EndScene(device);
7129         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7130     }
7131
7132     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7133     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7134     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7135     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7136
7137     if(dcl_short) {
7138         color = getPixelColor(device, 480, 360);
7139         ok(color == 0x000000ff || !s_ok,
7140            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7141     }
7142     if(dcl_ubyte) {
7143         color = getPixelColor(device, 160, 120);
7144         ok(color == 0x0000ffff || !ub_ok,
7145            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7146     }
7147     if(dcl_color) {
7148         color = getPixelColor(device, 160, 360);
7149         ok(color == 0x00ffff00,
7150            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7151     }
7152     if(dcl_float) {
7153         color = getPixelColor(device, 480, 120);
7154         ok(color == 0x00ff0000 || !f_ok,
7155            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7156     }
7157     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7158
7159     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7160     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7161
7162     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7163     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7164     memcpy(data, quad_transformed, sizeof(quad_transformed));
7165     hr = IDirect3DVertexBuffer9_Unlock(vb);
7166     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7167
7168     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7169     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7170
7171     hr = IDirect3DDevice9_BeginScene(device);
7172     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7173     if(SUCCEEDED(hr)) {
7174         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7175         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7176         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7177         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7178
7179         hr = IDirect3DDevice9_EndScene(device);
7180         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7181     }
7182
7183     color = getPixelColor(device, 88, 108);
7184     ok(color == 0x000000ff,
7185        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7186     color = getPixelColor(device, 92, 108);
7187     ok(color == 0x000000ff,
7188        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7189     color = getPixelColor(device, 88, 112);
7190     ok(color == 0x000000ff,
7191        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7192     color = getPixelColor(device, 92, 112);
7193     ok(color == 0x00ffff00,
7194        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7195
7196     color = getPixelColor(device, 568, 108);
7197     ok(color == 0x000000ff,
7198        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7199     color = getPixelColor(device, 572, 108);
7200     ok(color == 0x000000ff,
7201        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7202     color = getPixelColor(device, 568, 112);
7203     ok(color == 0x00ffff00,
7204        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7205     color = getPixelColor(device, 572, 112);
7206     ok(color == 0x000000ff,
7207        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7208
7209     color = getPixelColor(device, 88, 298);
7210     ok(color == 0x000000ff,
7211        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7212     color = getPixelColor(device, 92, 298);
7213     ok(color == 0x00ffff00,
7214        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7215     color = getPixelColor(device, 88, 302);
7216     ok(color == 0x000000ff,
7217        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7218     color = getPixelColor(device, 92, 302);
7219     ok(color == 0x000000ff,
7220        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7221
7222     color = getPixelColor(device, 568, 298);
7223     ok(color == 0x00ffff00,
7224        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7225     color = getPixelColor(device, 572, 298);
7226     ok(color == 0x000000ff,
7227        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7228     color = getPixelColor(device, 568, 302);
7229     ok(color == 0x000000ff,
7230        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7231     color = getPixelColor(device, 572, 302);
7232     ok(color == 0x000000ff,
7233        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7234
7235     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7236
7237     /* This test is pointless without those two declarations: */
7238     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7239         skip("color-ubyte switching test declarations aren't supported\n");
7240         goto out;
7241     }
7242
7243     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7244     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7245     memcpy(data, quads, sizeof(quads));
7246     hr = IDirect3DVertexBuffer9_Unlock(vb);
7247     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7248     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7249                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7250     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7251     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7252     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7253     memcpy(data, colors, sizeof(colors));
7254     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7255     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7256
7257     for(i = 0; i < 2; i++) {
7258         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7259         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7260
7261         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7262         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7263         if(i == 0) {
7264             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7265         } else {
7266             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7267         }
7268         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7269
7270         hr = IDirect3DDevice9_BeginScene(device);
7271         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7272         ub_ok = FALSE;
7273         if(SUCCEEDED(hr)) {
7274             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7275             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7276             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7277             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7278                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7279             ub_ok = SUCCEEDED(hr);
7280
7281             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7282             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7283             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7284             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7285
7286             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7287             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7288             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7289             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7290                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7291             ub_ok = (SUCCEEDED(hr) && ub_ok);
7292
7293             hr = IDirect3DDevice9_EndScene(device);
7294             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7295         }
7296
7297         if(i == 0) {
7298             color = getPixelColor(device, 480, 360);
7299             ok(color == 0x00ff0000,
7300                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7301             color = getPixelColor(device, 160, 120);
7302             ok(color == 0x00ffffff,
7303                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7304             color = getPixelColor(device, 160, 360);
7305             ok(color == 0x000000ff || !ub_ok,
7306                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7307             color = getPixelColor(device, 480, 120);
7308             ok(color == 0x000000ff || !ub_ok,
7309                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7310         } else {
7311             color = getPixelColor(device, 480, 360);
7312             ok(color == 0x000000ff,
7313                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7314             color = getPixelColor(device, 160, 120);
7315             ok(color == 0x00ffffff,
7316                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7317             color = getPixelColor(device, 160, 360);
7318             ok(color == 0x00ff0000 || !ub_ok,
7319                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7320             color = getPixelColor(device, 480, 120);
7321             ok(color == 0x00ff0000 || !ub_ok,
7322                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7323         }
7324         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7325     }
7326
7327     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7328     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7329     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7330     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7331     IDirect3DVertexBuffer9_Release(vb2);
7332
7333     out:
7334     IDirect3DVertexBuffer9_Release(vb);
7335     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7336     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7337     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7338     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7339     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7340     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7341     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7342 }
7343
7344 struct vertex_float16color {
7345     float x, y, z;
7346     DWORD c1, c2;
7347 };
7348
7349 static void test_vshader_float16(IDirect3DDevice9 *device)
7350 {
7351     HRESULT hr;
7352     DWORD color;
7353     void *data;
7354     static const D3DVERTEXELEMENT9 decl_elements[] = {
7355         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7356         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7357         D3DDECL_END()
7358     };
7359     IDirect3DVertexDeclaration9 *vdecl = NULL;
7360     IDirect3DVertexBuffer9 *buffer = NULL;
7361     IDirect3DVertexShader9 *shader;
7362     DWORD shader_code[] = {
7363         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7364         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7365         0x90e40001, 0x0000ffff
7366     };
7367     struct vertex_float16color quad[] = {
7368         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7369         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7370         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7371         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7372
7373         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7374         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7375         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7376         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7377
7378         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7379         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7380         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7381         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7382
7383         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7384         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7385         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7386         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7387     };
7388
7389     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7390     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7391
7392     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7393     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7394     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7395     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7396     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7397     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7398
7399     hr = IDirect3DDevice9_BeginScene(device);
7400     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7401     if(SUCCEEDED(hr)) {
7402         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7403         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7404         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7405         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7406         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7407         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7408         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7409         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7410         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7411         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7412
7413         hr = IDirect3DDevice9_EndScene(device);
7414         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7415     }
7416     color = getPixelColor(device, 480, 360);
7417     ok(color == 0x00ff0000,
7418        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7419     color = getPixelColor(device, 160, 120);
7420     ok(color == 0x00000000,
7421        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7422     color = getPixelColor(device, 160, 360);
7423     ok(color == 0x0000ff00,
7424        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7425     color = getPixelColor(device, 480, 120);
7426     ok(color == 0x000000ff,
7427        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7428     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7429
7430     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7431     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7432
7433     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7434                                              D3DPOOL_MANAGED, &buffer, NULL);
7435     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7436     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7437     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7438     memcpy(data, quad, sizeof(quad));
7439     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7440     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7441     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7442     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7443
7444     hr = IDirect3DDevice9_BeginScene(device);
7445     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7446     if(SUCCEEDED(hr)) {
7447             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7448             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7449             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7450             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7451             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7452             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7453             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7454             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7455
7456             hr = IDirect3DDevice9_EndScene(device);
7457             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7458     }
7459
7460     color = getPixelColor(device, 480, 360);
7461     ok(color == 0x00ff0000,
7462        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7463     color = getPixelColor(device, 160, 120);
7464     ok(color == 0x00000000,
7465        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7466     color = getPixelColor(device, 160, 360);
7467     ok(color == 0x0000ff00,
7468        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7469     color = getPixelColor(device, 480, 120);
7470     ok(color == 0x000000ff,
7471        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7472     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7473
7474     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7475     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7476     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7477     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7478     IDirect3DDevice9_SetVertexShader(device, NULL);
7479     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7480
7481     IDirect3DVertexDeclaration9_Release(vdecl);
7482     IDirect3DVertexShader9_Release(shader);
7483     IDirect3DVertexBuffer9_Release(buffer);
7484 }
7485
7486 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7487 {
7488     D3DCAPS9 caps;
7489     IDirect3DTexture9 *texture;
7490     HRESULT hr;
7491     D3DLOCKED_RECT rect;
7492     unsigned int x, y;
7493     DWORD *dst, color;
7494     const float quad[] = {
7495         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
7496          1.0,   -1.0,   0.1,    1.2,   -0.2,
7497         -1.0,    1.0,   0.1,   -0.2,    1.2,
7498          1.0,    1.0,   0.1,    1.2,    1.2
7499     };
7500     memset(&caps, 0, sizeof(caps));
7501
7502     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7503     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7504     if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7505         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7506         ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7507            "Card has conditional NP2 support without power of two restriction set\n");
7508         skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7509         return;
7510     } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7511         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7512         return;
7513     }
7514
7515     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7516     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7517
7518     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7519     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7520
7521     memset(&rect, 0, sizeof(rect));
7522     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7523     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7524     for(y = 0; y < 10; y++) {
7525         for(x = 0; x < 10; x++) {
7526             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7527             if(x == 0 || x == 9 || y == 0 || y == 9) {
7528                 *dst = 0x00ff0000;
7529             } else {
7530                 *dst = 0x000000ff;
7531             }
7532         }
7533     }
7534     hr = IDirect3DTexture9_UnlockRect(texture, 0);
7535     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7536
7537     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7538     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7539     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7540     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7541     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7542     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7543     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7544     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7545
7546     hr = IDirect3DDevice9_BeginScene(device);
7547     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7548     if(SUCCEEDED(hr)) {
7549         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7550         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7551
7552         hr = IDirect3DDevice9_EndScene(device);
7553         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7554     }
7555
7556     color = getPixelColor(device,    1,  1);
7557     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
7558     color = getPixelColor(device, 639, 479);
7559     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7560
7561     color = getPixelColor(device, 135, 101);
7562     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7563     color = getPixelColor(device, 140, 101);
7564     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7565     color = getPixelColor(device, 135, 105);
7566     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7567     color = getPixelColor(device, 140, 105);
7568     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7569
7570     color = getPixelColor(device, 135, 376);
7571     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7572     color = getPixelColor(device, 140, 376);
7573     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7574     color = getPixelColor(device, 135, 379);
7575     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7576     color = getPixelColor(device, 140, 379);
7577     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7578
7579     color = getPixelColor(device, 500, 101);
7580     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7581     color = getPixelColor(device, 504, 101);
7582     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7583     color = getPixelColor(device, 500, 105);
7584     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7585     color = getPixelColor(device, 504, 105);
7586     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7587
7588     color = getPixelColor(device, 500, 376);
7589     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7590     color = getPixelColor(device, 504, 376);
7591     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7592     color = getPixelColor(device, 500, 380);
7593     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7594     color = getPixelColor(device, 504, 380);
7595     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7596
7597     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7598
7599     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7600     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7601     IDirect3DTexture9_Release(texture);
7602 }
7603
7604 static void vFace_register_test(IDirect3DDevice9 *device)
7605 {
7606     HRESULT hr;
7607     DWORD color;
7608     const DWORD shader_code[] = {
7609         0xffff0300,                                                             /* ps_3_0                     */
7610         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7611         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7612         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
7613         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
7614         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
7615         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
7616         0x0000ffff                                                              /* END                        */
7617     };
7618     const DWORD vshader_code[] = {
7619         0xfffe0300,                                                             /* vs_3_0               */
7620         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
7621         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
7622         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
7623         0x0000ffff                                                              /* end                  */
7624     };
7625     IDirect3DPixelShader9 *shader;
7626     IDirect3DVertexShader9 *vshader;
7627     IDirect3DTexture9 *texture;
7628     IDirect3DSurface9 *surface, *backbuffer;
7629     const float quad[] = {
7630         -1.0,   -1.0,   0.1,
7631          1.0,   -1.0,   0.1,
7632         -1.0,    0.0,   0.1,
7633
7634          1.0,   -1.0,   0.1,
7635          1.0,    0.0,   0.1,
7636         -1.0,    0.0,   0.1,
7637
7638         -1.0,    0.0,   0.1,
7639         -1.0,    1.0,   0.1,
7640          1.0,    0.0,   0.1,
7641
7642          1.0,    0.0,   0.1,
7643         -1.0,    1.0,   0.1,
7644          1.0,    1.0,   0.1,
7645     };
7646     const float blit[] = {
7647          0.0,   -1.0,   0.1,    0.0,    0.0,
7648          1.0,   -1.0,   0.1,    1.0,    0.0,
7649          0.0,    1.0,   0.1,    0.0,    1.0,
7650          1.0,    1.0,   0.1,    1.0,    1.0,
7651     };
7652
7653     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
7654     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7655     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7656     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7657     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7658     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7659     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7660     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7661     hr = IDirect3DDevice9_SetPixelShader(device, shader);
7662     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7663     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
7664     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7665     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7666     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7667     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7668     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7669
7670     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7671     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7672
7673     hr = IDirect3DDevice9_BeginScene(device);
7674     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7675     if(SUCCEEDED(hr)) {
7676         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7677         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7678         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7679         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7680         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7681         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7682         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7683         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7684         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7685         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7686         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7687
7688         /* Blit the texture onto the back buffer to make it visible */
7689         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7690         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
7691         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7692         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7693         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7694         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7695         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7696         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7697         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7698         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7699         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7700         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7701
7702         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7703         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7704
7705         hr = IDirect3DDevice9_EndScene(device);
7706         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7707     }
7708
7709     color = getPixelColor(device, 160, 360);
7710     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7711     color = getPixelColor(device, 160, 120);
7712     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7713     color = getPixelColor(device, 480, 360);
7714     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7715     color = getPixelColor(device, 480, 120);
7716     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7717     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7718
7719     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7720     IDirect3DDevice9_SetTexture(device, 0, NULL);
7721     IDirect3DPixelShader9_Release(shader);
7722     IDirect3DVertexShader9_Release(vshader);
7723     IDirect3DSurface9_Release(surface);
7724     IDirect3DSurface9_Release(backbuffer);
7725     IDirect3DTexture9_Release(texture);
7726 }
7727
7728 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7729 {
7730     HRESULT hr;
7731     DWORD color;
7732     int i;
7733     D3DCAPS9 caps;
7734     BOOL L6V5U5_supported = FALSE;
7735     IDirect3DTexture9 *tex1, *tex2;
7736     D3DLOCKED_RECT locked_rect;
7737
7738     static const float quad[][7] = {
7739         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7740         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7741         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7742         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7743     };
7744
7745     static const D3DVERTEXELEMENT9 decl_elements[] = {
7746         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7747         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7748         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7749         D3DDECL_END()
7750     };
7751
7752     /* use asymmetric matrix to test loading */
7753     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7754     float scale, offset;
7755
7756     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7757     IDirect3DTexture9           *texture            = NULL;
7758
7759     memset(&caps, 0, sizeof(caps));
7760     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7761     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7762     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7763         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7764         return;
7765     } else {
7766         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7767          * They report that it is not supported, but after that bump mapping works properly. So just test
7768          * if the format is generally supported, and check the BUMPENVMAP flag
7769          */
7770         IDirect3D9 *d3d9;
7771
7772         IDirect3DDevice9_GetDirect3D(device, &d3d9);
7773         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7774                                           D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
7775         L6V5U5_supported = SUCCEEDED(hr);
7776         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7777                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7778         IDirect3D9_Release(d3d9);
7779         if(FAILED(hr)) {
7780             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7781             return;
7782         }
7783     }
7784
7785     /* Generate the textures */
7786     generate_bumpmap_textures(device);
7787
7788     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7789     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7790     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7791     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7792     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7793     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7794     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7795     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7796
7797     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7798     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7799     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7800     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7801     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7802     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7803
7804     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7805     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7806     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7807     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7808     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7809     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7810
7811     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7812     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7813
7814     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7815     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7816
7817     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7818     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7819
7820
7821     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7822     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7823     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7824     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7825
7826     hr = IDirect3DDevice9_BeginScene(device);
7827     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7828
7829     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7830     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7831
7832     hr = IDirect3DDevice9_EndScene(device);
7833     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7834
7835     /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
7836      * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
7837      * But since testing the color match is not the purpose of the test don't be too picky
7838      */
7839     color = getPixelColor(device, 320-32, 240);
7840     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7841     color = getPixelColor(device, 320+32, 240);
7842     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7843     color = getPixelColor(device, 320, 240-32);
7844     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7845     color = getPixelColor(device, 320, 240+32);
7846     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7847     color = getPixelColor(device, 320, 240);
7848     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7849     color = getPixelColor(device, 320+32, 240+32);
7850     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7851     color = getPixelColor(device, 320-32, 240+32);
7852     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7853     color = getPixelColor(device, 320+32, 240-32);
7854     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7855     color = getPixelColor(device, 320-32, 240-32);
7856     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7857     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7858     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7859
7860     for(i = 0; i < 2; i++) {
7861         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7862         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7863         IDirect3DTexture9_Release(texture); /* For the GetTexture */
7864         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7865         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7866         IDirect3DTexture9_Release(texture); /* To destroy it */
7867     }
7868
7869     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
7870         skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
7871         goto cleanup;
7872     }
7873     if(L6V5U5_supported == FALSE) {
7874         skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
7875         goto cleanup;
7876     }
7877
7878     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
7879     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7880     /* This test only tests the luminance part. The bumpmapping part was already tested above and
7881      * would only make this test more complicated
7882      */
7883     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
7884     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7885     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
7886     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7887
7888     memset(&locked_rect, 0, sizeof(locked_rect));
7889     hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
7890     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7891     *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
7892     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
7893     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7894
7895     memset(&locked_rect, 0, sizeof(locked_rect));
7896     hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
7897     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7898     *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
7899     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
7900     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7901
7902     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
7903     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7904     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
7905     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7906
7907     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
7908     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7909     scale = 2.0;
7910     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7911     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7912     offset = 0.1;
7913     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7914     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7915
7916     hr = IDirect3DDevice9_BeginScene(device);
7917     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7918     if(SUCCEEDED(hr)) {
7919         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7920         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7921         hr = IDirect3DDevice9_EndScene(device);
7922         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7923     }
7924
7925     color = getPixelColor(device, 320, 240);
7926     /* red:   1.0  * (0.25 * 2.0 + 0.1) = 1.0  * 0.6 = 0.6  = 0x99
7927      * green: 0.5  * (0.25 * 2.0 + 0.1) = 0.5  * 0.6 = 0.3  = 0x4c
7928      * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
7929      */
7930     ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
7931     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7932     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7933
7934     /* Check a result scale factor > 1.0 */
7935     scale = 10;
7936     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7937     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7938     offset = 10;
7939     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7940     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7941
7942     hr = IDirect3DDevice9_BeginScene(device);
7943     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7944     if(SUCCEEDED(hr)) {
7945         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7946         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7947         hr = IDirect3DDevice9_EndScene(device);
7948         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7949     }
7950     color = getPixelColor(device, 320, 240);
7951     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7952     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7953     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7954
7955     /* Check clamping in the scale factor calculation */
7956     scale = 1000;
7957     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7958     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7959     offset = -1;
7960     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7961     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7962
7963     hr = IDirect3DDevice9_BeginScene(device);
7964     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7965     if(SUCCEEDED(hr)) {
7966         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7967         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7968         hr = IDirect3DDevice9_EndScene(device);
7969         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7970     }
7971     color = getPixelColor(device, 320, 240);
7972     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7973     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7974     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7975
7976     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7977     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7978     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
7979     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7980
7981     IDirect3DTexture9_Release(tex1);
7982     IDirect3DTexture9_Release(tex2);
7983
7984 cleanup:
7985     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
7986     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7987     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
7988     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7989
7990     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7991     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
7992     IDirect3DVertexDeclaration9_Release(vertex_declaration);
7993 }
7994
7995 static void stencil_cull_test(IDirect3DDevice9 *device) {
7996     HRESULT hr;
7997     IDirect3DSurface9 *depthstencil = NULL;
7998     D3DSURFACE_DESC desc;
7999     float quad1[] = {
8000         -1.0,   -1.0,   0.1,
8001          0.0,   -1.0,   0.1,
8002         -1.0,    0.0,   0.1,
8003          0.0,    0.0,   0.1,
8004     };
8005     float quad2[] = {
8006          0.0,   -1.0,   0.1,
8007          1.0,   -1.0,   0.1,
8008          0.0,    0.0,   0.1,
8009          1.0,    0.0,   0.1,
8010     };
8011     float quad3[] = {
8012         0.0,    0.0,   0.1,
8013         1.0,    0.0,   0.1,
8014         0.0,    1.0,   0.1,
8015         1.0,    1.0,   0.1,
8016     };
8017     float quad4[] = {
8018         -1.0,    0.0,   0.1,
8019          0.0,    0.0,   0.1,
8020         -1.0,    1.0,   0.1,
8021          0.0,    1.0,   0.1,
8022     };
8023     struct vertex painter[] = {
8024        {-1.0,   -1.0,   0.0,    0x00000000},
8025        { 1.0,   -1.0,   0.0,    0x00000000},
8026        {-1.0,    1.0,   0.0,    0x00000000},
8027        { 1.0,    1.0,   0.0,    0x00000000},
8028     };
8029     WORD indices_cw[]  = {0, 1, 3};
8030     WORD indices_ccw[] = {0, 2, 3};
8031     unsigned int i;
8032     DWORD color;
8033
8034     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8035     if(depthstencil == NULL) {
8036         skip("No depth stencil buffer\n");
8037         return;
8038     }
8039     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8040     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8041     IDirect3DSurface9_Release(depthstencil);
8042     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8043         skip("No 4 or 8 bit stencil surface\n");
8044         return;
8045     }
8046
8047     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8048     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8049     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8050
8051     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8052     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8053     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8054     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8055     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8056     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8057     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8058     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8059
8060     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8061     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8062     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8063     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8064     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8065     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8066
8067     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8068     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8069     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8070     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8071
8072     /* First pass: Fill the stencil buffer with some values... */
8073     hr = IDirect3DDevice9_BeginScene(device);
8074     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8075     if(SUCCEEDED(hr))
8076     {
8077         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8078         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8079         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8080                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8081         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8082         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8083                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8084         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8085
8086         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8087         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8088         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8089         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8090         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8091                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8092         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8093         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8094                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8095         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8096
8097         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8098         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8099         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8100                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8101         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8102         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8103                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8104         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8105
8106         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8107         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8108         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8109                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8110         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8111         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8112                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8113         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8114
8115         hr = IDirect3DDevice9_EndScene(device);
8116         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8117     }
8118
8119     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8120     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8121     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8122     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8123     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8124     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8125     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8126     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8127     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8128     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8129     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8130     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8131     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8132
8133     /* 2nd pass: Make the stencil values visible */
8134     hr = IDirect3DDevice9_BeginScene(device);
8135     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8136     if(SUCCEEDED(hr))
8137     {
8138         IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8139         for(i = 0; i < 16; i++) {
8140             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8141             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8142
8143             painter[0].diffuse = (i * 16); /* Creates shades of blue */
8144             painter[1].diffuse = (i * 16);
8145             painter[2].diffuse = (i * 16);
8146             painter[3].diffuse = (i * 16);
8147             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8148             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8149         }
8150         hr = IDirect3DDevice9_EndScene(device);
8151         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8152     }
8153
8154     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8155     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8156
8157     color = getPixelColor(device, 160, 420);
8158     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8159     color = getPixelColor(device, 160, 300);
8160     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8161
8162     color = getPixelColor(device, 480, 420);
8163     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8164     color = getPixelColor(device, 480, 300);
8165     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8166
8167     color = getPixelColor(device, 160, 180);
8168     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8169     color = getPixelColor(device, 160, 60);
8170     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8171
8172     color = getPixelColor(device, 480, 180);
8173     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8174     color = getPixelColor(device, 480, 60);
8175     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8176
8177     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8178     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8179 }
8180
8181 static void vpos_register_test(IDirect3DDevice9 *device)
8182 {
8183     HRESULT hr;
8184     DWORD color;
8185     const DWORD shader_code[] = {
8186     0xffff0300,                                                             /* ps_3_0                     */
8187     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8188     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8189     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8190     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8191     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8192     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8193     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8194     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8195     0x0000ffff                                                              /* end                        */
8196     };
8197     const DWORD shader_frac_code[] = {
8198     0xffff0300,                                                             /* ps_3_0                     */
8199     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8200     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8201     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8202     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8203     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8204     0x0000ffff                                                              /* end                        */
8205     };
8206     const DWORD vshader_code[] = {
8207         0xfffe0300,                                                             /* vs_3_0               */
8208         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
8209         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
8210         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
8211         0x0000ffff                                                              /* end                  */
8212     };
8213     IDirect3DVertexShader9 *vshader;
8214     IDirect3DPixelShader9 *shader, *shader_frac;
8215     IDirect3DSurface9 *surface = NULL, *backbuffer;
8216     const float quad[] = {
8217         -1.0,   -1.0,   0.1,    0.0,    0.0,
8218          1.0,   -1.0,   0.1,    1.0,    0.0,
8219         -1.0,    1.0,   0.1,    0.0,    1.0,
8220          1.0,    1.0,   0.1,    1.0,    1.0,
8221     };
8222     D3DLOCKED_RECT lr;
8223     float constant[4] = {1.0, 0.0, 320, 240};
8224     DWORD *pos;
8225
8226     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8227     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8228     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8229     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8230     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8231     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8232     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8233     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8234     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8235     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8236     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8237     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8238     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8239     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8240     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8241     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8242
8243     hr = IDirect3DDevice9_BeginScene(device);
8244     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8245     if(SUCCEEDED(hr)) {
8246         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8247         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8248         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8249         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8250         hr = IDirect3DDevice9_EndScene(device);
8251         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8252     }
8253
8254     /* This has to be pixel exact */
8255     color = getPixelColor(device, 319, 239);
8256     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8257     color = getPixelColor(device, 320, 239);
8258     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8259     color = getPixelColor(device, 319, 240);
8260     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8261     color = getPixelColor(device, 320, 240);
8262     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8263     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8264
8265     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8266                                              &surface, NULL);
8267     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8268     hr = IDirect3DDevice9_BeginScene(device);
8269     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8270     if(SUCCEEDED(hr)) {
8271         constant[2] = 16; constant[3] = 16;
8272         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8273         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8274         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8275         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8276         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8277         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8278         hr = IDirect3DDevice9_EndScene(device);
8279         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8280     }
8281     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8282     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8283
8284     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8285     color = *pos & 0x00ffffff;
8286     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8287     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8288     color = *pos & 0x00ffffff;
8289     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8290     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8291     color = *pos & 0x00ffffff;
8292     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8293     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8294     color = *pos & 0x00ffffff;
8295     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8296
8297     hr = IDirect3DSurface9_UnlockRect(surface);
8298     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8299
8300     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8301      * have full control over the multisampling setting inside this test
8302      */
8303     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8304     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8305     hr = IDirect3DDevice9_BeginScene(device);
8306     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8307     if(SUCCEEDED(hr)) {
8308         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8309         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8310         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8311         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8312         hr = IDirect3DDevice9_EndScene(device);
8313         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8314     }
8315     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8316     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8317
8318     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8319     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8320
8321     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8322     color = *pos & 0x00ffffff;
8323     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8324
8325     hr = IDirect3DSurface9_UnlockRect(surface);
8326     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8327
8328     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8329     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8330     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8331     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8332     IDirect3DPixelShader9_Release(shader);
8333     IDirect3DPixelShader9_Release(shader_frac);
8334     IDirect3DVertexShader9_Release(vshader);
8335     if(surface) IDirect3DSurface9_Release(surface);
8336     IDirect3DSurface9_Release(backbuffer);
8337 }
8338
8339 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
8340 {
8341     D3DCOLOR color;
8342
8343     color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
8344     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8345     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8346     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8347     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8348
8349     ++r;
8350     color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
8351     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8352     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8353     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8354     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8355
8356     return TRUE;
8357 }
8358
8359 static void pointsize_test(IDirect3DDevice9 *device)
8360 {
8361     HRESULT hr;
8362     D3DCAPS9 caps;
8363     D3DMATRIX matrix;
8364     D3DMATRIX identity;
8365     float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8366     DWORD color;
8367     IDirect3DSurface9 *rt, *backbuffer;
8368     IDirect3DTexture9 *tex1, *tex2;
8369     RECT rect = {0, 0, 128, 128};
8370     D3DLOCKED_RECT lr;
8371     const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8372                                 0x00000000, 0x00000000};
8373     const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8374                                 0x00000000, 0x0000ff00};
8375
8376     const float vertices[] = {
8377         64,     64,     0.1,
8378         128,    64,     0.1,
8379         192,    64,     0.1,
8380         256,    64,     0.1,
8381         320,    64,     0.1,
8382         384,    64,     0.1,
8383         448,    64,     0.1,
8384         512,    64,     0.1,
8385     };
8386
8387     /* 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 */
8388     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;
8389     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;
8390     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;
8391     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;
8392
8393     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;
8394     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;
8395     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;
8396     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;
8397
8398     memset(&caps, 0, sizeof(caps));
8399     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8400     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8401     if(caps.MaxPointSize < 32.0) {
8402         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8403         return;
8404     }
8405
8406     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8407     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8408     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8409     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8410     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8411     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8412     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8413     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8414
8415     hr = IDirect3DDevice9_BeginScene(device);
8416     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8417     if (SUCCEEDED(hr))
8418     {
8419         ptsize = 15.0;
8420         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8421         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8422         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8423         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8424
8425         ptsize = 31.0;
8426         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8427         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8428         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8429         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8430
8431         ptsize = 30.75;
8432         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8433         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8434         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8435         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8436
8437         if (caps.MaxPointSize >= 63.0)
8438         {
8439             ptsize = 63.0;
8440             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8441             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8442             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8443             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8444
8445             ptsize = 62.75;
8446             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8447             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8448             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8449             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8450         }
8451
8452         ptsize = 1.0;
8453         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8454         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8455         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8456         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8457
8458         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8459         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8460         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8461         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8462
8463         /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8464         ptsize = 15.0;
8465         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8466         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8467         ptsize = 1.0;
8468         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8469         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8470         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8471         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8472
8473         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8474         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8475
8476         /* pointsize < pointsize_min < pointsize_max?
8477          * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
8478         ptsize = 1.0;
8479         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8480         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8481         ptsize = 15.0;
8482         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8483         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8484         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8485         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8486
8487         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8488         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8489
8490         hr = IDirect3DDevice9_EndScene(device);
8491         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8492     }
8493
8494     ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
8495     ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
8496     ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
8497
8498     if (caps.MaxPointSize >= 63.0)
8499     {
8500         ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
8501         ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
8502     }
8503
8504     ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
8505     /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
8506     ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
8507     /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
8508     ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
8509
8510     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8511
8512     /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8513      * generates texture coordinates for the point(result: Yes, it does)
8514      *
8515      * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8516      * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8517      * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8518      */
8519     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8520     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8521
8522     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8523     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8524     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8525     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8526     memset(&lr, 0, sizeof(lr));
8527     hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8528     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8529     memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8530     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8531     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8532     memset(&lr, 0, sizeof(lr));
8533     hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8534     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8535     memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8536     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8537     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8538     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8539     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8540     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8541     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8542     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8543     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8544     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8545     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8546     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8547     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8548     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8549     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8550     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8551     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8552
8553     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8554     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8555     ptsize = 32.0;
8556     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8557     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8558
8559     hr = IDirect3DDevice9_BeginScene(device);
8560     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8561     if(SUCCEEDED(hr))
8562     {
8563         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8564         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8565         hr = IDirect3DDevice9_EndScene(device);
8566         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8567     }
8568
8569     color = getPixelColor(device, 64-4, 64-4);
8570     ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
8571     color = getPixelColor(device, 64-4, 64+4);
8572     ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
8573     color = getPixelColor(device, 64+4, 64+4);
8574     ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
8575     color = getPixelColor(device, 64+4, 64-4);
8576     ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
8577     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8578
8579     U(matrix).m[0][0] =  1.0f / 64.0f;
8580     U(matrix).m[1][1] = -1.0f / 64.0f;
8581     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8582     ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
8583
8584     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
8585     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
8586
8587     hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
8588             D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
8589     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
8590
8591     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
8592     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8593     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 0.0f, 0);
8594     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
8595
8596     hr = IDirect3DDevice9_BeginScene(device);
8597     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
8598     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8599     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
8600     hr = IDirect3DDevice9_EndScene(device);
8601     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
8602
8603     hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
8604     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
8605     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8606     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8607     IDirect3DSurface9_Release(backbuffer);
8608     IDirect3DSurface9_Release(rt);
8609
8610     color = getPixelColor(device, 64-4, 64-4);
8611     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
8612             "Expected color 0x00ff0000, got 0x%08x.\n", color);
8613     color = getPixelColor(device, 64+4, 64-4);
8614     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
8615             "Expected color 0x00ffff00, got 0x%08x.\n", color);
8616     color = getPixelColor(device, 64-4, 64+4);
8617     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
8618             "Expected color 0x00000000, got 0x%08x.\n", color);
8619     color = getPixelColor(device, 64+4, 64+4);
8620     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
8621             "Expected color 0x0000ff00, got 0x%08x.\n", color);
8622
8623     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8624     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
8625
8626     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8627     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8628     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8629     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8630     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8631     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8632     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8633     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8634     IDirect3DTexture9_Release(tex1);
8635     IDirect3DTexture9_Release(tex2);
8636
8637     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
8638     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8639     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8640     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8641     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8642     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8643 }
8644
8645 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8646 {
8647     static const DWORD vshader_code[] =
8648     {
8649         0xfffe0300,                                                             /* vs_3_0                     */
8650         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0            */
8651         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0            */
8652         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                 */
8653         0x0000ffff                                                              /* end                        */
8654     };
8655     static const DWORD pshader_code1[] =
8656     {
8657         0xffff0300,                                                             /* ps_3_0                     */
8658         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8659         0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
8660         0x0000ffff                                                              /* end                        */
8661     };
8662     static const DWORD pshader_code2[] =
8663     {
8664         0xffff0300,                                                             /* ps_3_0                     */
8665         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8666         0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
8667         0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
8668         0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1                */
8669         0x0000ffff                                                              /* end                        */
8670     };
8671
8672     HRESULT hr;
8673     IDirect3DVertexShader9 *vs;
8674     IDirect3DPixelShader9 *ps1, *ps2;
8675     IDirect3DTexture9 *tex1, *tex2;
8676     IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
8677     D3DCAPS9 caps;
8678     DWORD color;
8679     UINT i, j;
8680     float quad[] = {
8681        -1.0,   -1.0,    0.1,
8682         1.0,   -1.0,    0.1,
8683        -1.0,    1.0,    0.1,
8684         1.0,    1.0,    0.1,
8685     };
8686     float texquad[] = {
8687        -1.0,   -1.0,    0.1,    0.0,    0.0,
8688         0.0,   -1.0,    0.1,    1.0,    0.0,
8689        -1.0,    1.0,    0.1,    0.0,    1.0,
8690         0.0,    1.0,    0.1,    1.0,    1.0,
8691
8692         0.0,   -1.0,    0.1,    0.0,    0.0,
8693         1.0,   -1.0,    0.1,    1.0,    0.0,
8694         0.0,    1.0,    0.1,    0.0,    1.0,
8695         1.0,    1.0,    0.1,    1.0,    1.0,
8696     };
8697
8698     memset(&caps, 0, sizeof(caps));
8699     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8700     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8701     if(caps.NumSimultaneousRTs < 2) {
8702         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8703         return;
8704     }
8705
8706     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8707     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8708
8709     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
8710             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
8711     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
8712
8713     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
8714             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8715     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8716     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
8717             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8718     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8719     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
8720     ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
8721     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code1, &ps1);
8722     ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
8723     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code2, &ps2);
8724     ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
8725
8726     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8727     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8728     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8729     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8730     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8731     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8732
8733     hr = IDirect3DDevice9_SetVertexShader(device, vs);
8734     ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
8735     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8736     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8737     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8738     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8739     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8740     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8741
8742     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
8743     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
8744     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, 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     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
8750     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8751     color = getPixelColorFromSurface(readback, 8, 8);
8752     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
8753             "Expected color 0x000000ff, got 0x%08x.\n", color);
8754
8755     /* Render targets not written by the pixel shader should be unmodified. */
8756     hr = IDirect3DDevice9_SetPixelShader(device, ps1);
8757     ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
8758     hr = IDirect3DDevice9_BeginScene(device);
8759     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
8760     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8761     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
8762     hr = IDirect3DDevice9_EndScene(device);
8763     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
8764     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
8765     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8766     color = getPixelColorFromSurface(readback, 8, 8);
8767     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
8768             "Expected color 0xff00ff00, got 0x%08x.\n", color);
8769     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
8770     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8771     for (i = 6; i < 10; ++i)
8772     {
8773         for (j = 6; j < 10; ++j)
8774         {
8775             color = getPixelColorFromSurface(readback, j, i);
8776             ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
8777                     "Expected color 0xff0000ff, got 0x%08x at %u, %u.\n", color, j, i);
8778         }
8779     }
8780
8781     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
8782     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
8783     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, 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     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
8789     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8790     color = getPixelColorFromSurface(readback, 8, 8);
8791     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
8792             "Expected color 0x0000ff00, got 0x%08x.\n", color);
8793
8794     hr = IDirect3DDevice9_SetPixelShader(device, ps2);
8795     ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
8796
8797     hr = IDirect3DDevice9_BeginScene(device);
8798     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8799     if(SUCCEEDED(hr)) {
8800         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8801         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8802
8803         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8804         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
8805         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8806         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8807         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8808         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8809         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8810         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8811         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8812         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8813
8814         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8815         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8816         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8817         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8818
8819         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8820         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8821         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8822         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8823
8824         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8825         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8826
8827         hr = IDirect3DDevice9_EndScene(device);
8828         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8829     }
8830
8831     color = getPixelColor(device, 160, 240);
8832     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8833     color = getPixelColor(device, 480, 240);
8834     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8835     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8836
8837     IDirect3DPixelShader9_Release(ps2);
8838     IDirect3DPixelShader9_Release(ps1);
8839     IDirect3DVertexShader9_Release(vs);
8840     IDirect3DTexture9_Release(tex1);
8841     IDirect3DTexture9_Release(tex2);
8842     IDirect3DSurface9_Release(surf1);
8843     IDirect3DSurface9_Release(surf2);
8844     IDirect3DSurface9_Release(backbuf);
8845     IDirect3DSurface9_Release(readback);
8846 }
8847
8848 struct formats {
8849     const char *fmtName;
8850     D3DFORMAT textureFormat;
8851     DWORD resultColorBlending;
8852     DWORD resultColorNoBlending;
8853 };
8854
8855 static const struct formats test_formats[] = {
8856   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
8857   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8858   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8859   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8860   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8861   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8862   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8863   { NULL, 0 }
8864 };
8865
8866 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8867 {
8868     HRESULT hr;
8869     IDirect3DTexture9 *offscreenTexture = NULL;
8870     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8871     IDirect3D9 *d3d = NULL;
8872     DWORD color;
8873     DWORD r0, g0, b0, r1, g1, b1;
8874     int fmt_index;
8875
8876     static const float quad[][5] = {
8877         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8878         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
8879         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8880         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
8881     };
8882
8883     /* Quad with R=0x10, G=0x20 */
8884     static const struct vertex quad1[] = {
8885         {-1.0f, -1.0f, 0.1f, 0x80102000},
8886         {-1.0f,  1.0f, 0.1f, 0x80102000},
8887         { 1.0f, -1.0f, 0.1f, 0x80102000},
8888         { 1.0f,  1.0f, 0.1f, 0x80102000},
8889     };
8890
8891     /* Quad with R=0x20, G=0x10 */
8892     static const struct vertex quad2[] = {
8893         {-1.0f, -1.0f, 0.1f, 0x80201000},
8894         {-1.0f,  1.0f, 0.1f, 0x80201000},
8895         { 1.0f, -1.0f, 0.1f, 0x80201000},
8896         { 1.0f,  1.0f, 0.1f, 0x80201000},
8897     };
8898
8899     IDirect3DDevice9_GetDirect3D(device, &d3d);
8900
8901     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8902     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8903     if(!backbuffer) {
8904         goto out;
8905     }
8906
8907     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8908     {
8909         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8910
8911         if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
8912                 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
8913         {
8914             skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
8915             continue;
8916         }
8917
8918         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8919         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8920
8921         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8922         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
8923         if(!offscreenTexture) {
8924             continue;
8925         }
8926
8927         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8928         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8929         if(!offscreen) {
8930             continue;
8931         }
8932
8933         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8934         ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8935
8936         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8937         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8938         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8939         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8940         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8941         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8942         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8943         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8944         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8945         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8946
8947         /* Below we will draw two quads with different colors and try to blend them together.
8948          * The result color is compared with the expected outcome.
8949          */
8950         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8951             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8952             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8953             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8954             ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8955
8956             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8957             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8958
8959             /* Draw a quad using color 0x0010200 */
8960             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8961             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8962             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8963             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8964             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8965             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8966
8967             /* Draw a quad using color 0x0020100 */
8968             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8969             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8970             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8971             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8972             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8973             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8974
8975             /* We don't want to blend the result on the backbuffer */
8976             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8977             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8978
8979             /* Prepare rendering the 'blended' texture quad to the backbuffer */
8980             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8981             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8982             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8983             ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
8984
8985             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8986             ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8987
8988             /* This time with the texture */
8989             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8990             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
8991
8992             IDirect3DDevice9_EndScene(device);
8993         }
8994
8995         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
8996             /* Compare the color of the center quad with our expectation */
8997             color = getPixelColor(device, 320, 240);
8998             r0 = (color & 0x00ff0000) >> 16;
8999             g0 = (color & 0x0000ff00) >>  8;
9000             b0 = (color & 0x000000ff) >>  0;
9001
9002             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
9003             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
9004             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
9005
9006             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9007                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9008                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9009                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9010         } else {
9011             /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9012              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9013              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9014             color = getPixelColor(device, 320, 240);
9015             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);
9016         }
9017         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9018
9019         IDirect3DDevice9_SetTexture(device, 0, NULL);
9020         if(offscreenTexture) {
9021             IDirect3DTexture9_Release(offscreenTexture);
9022         }
9023         if(offscreen) {
9024             IDirect3DSurface9_Release(offscreen);
9025         }
9026     }
9027
9028 out:
9029     /* restore things */
9030     if(backbuffer) {
9031         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9032         IDirect3DSurface9_Release(backbuffer);
9033     }
9034 }
9035
9036 static void tssargtemp_test(IDirect3DDevice9 *device)
9037 {
9038     HRESULT hr;
9039     DWORD color;
9040     static const struct vertex quad[] = {
9041         {-1.0,     -1.0,    0.1,    0x00ff0000},
9042         { 1.0,     -1.0,    0.1,    0x00ff0000},
9043         {-1.0,      1.0,    0.1,    0x00ff0000},
9044         { 1.0,      1.0,    0.1,    0x00ff0000}
9045     };
9046     D3DCAPS9 caps;
9047
9048     memset(&caps, 0, sizeof(caps));
9049     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9050     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9051     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9052         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9053         return;
9054     }
9055
9056     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9057     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9058
9059     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9060     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9061     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9062     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9063
9064     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9065     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9066     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9067     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9068     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9069     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9070
9071     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9072     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9073     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9074     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9075     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9076     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9077
9078     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9079     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9080
9081     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9082     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9083     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9084     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9085
9086     hr = IDirect3DDevice9_BeginScene(device);
9087     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9088     if(SUCCEEDED(hr)) {
9089         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9090         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9091         hr = IDirect3DDevice9_EndScene(device);
9092         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9093     }
9094     color = getPixelColor(device, 320, 240);
9095     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9096     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9097
9098     /* Set stage 1 back to default */
9099     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9100     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9101     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9102     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9103     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9104     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9105     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9106     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9107     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9108     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9109 }
9110
9111 struct testdata
9112 {
9113     DWORD idxVertex; /* number of instances in the first stream */
9114     DWORD idxColor; /* number of instances in the second stream */
9115     DWORD idxInstance; /* should be 1 ?? */
9116     DWORD color1; /* color 1 instance */
9117     DWORD color2; /* color 2 instance */
9118     DWORD color3; /* color 3 instance */
9119     DWORD color4; /* color 4 instance */
9120     WORD strVertex; /* specify which stream to use 0-2*/
9121     WORD strColor;
9122     WORD strInstance;
9123 };
9124
9125 static const struct testdata testcases[]=
9126 {
9127     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
9128     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
9129     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
9130     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
9131     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  4 */
9132     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
9133     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
9134     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
9135     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  8 */
9136     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /*  9 */
9137     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 10 */
9138     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 11 */
9139     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 12 */
9140     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 13 */
9141 /*
9142     This draws one instance on some machines, no instance on others
9143     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2},
9144 */
9145 /*
9146     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
9147     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9148 */
9149 };
9150
9151 /* Drawing Indexed Geometry with instances*/
9152 static void stream_test(IDirect3DDevice9 *device)
9153 {
9154     IDirect3DVertexBuffer9 *vb = NULL;
9155     IDirect3DVertexBuffer9 *vb2 = NULL;
9156     IDirect3DVertexBuffer9 *vb3 = NULL;
9157     IDirect3DIndexBuffer9 *ib = NULL;
9158     IDirect3DVertexDeclaration9 *pDecl = NULL;
9159     IDirect3DVertexShader9 *shader = NULL;
9160     HRESULT hr;
9161     BYTE *data;
9162     DWORD color;
9163     DWORD ind;
9164     unsigned i;
9165
9166     const DWORD shader_code[] =
9167     {
9168         0xfffe0101,                                     /* vs_1_1 */
9169         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
9170         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
9171         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
9172         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
9173         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9174         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
9175         0x0000ffff
9176     };
9177
9178     const float quad[][3] =
9179     {
9180         {-0.5f, -0.5f,  1.1f}, /*0 */
9181         {-0.5f,  0.5f,  1.1f}, /*1 */
9182         { 0.5f, -0.5f,  1.1f}, /*2 */
9183         { 0.5f,  0.5f,  1.1f}, /*3 */
9184     };
9185
9186     const float vertcolor[][4] =
9187     {
9188         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9189         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9190         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9191         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9192     };
9193
9194     /* 4 position for 4 instances */
9195     const float instancepos[][3] =
9196     {
9197         {-0.6f,-0.6f, 0.0f},
9198         { 0.6f,-0.6f, 0.0f},
9199         { 0.6f, 0.6f, 0.0f},
9200         {-0.6f, 0.6f, 0.0f},
9201     };
9202
9203     short indices[] = {0, 1, 2, 1, 2, 3};
9204
9205     D3DVERTEXELEMENT9 decl[] =
9206     {
9207         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9208         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9209         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9210         D3DDECL_END()
9211     };
9212
9213     /* set the default value because it isn't done in wine? */
9214     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9215     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9216
9217     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9218     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9219     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9220
9221     /* check wrong cases */
9222     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9223     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9224     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9225     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9226     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9227     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9228     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9229     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9230     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9231     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9232     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9233     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9234     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9235     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9236     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9237     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9238     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9239     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9240     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9241     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9242
9243     /* set the default value back */
9244     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9245     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9246
9247     /* create all VertexBuffers*/
9248     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9249     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9250     if(!vb) {
9251         skip("Failed to create a vertex buffer\n");
9252         return;
9253     }
9254     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9255     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9256     if(!vb2) {
9257         skip("Failed to create a vertex buffer\n");
9258         goto out;
9259     }
9260     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9261     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9262     if(!vb3) {
9263         skip("Failed to create a vertex buffer\n");
9264         goto out;
9265     }
9266
9267     /* create IndexBuffer*/
9268     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9269     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9270     if(!ib) {
9271         skip("Failed to create a index buffer\n");
9272         goto out;
9273     }
9274
9275     /* copy all Buffers (Vertex + Index)*/
9276     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9277     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9278     memcpy(data, quad, sizeof(quad));
9279     hr = IDirect3DVertexBuffer9_Unlock(vb);
9280     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9281     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9282     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9283     memcpy(data, vertcolor, sizeof(vertcolor));
9284     hr = IDirect3DVertexBuffer9_Unlock(vb2);
9285     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9286     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9287     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9288     memcpy(data, instancepos, sizeof(instancepos));
9289     hr = IDirect3DVertexBuffer9_Unlock(vb3);
9290     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9291     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9292     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9293     memcpy(data, indices, sizeof(indices));
9294     hr = IDirect3DIndexBuffer9_Unlock(ib);
9295     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9296
9297     /* create VertexShader */
9298     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9299     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9300     if(!shader) {
9301         skip("Failed to create a vetex shader\n");
9302         goto out;
9303     }
9304
9305     hr = IDirect3DDevice9_SetVertexShader(device, shader);
9306     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9307
9308     hr = IDirect3DDevice9_SetIndices(device, ib);
9309     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9310
9311     /* run all tests */
9312     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9313     {
9314         struct testdata act = testcases[i];
9315         decl[0].Stream = act.strVertex;
9316         decl[1].Stream = act.strColor;
9317         decl[2].Stream = act.strInstance;
9318         /* create VertexDeclarations */
9319         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9320         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9321
9322         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9323         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9324
9325         hr = IDirect3DDevice9_BeginScene(device);
9326         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9327         if(SUCCEEDED(hr))
9328         {
9329             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9330             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9331
9332             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9333             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9334             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9335             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9336
9337             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9338             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9339             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9340             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9341
9342             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9343             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9344             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9345             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9346
9347             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
9348             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9349             hr = IDirect3DDevice9_EndScene(device);
9350             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9351
9352             /* set all StreamSource && StreamSourceFreq back to default */
9353             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9354             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9355             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9356             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9357             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9358             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9359             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9360             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9361             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9362             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9363             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9364             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9365         }
9366
9367         hr = IDirect3DVertexDeclaration9_Release(pDecl);
9368         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9369
9370         color = getPixelColor(device, 160, 360);
9371         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9372         color = getPixelColor(device, 480, 360);
9373         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9374         color = getPixelColor(device, 480, 120);
9375         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9376         color = getPixelColor(device, 160, 120);
9377         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9378
9379         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9380         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9381     }
9382
9383     hr = IDirect3DDevice9_SetIndices(device, NULL);
9384     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9385
9386 out:
9387     if(vb) IDirect3DVertexBuffer9_Release(vb);
9388     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9389     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9390     if(ib)IDirect3DIndexBuffer9_Release(ib);
9391     if(shader)IDirect3DVertexShader9_Release(shader);
9392 }
9393
9394 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9395     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9396     IDirect3DTexture9 *dsttex = NULL;
9397     HRESULT hr;
9398     DWORD color;
9399     D3DRECT r1 = {0,  0,  50,  50 };
9400     D3DRECT r2 = {50, 0,  100, 50 };
9401     D3DRECT r3 = {50, 50, 100, 100};
9402     D3DRECT r4 = {0,  50,  50, 100};
9403     const float quad[] = {
9404         -1.0,   -1.0,   0.1,    0.0,    0.0,
9405          1.0,   -1.0,   0.1,    1.0,    0.0,
9406         -1.0,    1.0,   0.1,    0.0,    1.0,
9407          1.0,    1.0,   0.1,    1.0,    1.0,
9408     };
9409
9410     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9411     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9412
9413     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9414     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9415     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9416     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9417
9418     if(!src || !dsttex) {
9419         skip("One or more test resources could not be created\n");
9420         goto cleanup;
9421     }
9422
9423     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9424     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9425
9426     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9427     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9428
9429     /* Clear the StretchRect destination for debugging */
9430     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9431     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9432     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9433     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9434
9435     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9436     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9437
9438     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9439     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9440     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9441     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9442     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9443     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9444     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9445     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9446
9447     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9448      * the target -> texture GL blit path
9449      */
9450     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9451     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9452     IDirect3DSurface9_Release(dst);
9453
9454     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9455     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9456
9457     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9458     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9459     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9460     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9461     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9462     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9463     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9464     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9465
9466     hr = IDirect3DDevice9_BeginScene(device);
9467     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9468     if(SUCCEEDED(hr)) {
9469         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9470         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9471         hr = IDirect3DDevice9_EndScene(device);
9472         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9473     }
9474
9475     color = getPixelColor(device, 160, 360);
9476     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9477     color = getPixelColor(device, 480, 360);
9478     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9479     color = getPixelColor(device, 480, 120);
9480     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9481     color = getPixelColor(device, 160, 120);
9482     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9483     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9484     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9485
9486     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9487     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9488     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9489     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9490
9491 cleanup:
9492     if(src) IDirect3DSurface9_Release(src);
9493     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9494     if(dsttex) IDirect3DTexture9_Release(dsttex);
9495 }
9496
9497 static void texop_test(IDirect3DDevice9 *device)
9498 {
9499     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9500     IDirect3DTexture9 *texture = NULL;
9501     D3DLOCKED_RECT locked_rect;
9502     D3DCOLOR color;
9503     D3DCAPS9 caps;
9504     HRESULT hr;
9505     unsigned i;
9506
9507     static const struct {
9508         float x, y, z;
9509         float s, t;
9510         D3DCOLOR diffuse;
9511     } quad[] = {
9512         {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9513         {-1.0f,  1.0f, 0.1f, -1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9514         { 1.0f, -1.0f, 0.1f,  1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9515         { 1.0f,  1.0f, 0.1f,  1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9516     };
9517
9518     static const D3DVERTEXELEMENT9 decl_elements[] = {
9519         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9520         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9521         {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9522         D3DDECL_END()
9523     };
9524
9525     static const struct {
9526         D3DTEXTUREOP op;
9527         const char *name;
9528         DWORD caps_flag;
9529         D3DCOLOR result;
9530     } test_data[] = {
9531         {D3DTOP_SELECTARG1,                "SELECTARG1",                D3DTEXOPCAPS_SELECTARG1,                D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9532         {D3DTOP_SELECTARG2,                "SELECTARG2",                D3DTEXOPCAPS_SELECTARG2,                D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9533         {D3DTOP_MODULATE,                  "MODULATE",                  D3DTEXOPCAPS_MODULATE,                  D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9534         {D3DTOP_MODULATE2X,                "MODULATE2X",                D3DTEXOPCAPS_MODULATE2X,                D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9535         {D3DTOP_MODULATE4X,                "MODULATE4X",                D3DTEXOPCAPS_MODULATE4X,                D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9536         {D3DTOP_ADD,                       "ADD",                       D3DTEXOPCAPS_ADD,                       D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9537         {D3DTOP_ADDSIGNED,                 "ADDSIGNED",                 D3DTEXOPCAPS_ADDSIGNED,                 D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9538         {D3DTOP_ADDSIGNED2X,               "ADDSIGNED2X",               D3DTEXOPCAPS_ADDSIGNED2X,               D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9539         {D3DTOP_SUBTRACT,                  "SUBTRACT",                  D3DTEXOPCAPS_SUBTRACT,                  D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9540         {D3DTOP_ADDSMOOTH,                 "ADDSMOOTH",                 D3DTEXOPCAPS_ADDSMOOTH,                 D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9541         {D3DTOP_BLENDDIFFUSEALPHA,         "BLENDDIFFUSEALPHA",         D3DTEXOPCAPS_BLENDDIFFUSEALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9542         {D3DTOP_BLENDTEXTUREALPHA,         "BLENDTEXTUREALPHA",         D3DTEXOPCAPS_BLENDTEXTUREALPHA,         D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9543         {D3DTOP_BLENDFACTORALPHA,          "BLENDFACTORALPHA",          D3DTEXOPCAPS_BLENDFACTORALPHA,          D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9544         {D3DTOP_BLENDTEXTUREALPHAPM,       "BLENDTEXTUREALPHAPM",       D3DTEXOPCAPS_BLENDTEXTUREALPHAPM,       D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9545         {D3DTOP_BLENDCURRENTALPHA,         "BLENDCURRENTALPHA",         D3DTEXOPCAPS_BLENDCURRENTALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9546         {D3DTOP_MODULATEALPHA_ADDCOLOR,    "MODULATEALPHA_ADDCOLOR",    D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR,    D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9547         {D3DTOP_MODULATECOLOR_ADDALPHA,    "MODULATECOLOR_ADDALPHA",    D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA,    D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9548         {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9549         {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9550         /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9551         {D3DTOP_DOTPRODUCT3,               "DOTPRODUCT3",               D3DTEXOPCAPS_DOTPRODUCT3,               D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9552         {D3DTOP_MULTIPLYADD,               "MULTIPLYADD",               D3DTEXOPCAPS_MULTIPLYADD,               D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9553         {D3DTOP_LERP,                      "LERP",                      D3DTEXOPCAPS_LERP,                      D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9554     };
9555
9556     memset(&caps, 0, sizeof(caps));
9557     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9558     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9559
9560     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9561     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9562     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9563     ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9564
9565     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9566     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9567     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9568     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9569     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9570     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9571     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9572     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9573     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9574
9575     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9576     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9577     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9578     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9579     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9580     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9581
9582     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9583     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9584
9585     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9586     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9587     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9588     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9589     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9590     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9591
9592     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9593     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9594
9595     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9596     {
9597         if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9598         {
9599             skip("tex operation %s not supported\n", test_data[i].name);
9600             continue;
9601         }
9602
9603         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9604         ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9605
9606         hr = IDirect3DDevice9_BeginScene(device);
9607         ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9608
9609         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9610         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9611
9612         hr = IDirect3DDevice9_EndScene(device);
9613         ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9614
9615         color = getPixelColor(device, 320, 240);
9616         ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9617                 test_data[i].name, color, test_data[i].result);
9618
9619         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9620         ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9621     }
9622
9623     if (texture) IDirect3DTexture9_Release(texture);
9624     if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9625 }
9626
9627 static void yuv_color_test(IDirect3DDevice9 *device) {
9628     HRESULT hr;
9629     IDirect3DSurface9 *surface = NULL, *target = NULL;
9630     unsigned int fmt, i;
9631     D3DFORMAT format;
9632     const char *fmt_string;
9633     D3DLOCKED_RECT lr;
9634     IDirect3D9 *d3d;
9635     HRESULT color;
9636     DWORD ref_color_left, ref_color_right;
9637
9638     struct {
9639         DWORD in;           /* The input color */
9640         DWORD uyvy_left;    /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9641         DWORD uyvy_right;   /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9642         DWORD yuy2_left;    /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9643         DWORD yuy2_right;   /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9644     } test_data[] = {
9645     /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9646      * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9647      * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9648      * that
9649      */
9650       { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9651       { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9652       { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9653       { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9654       { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9655       { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9656       { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9657       { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9658       { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9659       { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9660       { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9661       { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9662       { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9663       { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9664
9665       { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9666       { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9667       { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9668       { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9669     };
9670
9671     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9672     ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9673     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9674     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9675
9676     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9677     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9678
9679     for(fmt = 0; fmt < 2; fmt++) {
9680         if(fmt == 0) {
9681             format = D3DFMT_UYVY;
9682             fmt_string = "D3DFMT_UYVY";
9683         } else {
9684             format = D3DFMT_YUY2;
9685             fmt_string = "D3DFMT_YUY2";
9686         }
9687
9688         /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9689                        * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9690                        */
9691         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9692                                         D3DRTYPE_SURFACE, format) != D3D_OK) {
9693             skip("%s is not supported\n", fmt_string);
9694             continue;
9695         }
9696
9697         /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9698         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9699         ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9700
9701         for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9702             if(fmt == 0) {
9703                 ref_color_left = test_data[i].uyvy_left;
9704                 ref_color_right = test_data[i].uyvy_right;
9705             } else {
9706                 ref_color_left = test_data[i].yuy2_left;
9707                 ref_color_right = test_data[i].yuy2_right;
9708             }
9709
9710             memset(&lr, 0, sizeof(lr));
9711             hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9712             ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9713             *((DWORD *) lr.pBits) = test_data[i].in;
9714             hr = IDirect3DSurface9_UnlockRect(surface);
9715             ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9716
9717             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9718             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9719             hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9720             ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9721
9722             /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9723              * prevent running into precision problems, read a far left and far right pixel. In the future we may
9724              * want to add tests for the filtered pixels as well.
9725              *
9726              * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9727              * differently, so we need a max diff of 16
9728              */
9729             color = getPixelColor(device, 40, 240);
9730
9731             /* Newer versions of the Nvidia Windows driver mix up the U and V channels, breaking all the tests
9732              * where U != V. Skip the entire test if this bug in this case
9733              */
9734             if (broken(test_data[i].in == 0xff000000 && color == 0x00008800 && format == D3DFMT_UYVY))
9735             {
9736                 skip("Nvidia channel confusion bug detected, skipping YUV tests\n");
9737                 IDirect3DSurface9_Release(surface);
9738                 goto out;
9739             }
9740
9741             ok(color_match(color, ref_color_left, 18),
9742                "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9743                test_data[i].in, color, ref_color_left, fmt_string);
9744             color = getPixelColor(device, 600, 240);
9745             ok(color_match(color, ref_color_right, 18),
9746                "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9747                test_data[i].in, color, ref_color_right, fmt_string);
9748             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9749             ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9750         }
9751         IDirect3DSurface9_Release(surface);
9752     }
9753
9754 out:
9755     IDirect3DSurface9_Release(target);
9756     IDirect3D9_Release(d3d);
9757 }
9758
9759 static void texop_range_test(IDirect3DDevice9 *device)
9760 {
9761     static const struct {
9762         float x, y, z;
9763         D3DCOLOR diffuse;
9764     } quad[] = {
9765         {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9766         {-1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9767         { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9768         { 1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
9769     };
9770     HRESULT hr;
9771     IDirect3DTexture9 *texture;
9772     D3DLOCKED_RECT locked_rect;
9773     D3DCAPS9 caps;
9774     DWORD color;
9775
9776     /* We need ADD and SUBTRACT operations */
9777     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9778     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9779     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
9780         skip("D3DTOP_ADD is not supported, skipping value range test\n");
9781         return;
9782     }
9783     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
9784         skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
9785         return;
9786     }
9787
9788     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9789     ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
9790     /* Stage 1: result = diffuse(=1.0) + diffuse
9791      * stage 2: result = result - tfactor(= 0.5)
9792      */
9793     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9794     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9795     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9796     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9797     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9798     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9799     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9800     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9801     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9802     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9803     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9804     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9805     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9806     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9807
9808     hr = IDirect3DDevice9_BeginScene(device);
9809     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9810     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9811     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9812     hr = IDirect3DDevice9_EndScene(device);
9813     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9814
9815     color = getPixelColor(device, 320, 240);
9816     ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
9817        color);
9818     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9819     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9820
9821     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9822     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9823     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9824     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9825     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
9826     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9827     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9828     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9829     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9830
9831     /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
9832      * stage 2: result = result + diffuse(1.0)
9833      */
9834     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9835     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9836     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9837     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9838     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9839     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9840     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9841     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9842     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9843     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9844     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9845     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9846     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9847     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9848
9849     hr = IDirect3DDevice9_BeginScene(device);
9850     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9851     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9852     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9853     hr = IDirect3DDevice9_EndScene(device);
9854     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9855
9856     color = getPixelColor(device, 320, 240);
9857     ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
9858        color);
9859     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9860     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9861
9862     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9863     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9864     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9865     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9866     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9867     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9868     IDirect3DTexture9_Release(texture);
9869 }
9870
9871 static void alphareplicate_test(IDirect3DDevice9 *device) {
9872     struct vertex quad[] = {
9873         { -1.0,    -1.0,    0.1,    0x80ff00ff },
9874         {  1.0,    -1.0,    0.1,    0x80ff00ff },
9875         { -1.0,     1.0,    0.1,    0x80ff00ff },
9876         {  1.0,     1.0,    0.1,    0x80ff00ff },
9877     };
9878     HRESULT hr;
9879     DWORD color;
9880
9881     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9882     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9883
9884     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9885     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9886
9887     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9888     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9889     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
9890     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9891
9892     hr = IDirect3DDevice9_BeginScene(device);
9893     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9894     if(SUCCEEDED(hr)) {
9895         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9896         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9897         hr = IDirect3DDevice9_EndScene(device);
9898         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
9899     }
9900
9901     color = getPixelColor(device, 320, 240);
9902     ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
9903        color);
9904     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9905     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9906
9907     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9908     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9909
9910 }
9911
9912 static void dp3_alpha_test(IDirect3DDevice9 *device) {
9913     HRESULT hr;
9914     D3DCAPS9 caps;
9915     DWORD color;
9916     struct vertex quad[] = {
9917         { -1.0,    -1.0,    0.1,    0x408080c0 },
9918         {  1.0,    -1.0,    0.1,    0x408080c0 },
9919         { -1.0,     1.0,    0.1,    0x408080c0 },
9920         {  1.0,     1.0,    0.1,    0x408080c0 },
9921     };
9922
9923     memset(&caps, 0, sizeof(caps));
9924     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9925     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9926     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
9927         skip("D3DTOP_DOTPRODUCT3 not supported\n");
9928         return;
9929     }
9930
9931     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9932     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9933
9934     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9935     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9936
9937     /* dp3_x4 r0, diffuse_bias, tfactor_bias
9938      * mov r0.a, diffuse.a
9939      * mov r0, r0.a
9940      *
9941      * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
9942      * 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
9943      * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
9944      */
9945     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
9946     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9947     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9948     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9949     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9950     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9951     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
9952     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9953     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
9954     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9955     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9956     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9957     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
9958     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9959     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9960     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9961     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
9962     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9963
9964     hr = IDirect3DDevice9_BeginScene(device);
9965     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9966     if(SUCCEEDED(hr)) {
9967         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9968         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9969         hr = IDirect3DDevice9_EndScene(device);
9970         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
9971     }
9972
9973     color = getPixelColor(device, 320, 240);
9974     ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
9975        color);
9976     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9977     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9978
9979     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9980     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9981     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9982     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9983     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9984     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9985 }
9986
9987 static void zwriteenable_test(IDirect3DDevice9 *device) {
9988     HRESULT hr;
9989     DWORD color;
9990     struct vertex quad1[] = {
9991         { -1.0,  -1.0,  0.1,    0x00ff0000},
9992         { -1.0,   1.0,  0.1,    0x00ff0000},
9993         {  1.0,  -1.0,  0.1,    0x00ff0000},
9994         {  1.0,   1.0,  0.1,    0x00ff0000},
9995     };
9996     struct vertex quad2[] = {
9997         { -1.0,  -1.0,  0.9,    0x0000ff00},
9998         { -1.0,   1.0,  0.9,    0x0000ff00},
9999         {  1.0,  -1.0,  0.9,    0x0000ff00},
10000         {  1.0,   1.0,  0.9,    0x0000ff00},
10001     };
10002
10003     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
10004     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10005
10006     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10007     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10008     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10009     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10010     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10011     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10012     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10013     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10014
10015     hr = IDirect3DDevice9_BeginScene(device);
10016     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10017     if(SUCCEEDED(hr)) {
10018         /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10019          * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10020          * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10021          * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10022          * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10023          * the screen is green, so zenable = D3DZB_FALSE and zwriteenable  = TRUE does NOT write to the z buffer.
10024          */
10025         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10026         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10027         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10028         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10029         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10030         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10031
10032         hr = IDirect3DDevice9_EndScene(device);
10033         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10034     }
10035
10036     color = getPixelColor(device, 320, 240);
10037     ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10038        color);
10039     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10040     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10041
10042     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10043     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10044 }
10045
10046 static void alphatest_test(IDirect3DDevice9 *device) {
10047 #define ALPHATEST_PASSED 0x0000ff00
10048 #define ALPHATEST_FAILED 0x00ff0000
10049     struct {
10050         D3DCMPFUNC  func;
10051         DWORD       color_less;
10052         DWORD       color_equal;
10053         DWORD       color_greater;
10054     } testdata[] = {
10055         {   D3DCMP_NEVER,           ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10056         {   D3DCMP_LESS,            ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10057         {   D3DCMP_EQUAL,           ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10058         {   D3DCMP_LESSEQUAL,       ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10059         {   D3DCMP_GREATER,         ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10060         {   D3DCMP_NOTEQUAL,        ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10061         {   D3DCMP_GREATEREQUAL,    ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10062         {   D3DCMP_ALWAYS,          ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10063     };
10064     unsigned int i, j;
10065     HRESULT hr;
10066     DWORD color;
10067     struct vertex quad[] = {
10068         {   -1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10069         {    1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10070         {   -1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10071         {    1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10072     };
10073     D3DCAPS9 caps;
10074
10075     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10076     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10077     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10078     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10079
10080     for(j = 0; j < 2; j++) {
10081         if(j == 1) {
10082             /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10083              * the alpha test either for performance reasons(floating point RTs) or to work
10084              * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10085              * codepath for ffp and shader in this case, and the test should cover both
10086              */
10087             IDirect3DPixelShader9 *ps;
10088             DWORD shader_code[] = {
10089                 0xffff0101,                                 /* ps_1_1           */
10090                 0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
10091                 0x0000ffff                                  /* end              */
10092             };
10093             memset(&caps, 0, sizeof(caps));
10094             IDirect3DDevice9_GetDeviceCaps(device, &caps);
10095             ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10096             if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10097                 break;
10098             }
10099
10100             hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10101             ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10102             IDirect3DDevice9_SetPixelShader(device, ps);
10103             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10104             IDirect3DPixelShader9_Release(ps);
10105         }
10106
10107         for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10108             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10109             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10110
10111             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10112             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10113             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10114             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10115             hr = IDirect3DDevice9_BeginScene(device);
10116             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10117             if(SUCCEEDED(hr)) {
10118                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10119                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10120                 hr = IDirect3DDevice9_EndScene(device);
10121                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10122             }
10123             color = getPixelColor(device, 320, 240);
10124             ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10125             color, testdata[i].color_less, testdata[i].func);
10126             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10127             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10128
10129             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10130             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10131             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10132             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10133             hr = IDirect3DDevice9_BeginScene(device);
10134             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10135             if(SUCCEEDED(hr)) {
10136                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10137                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10138                 hr = IDirect3DDevice9_EndScene(device);
10139                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10140             }
10141             color = getPixelColor(device, 320, 240);
10142             ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10143             color, testdata[i].color_equal, testdata[i].func);
10144             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10145             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10146
10147             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10148             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10149             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10150             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10151             hr = IDirect3DDevice9_BeginScene(device);
10152             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10153             if(SUCCEEDED(hr)) {
10154                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10155                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10156                 hr = IDirect3DDevice9_EndScene(device);
10157                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10158             }
10159             color = getPixelColor(device, 320, 240);
10160             ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10161             color, testdata[i].color_greater, testdata[i].func);
10162             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10163             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10164         }
10165     }
10166
10167     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10168     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10169     IDirect3DDevice9_SetPixelShader(device, NULL);
10170     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10171 }
10172
10173 static void sincos_test(IDirect3DDevice9 *device) {
10174     const DWORD sin_shader_code[] = {
10175         0xfffe0200,                                                                 /* vs_2_0                       */
10176         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10177         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10178         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10179         0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.y, r1.x, c0, c1    */
10180         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10181         0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002,                             /* mul oPos.y, r0.y, c2.w       */
10182         0x02000001, 0xd00f0000, 0xa0a60002,                                         /* mov oD0, c2.zyzz             */
10183         0x0000ffff                                                                  /* end                          */
10184     };
10185     const DWORD cos_shader_code[] = {
10186         0xfffe0200,                                                                 /* vs_2_0                       */
10187         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10188         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10189         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10190         0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.x, r1.x, c0, c1    */
10191         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10192         0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002,                             /* mul oPos.y, r0.x, c2.w       */
10193         0x02000001, 0xd00f0000, 0xa0a90002,                                         /* mov oD0, c2.yzzz             */
10194         0x0000ffff                                                                  /* end                          */
10195     };
10196     IDirect3DVertexShader9 *sin_shader, *cos_shader;
10197     HRESULT hr;
10198     struct {
10199         float x, y, z;
10200     } data[1280];
10201     unsigned int i;
10202     float sincosc1[4] = {D3DSINCOSCONST1};
10203     float sincosc2[4] = {D3DSINCOSCONST2};
10204
10205     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10206     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10207
10208     hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10209     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10210     hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10211     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10212     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10213     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10214     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10215     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10216     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10217     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10218
10219     /* Generate a point from -1 to 1 every 0.5 pixels */
10220     for(i = 0; i < 1280; i++) {
10221         data[i].x = (-640.0 + i) / 640.0;
10222         data[i].y = 0.0;
10223         data[i].z = 0.1;
10224     }
10225
10226     hr = IDirect3DDevice9_BeginScene(device);
10227     if(SUCCEEDED(hr)) {
10228         hr = IDirect3DDevice9_SetVertexShader(device, sin_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_SetVertexShader(device, cos_shader);
10234         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10235         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10236         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10237
10238         hr = IDirect3DDevice9_EndScene(device);
10239         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10240     }
10241     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10242     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10243     /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10244
10245     IDirect3DDevice9_SetVertexShader(device, NULL);
10246     IDirect3DVertexShader9_Release(sin_shader);
10247     IDirect3DVertexShader9_Release(cos_shader);
10248 }
10249
10250 static void loop_index_test(IDirect3DDevice9 *device) {
10251     const DWORD shader_code[] = {
10252         0xfffe0200,                                                 /* vs_2_0                   */
10253         0x0200001f, 0x80000000, 0x900f0000,                         /* dcl_position v0          */
10254         0x02000001, 0x800f0000, 0xa0e40000,                         /* mov r0, c0               */
10255         0x0200001b, 0xf0e40800, 0xf0e40000,                         /* loop aL, i0              */
10256         0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1]    */
10257         0x0000001d,                                                 /* endloop                  */
10258         0x02000001, 0xc00f0000, 0x90e40000,                         /* mov oPos, v0             */
10259         0x02000001, 0xd00f0000, 0x80e40000,                         /* mov oD0, r0              */
10260         0x0000ffff                                                  /* END                      */
10261     };
10262     IDirect3DVertexShader9 *shader;
10263     HRESULT hr;
10264     DWORD color;
10265     const float quad[] = {
10266         -1.0,   -1.0,   0.1,
10267          1.0,   -1.0,   0.1,
10268         -1.0,    1.0,   0.1,
10269          1.0,    1.0,   0.1
10270     };
10271     const float zero[4] = {0, 0, 0, 0};
10272     const float one[4] = {1, 1, 1, 1};
10273     int i0[4] = {2, 10, -3, 0};
10274     float values[4];
10275
10276     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10277     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10278     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10279     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10280     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10281     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10282     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10283     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10284
10285     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10286     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10287     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10288     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10289     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10290     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10291     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10292     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10293     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10294     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10295     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10296     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10297     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10298     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10299     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10300     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10301     values[0] = 1.0;
10302     values[1] = 1.0;
10303     values[2] = 0.0;
10304     values[3] = 0.0;
10305     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10306     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10307     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10308     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10309     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10310     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10311     values[0] = -1.0;
10312     values[1] = 0.0;
10313     values[2] = 0.0;
10314     values[3] = 0.0;
10315     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10316     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10317     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10318     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10319     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10320     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10321     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10322     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10323     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10324     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10325
10326     hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10327     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10328
10329     hr = IDirect3DDevice9_BeginScene(device);
10330     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10331     if(SUCCEEDED(hr))
10332     {
10333         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10334         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10335         hr = IDirect3DDevice9_EndScene(device);
10336         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10337     }
10338     color = getPixelColor(device, 320, 240);
10339     ok(color_match(color, 0x0000ff00, 1),
10340        "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10341     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10342     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10343
10344     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10345     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10346     IDirect3DVertexShader9_Release(shader);
10347 }
10348
10349 static void sgn_test(IDirect3DDevice9 *device) {
10350     const DWORD shader_code[] = {
10351         0xfffe0200,                                                             /* vs_2_0                       */
10352         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position o0              */
10353         0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10354         0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0   */
10355         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
10356         0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002,             /* sgn r0, c0, r1, r2           */
10357         0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001,                         /* add oD0, r0, c1              */
10358         0x0000ffff                                                              /* end                          */
10359     };
10360     IDirect3DVertexShader9 *shader;
10361     HRESULT hr;
10362     DWORD color;
10363     const float quad[] = {
10364         -1.0,   -1.0,   0.1,
10365          1.0,   -1.0,   0.1,
10366         -1.0,    1.0,   0.1,
10367          1.0,    1.0,   0.1
10368     };
10369
10370     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10371     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10372     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10373     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10374     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10375     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10376     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10377     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10378
10379     hr = IDirect3DDevice9_BeginScene(device);
10380     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10381     if(SUCCEEDED(hr))
10382     {
10383         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10384         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10385         hr = IDirect3DDevice9_EndScene(device);
10386         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10387     }
10388     color = getPixelColor(device, 320, 240);
10389     ok(color_match(color, 0x008000ff, 1),
10390        "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10391     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10392     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10393
10394     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10395     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10396     IDirect3DVertexShader9_Release(shader);
10397 }
10398
10399 static void viewport_test(IDirect3DDevice9 *device) {
10400     HRESULT hr;
10401     DWORD color;
10402     D3DVIEWPORT9 vp, old_vp;
10403     BOOL draw_failed = TRUE;
10404     const float quad[] =
10405     {
10406         -0.5,   -0.5,   0.1,
10407          0.5,   -0.5,   0.1,
10408         -0.5,    0.5,   0.1,
10409          0.5,    0.5,   0.1
10410     };
10411
10412     memset(&old_vp, 0, sizeof(old_vp));
10413     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10414     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10415
10416     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10417     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10418
10419     /* Test a viewport with Width and Height bigger than the surface dimensions
10420      *
10421      * TODO: Test Width < surface.width, but X + Width > surface.width
10422      * TODO: Test Width < surface.width, what happens with the height?
10423      *
10424      * The expected behavior is that the viewport behaves like the "default"
10425      * viewport with X = Y = 0, Width = surface_width, Height = surface_height,
10426      * MinZ = 0.0, MaxZ = 1.0.
10427      *
10428      * Starting with Windows 7 the behavior among driver versions is not
10429      * consistent. The SetViewport call is accepted on all drivers. Some
10430      * drivers(older nvidia ones) refuse to draw and return an error. Newer
10431      * nvidia drivers draw, but use the actual values in the viewport and only
10432      * display the upper left part on the surface.
10433      */
10434     memset(&vp, 0, sizeof(vp));
10435     vp.X = 0;
10436     vp.Y = 0;
10437     vp.Width = 10000;
10438     vp.Height = 10000;
10439     vp.MinZ = 0.0;
10440     vp.MaxZ = 0.0;
10441     hr = IDirect3DDevice9_SetViewport(device, &vp);
10442     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10443
10444     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10445     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10446     hr = IDirect3DDevice9_BeginScene(device);
10447     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10448     if(SUCCEEDED(hr))
10449     {
10450         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10451         ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "DrawPrimitiveUP failed (%08x)\n", hr);
10452         draw_failed = FAILED(hr);
10453         hr = IDirect3DDevice9_EndScene(device);
10454         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10455     }
10456
10457     if(!draw_failed)
10458     {
10459         color = getPixelColor(device, 158, 118);
10460         ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10461         color = getPixelColor(device, 162, 118);
10462         ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10463         color = getPixelColor(device, 158, 122);
10464         ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10465         color = getPixelColor(device, 162, 122);
10466         ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (162,122) has color %08x\n", color);
10467
10468         color = getPixelColor(device, 478, 358);
10469         ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (478,358 has color %08x\n", color);
10470         color = getPixelColor(device, 482, 358);
10471         ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10472         color = getPixelColor(device, 478, 362);
10473         ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10474         color = getPixelColor(device, 482, 362);
10475         ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10476     }
10477
10478     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10479     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10480
10481     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10482     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10483 }
10484
10485 /* This test tests depth clamping / clipping behaviour:
10486  *   - With software vertex processing, depth values are clamped to the
10487  *     minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
10488  *     when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
10489  *     same as regular vertices here.
10490  *   - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
10491  *     Normal vertices are always clipped. Pretransformed vertices are
10492  *     clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
10493  *   - The viewport's MinZ/MaxZ is irrelevant for this.
10494  */
10495 static void depth_clamp_test(IDirect3DDevice9 *device)
10496 {
10497     const struct tvertex quad1[] =
10498     {
10499         {  0.0f,   0.0f,  5.0f, 1.0f, 0xff002b7f},
10500         {640.0f,   0.0f,  5.0f, 1.0f, 0xff002b7f},
10501         {  0.0f, 480.0f,  5.0f, 1.0f, 0xff002b7f},
10502         {640.0f, 480.0f,  5.0f, 1.0f, 0xff002b7f},
10503     };
10504     const struct tvertex quad2[] =
10505     {
10506         {  0.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
10507         {640.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
10508         {  0.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
10509         {640.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
10510     };
10511     const struct tvertex quad3[] =
10512     {
10513         {112.0f, 108.0f,  5.0f, 1.0f, 0xffffffff},
10514         {208.0f, 108.0f,  5.0f, 1.0f, 0xffffffff},
10515         {112.0f, 204.0f,  5.0f, 1.0f, 0xffffffff},
10516         {208.0f, 204.0f,  5.0f, 1.0f, 0xffffffff},
10517     };
10518     const struct tvertex quad4[] =
10519     {
10520         { 42.0f,  41.0f, 10.0f, 1.0f, 0xffffffff},
10521         {112.0f,  41.0f, 10.0f, 1.0f, 0xffffffff},
10522         { 42.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
10523         {112.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
10524     };
10525     const struct vertex quad5[] =
10526     {
10527         { -0.5f,   0.5f, 10.0f,       0xff14f914},
10528         {  0.5f,   0.5f, 10.0f,       0xff14f914},
10529         { -0.5f,  -0.5f, 10.0f,       0xff14f914},
10530         {  0.5f,  -0.5f, 10.0f,       0xff14f914},
10531     };
10532     const struct vertex quad6[] =
10533     {
10534         { -1.0f,   0.5f, 10.0f,      0xfff91414},
10535         {  1.0f,   0.5f, 10.0f,      0xfff91414},
10536         { -1.0f,  0.25f, 10.0f,      0xfff91414},
10537         {  1.0f,  0.25f, 10.0f,      0xfff91414},
10538     };
10539
10540     D3DVIEWPORT9 vp;
10541     D3DCOLOR color;
10542     D3DCAPS9 caps;
10543     HRESULT hr;
10544
10545     vp.X = 0;
10546     vp.Y = 0;
10547     vp.Width = 640;
10548     vp.Height = 480;
10549     vp.MinZ = 0.0;
10550     vp.MaxZ = 7.5;
10551
10552     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10553     ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
10554
10555     hr = IDirect3DDevice9_SetViewport(device, &vp);
10556     if(FAILED(hr))
10557     {
10558         /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
10559          * the tests because the 7.5 is just intended to show that it doesn't have
10560          * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
10561          * viewport and continue.
10562          */
10563         ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
10564         vp.MaxZ = 1.0;
10565         hr = IDirect3DDevice9_SetViewport(device, &vp);
10566     }
10567     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10568
10569     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
10570     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10571
10572     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10573     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10574     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10575     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10576     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10577     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10578     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10579     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10580
10581     hr = IDirect3DDevice9_BeginScene(device);
10582     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10583
10584     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10585     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10586
10587     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10588     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10589     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10590     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10591
10592     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10593     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10594
10595     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10596     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10597     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
10598     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10599
10600     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10601     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10602
10603     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10604     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10605
10606     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
10607     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10608
10609     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10610     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10611
10612     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
10613     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10614
10615     hr = IDirect3DDevice9_EndScene(device);
10616     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10617
10618     if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
10619     {
10620         color = getPixelColor(device, 75, 75);
10621         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10622         color = getPixelColor(device, 150, 150);
10623         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10624         color = getPixelColor(device, 320, 240);
10625         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10626         color = getPixelColor(device, 320, 330);
10627         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10628         color = getPixelColor(device, 320, 330);
10629         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10630     }
10631     else
10632     {
10633         color = getPixelColor(device, 75, 75);
10634         ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10635         color = getPixelColor(device, 150, 150);
10636         ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10637         color = getPixelColor(device, 320, 240);
10638         ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10639         color = getPixelColor(device, 320, 330);
10640         ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10641         color = getPixelColor(device, 320, 330);
10642         ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10643     }
10644
10645     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10646     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10647
10648     vp.MinZ = 0.0;
10649     vp.MaxZ = 1.0;
10650     hr = IDirect3DDevice9_SetViewport(device, &vp);
10651     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10652 }
10653
10654 static void depth_bounds_test(IDirect3DDevice9 *device)
10655 {
10656     const struct tvertex quad1[] =
10657     {
10658         {    0,    0, 0.0f, 1, 0xfff9e814},
10659         {  640,    0, 0.0f, 1, 0xfff9e814},
10660         {    0,  480, 1.0f, 1, 0xfff9e814},
10661         {  640,  480, 1.0f, 1, 0xfff9e814},
10662     };
10663     const struct tvertex quad2[] =
10664     {
10665         {    0,    0,  0.6f, 1, 0xff002b7f},
10666         {  640,    0,  0.6f, 1, 0xff002b7f},
10667         {    0,  480,  0.6f, 1, 0xff002b7f},
10668         {  640,  480,  0.6f, 1, 0xff002b7f},
10669     };
10670     const struct tvertex quad3[] =
10671     {
10672         {    0,  100, 0.6f, 1, 0xfff91414},
10673         {  640,  100, 0.6f, 1, 0xfff91414},
10674         {    0,  160, 0.6f, 1, 0xfff91414},
10675         {  640,  160, 0.6f, 1, 0xfff91414},
10676     };
10677
10678     union {
10679         DWORD d;
10680         float f;
10681     } tmpvalue;
10682
10683     IDirect3D9 *d3d = NULL;
10684     IDirect3DSurface9 *offscreen_surface = NULL;
10685     D3DCOLOR color;
10686     HRESULT hr;
10687
10688     IDirect3DDevice9_GetDirect3D(device, &d3d);
10689     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
10690             0,  D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK) {
10691         skip("No NVDB (depth bounds test) support\n");
10692         IDirect3D9_Release(d3d);
10693         return;
10694     }
10695     IDirect3D9_Release(d3d);
10696
10697     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
10698             MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
10699     ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
10700     if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
10701
10702     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
10703     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10704
10705     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10706     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10707     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
10708     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10709     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10710     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10711     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
10712     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10713
10714
10715     hr = IDirect3DDevice9_BeginScene(device);
10716     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10717
10718     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10719     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10720
10721     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10722     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10723
10724     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
10725     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10726
10727     tmpvalue.f = 0.625;
10728     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
10729     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10730
10731     tmpvalue.f = 0.75;
10732     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
10733     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10734
10735     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10736     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10737
10738     tmpvalue.f = 0.75;
10739     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
10740     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10741
10742     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10743     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10744
10745     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
10746     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10747
10748     hr = IDirect3DDevice9_EndScene(device);
10749     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10750
10751     color = getPixelColor(device, 150, 130);
10752     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10753     color = getPixelColor(device, 150, 200);
10754     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10755     color = getPixelColor(device, 150, 300-5);
10756     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10757     color = getPixelColor(device, 150, 300+5);
10758     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
10759     color = getPixelColor(device, 150, 330);
10760     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10761     color = getPixelColor(device, 150, 360-5);
10762     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
10763     color = getPixelColor(device, 150, 360+5);
10764     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10765
10766     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10767     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10768 }
10769
10770 static void depth_buffer_test(IDirect3DDevice9 *device)
10771 {
10772     static const struct vertex quad1[] =
10773     {
10774         { -1.0,  1.0, 0.33f, 0xff00ff00},
10775         {  1.0,  1.0, 0.33f, 0xff00ff00},
10776         { -1.0, -1.0, 0.33f, 0xff00ff00},
10777         {  1.0, -1.0, 0.33f, 0xff00ff00},
10778     };
10779     static const struct vertex quad2[] =
10780     {
10781         { -1.0,  1.0, 0.50f, 0xffff00ff},
10782         {  1.0,  1.0, 0.50f, 0xffff00ff},
10783         { -1.0, -1.0, 0.50f, 0xffff00ff},
10784         {  1.0, -1.0, 0.50f, 0xffff00ff},
10785     };
10786     static const struct vertex quad3[] =
10787     {
10788         { -1.0,  1.0, 0.66f, 0xffff0000},
10789         {  1.0,  1.0, 0.66f, 0xffff0000},
10790         { -1.0, -1.0, 0.66f, 0xffff0000},
10791         {  1.0, -1.0, 0.66f, 0xffff0000},
10792     };
10793     static const DWORD expected_colors[4][4] =
10794     {
10795         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10796         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10797         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
10798         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
10799     };
10800
10801     IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
10802     unsigned int i, j;
10803     D3DVIEWPORT9 vp;
10804     D3DCOLOR color;
10805     HRESULT hr;
10806
10807     vp.X = 0;
10808     vp.Y = 0;
10809     vp.Width = 640;
10810     vp.Height = 480;
10811     vp.MinZ = 0.0;
10812     vp.MaxZ = 1.0;
10813
10814     hr = IDirect3DDevice9_SetViewport(device, &vp);
10815     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10816
10817     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10818     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10819     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10820     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10821     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10822     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10823     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10824     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10825     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10826     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10827
10828     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
10829     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10830     hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
10831             D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
10832     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10833     hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
10834             D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
10835     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10836     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
10837             D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
10838     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10839
10840     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
10841     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10842     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
10843     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10844
10845     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10846     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10847     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10848     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10849
10850     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
10851     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10852     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
10853     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10854
10855     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
10856     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10857     hr = IDirect3DDevice9_BeginScene(device);
10858     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10859     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10860     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10861     hr = IDirect3DDevice9_EndScene(device);
10862     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10863
10864     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10865     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10866     IDirect3DSurface9_Release(backbuffer);
10867     IDirect3DSurface9_Release(rt3);
10868     IDirect3DSurface9_Release(rt2);
10869     IDirect3DSurface9_Release(rt1);
10870
10871     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
10872     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10873
10874     hr = IDirect3DDevice9_BeginScene(device);
10875     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10876     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10877     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10878     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10879     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10880     hr = IDirect3DDevice9_EndScene(device);
10881     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10882
10883     for (i = 0; i < 4; ++i)
10884     {
10885         for (j = 0; j < 4; ++j)
10886         {
10887             unsigned int x = 80 * ((2 * j) + 1);
10888             unsigned int y = 60 * ((2 * i) + 1);
10889             color = getPixelColor(device, x, y);
10890             ok(color_match(color, expected_colors[i][j], 0),
10891                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
10892         }
10893     }
10894
10895     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10896     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10897 }
10898
10899 /* Test that partial depth copies work the way they're supposed to. The clear
10900  * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
10901  * the following draw should only copy back the part that was modified. */
10902 static void depth_buffer2_test(IDirect3DDevice9 *device)
10903 {
10904     static const struct vertex quad[] =
10905     {
10906         { -1.0,  1.0, 0.66f, 0xffff0000},
10907         {  1.0,  1.0, 0.66f, 0xffff0000},
10908         { -1.0, -1.0, 0.66f, 0xffff0000},
10909         {  1.0, -1.0, 0.66f, 0xffff0000},
10910     };
10911
10912     IDirect3DSurface9 *backbuffer, *rt1, *rt2;
10913     unsigned int i, j;
10914     D3DVIEWPORT9 vp;
10915     D3DCOLOR color;
10916     HRESULT hr;
10917
10918     vp.X = 0;
10919     vp.Y = 0;
10920     vp.Width = 640;
10921     vp.Height = 480;
10922     vp.MinZ = 0.0;
10923     vp.MaxZ = 1.0;
10924
10925     hr = IDirect3DDevice9_SetViewport(device, &vp);
10926     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10927
10928     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10929     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10930     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10931     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10932     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10933     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10934     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10935     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10936     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10937     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10938
10939     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
10940             D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
10941     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10942     hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
10943             D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
10944     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10945     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
10946     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10947
10948     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
10949     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10950     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10951     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10952
10953     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10954     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10955     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
10956     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10957
10958     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
10959     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10960     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
10961     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10962
10963     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10964     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10965     IDirect3DSurface9_Release(backbuffer);
10966     IDirect3DSurface9_Release(rt2);
10967     IDirect3DSurface9_Release(rt1);
10968
10969     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
10970     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10971
10972     hr = IDirect3DDevice9_BeginScene(device);
10973     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10974     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10975     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10976     hr = IDirect3DDevice9_EndScene(device);
10977     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10978
10979     for (i = 0; i < 4; ++i)
10980     {
10981         for (j = 0; j < 4; ++j)
10982         {
10983             unsigned int x = 80 * ((2 * j) + 1);
10984             unsigned int y = 60 * ((2 * i) + 1);
10985             color = getPixelColor(device, x, y);
10986             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
10987                     "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
10988         }
10989     }
10990
10991     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10992     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10993 }
10994
10995 static void depth_blit_test(IDirect3DDevice9 *device)
10996 {
10997     static const struct vertex quad1[] =
10998     {
10999         { -1.0,  1.0, 0.50f, 0xff00ff00},
11000         {  1.0,  1.0, 0.50f, 0xff00ff00},
11001         { -1.0, -1.0, 0.50f, 0xff00ff00},
11002         {  1.0, -1.0, 0.50f, 0xff00ff00},
11003     };
11004     static const struct vertex quad2[] =
11005     {
11006         { -1.0,  1.0, 0.66f, 0xff0000ff},
11007         {  1.0,  1.0, 0.66f, 0xff0000ff},
11008         { -1.0, -1.0, 0.66f, 0xff0000ff},
11009         {  1.0, -1.0, 0.66f, 0xff0000ff},
11010     };
11011     static const DWORD expected_colors[4][4] =
11012     {
11013         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11014         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11015         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
11016         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
11017     };
11018
11019     IDirect3DSurface9 *backbuffer, *ds1, *ds2;
11020     RECT src_rect, dst_rect;
11021     unsigned int i, j;
11022     D3DVIEWPORT9 vp;
11023     D3DCOLOR color;
11024     HRESULT hr;
11025
11026     vp.X = 0;
11027     vp.Y = 0;
11028     vp.Width = 640;
11029     vp.Height = 480;
11030     vp.MinZ = 0.0;
11031     vp.MaxZ = 1.0;
11032
11033     hr = IDirect3DDevice9_SetViewport(device, &vp);
11034     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11035
11036     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11037     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11038     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
11039     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11040     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
11041     ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
11042     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
11043     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11044
11045     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11046     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11047     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11048     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11049     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11050     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11051     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11052     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11053
11054     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11055     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11056     SetRect(&dst_rect, 0, 0, 480, 360);
11057     hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
11058     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11059     SetRect(&dst_rect, 0, 0, 320, 240);
11060     hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
11061     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11062
11063     /* Partial blit. */
11064     SetRect(&src_rect, 0, 0, 320, 240);
11065     SetRect(&dst_rect, 0, 0, 320, 240);
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     /* Flipped. */
11069     SetRect(&src_rect, 0, 0, 640, 480);
11070     SetRect(&dst_rect, 0, 480, 640, 0);
11071     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11072     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11073     /* Full, explicit. */
11074     SetRect(&src_rect, 0, 0, 640, 480);
11075     SetRect(&dst_rect, 0, 0, 640, 480);
11076     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11077     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11078     /* Filtered blit. */
11079     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
11080     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11081     /* Depth -> color blit.*/
11082     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
11083     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11084     IDirect3DSurface9_Release(backbuffer);
11085
11086     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
11087     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11088     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
11089     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11090     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
11091     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11092     IDirect3DSurface9_Release(ds2);
11093     IDirect3DSurface9_Release(ds1);
11094
11095     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11096     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11097     hr = IDirect3DDevice9_BeginScene(device);
11098     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11099     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11100     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11101     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11102     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11103     hr = IDirect3DDevice9_EndScene(device);
11104     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11105
11106     for (i = 0; i < 4; ++i)
11107     {
11108         for (j = 0; j < 4; ++j)
11109         {
11110             unsigned int x = 80 * ((2 * j) + 1);
11111             unsigned int y = 60 * ((2 * i) + 1);
11112             color = getPixelColor(device, x, y);
11113             ok(color_match(color, expected_colors[i][j], 0),
11114                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11115         }
11116     }
11117
11118     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11119     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11120 }
11121
11122 static void intz_test(IDirect3DDevice9 *device)
11123 {
11124     static const DWORD ps_code[] =
11125     {
11126         0xffff0200,                                                             /* ps_2_0                       */
11127         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
11128         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
11129         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
11130         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
11131         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
11132         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
11133         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
11134         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
11135         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov oC0, r1                  */
11136         0x0000ffff,                                                             /* end                          */
11137     };
11138     struct
11139     {
11140         float x, y, z;
11141         float s, t, p, q;
11142     }
11143     quad[] =
11144     {
11145         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11146         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11147         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11148         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11149     };
11150     struct
11151     {
11152         UINT x, y;
11153         D3DCOLOR color;
11154     }
11155     expected_colors[] =
11156     {
11157         { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11158         {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11159         {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11160         {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11161         { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11162         {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11163         {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11164         {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11165     };
11166
11167     IDirect3DSurface9 *original_ds, *original_rt, *rt;
11168     IDirect3DTexture9 *texture;
11169     IDirect3DPixelShader9 *ps;
11170     IDirect3DSurface9 *ds;
11171     IDirect3D9 *d3d9;
11172     D3DCAPS9 caps;
11173     HRESULT hr;
11174     UINT i;
11175
11176     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11177     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11178     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11179     {
11180         skip("No pixel shader 2.0 support, skipping INTZ test.\n");
11181         return;
11182     }
11183
11184     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11185     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11186
11187     hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11188             D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
11189     if (FAILED(hr))
11190     {
11191         skip("No INTZ support, skipping INTZ test.\n");
11192         return;
11193     }
11194
11195     IDirect3D9_Release(d3d9);
11196
11197     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11198     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11199     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11200     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11201
11202     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
11203             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11204     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11205     hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
11206             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11207     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11208     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11209     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11210
11211     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11212     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11213     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11214     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11215     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11216     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11217     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11218     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11219     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11220     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11221
11222     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11223     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11224     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11225     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11226     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11227     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11228     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11229     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11230     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11231     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11232
11233     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11234     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11235     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11236     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11237     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11238     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11239     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11240     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11241
11242     /* Setup the depth/stencil surface. */
11243     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11244     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11245
11246     hr = IDirect3DDevice9_BeginScene(device);
11247     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11248     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11249     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11250     hr = IDirect3DDevice9_EndScene(device);
11251     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11252
11253     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11254     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11255     IDirect3DSurface9_Release(ds);
11256     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11257     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11258     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11259     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11260     hr = IDirect3DDevice9_SetPixelShader(device, ps);
11261     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11262
11263     /* Read the depth values back. */
11264     hr = IDirect3DDevice9_BeginScene(device);
11265     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11266     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11267     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11268     hr = IDirect3DDevice9_EndScene(device);
11269     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11270
11271     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11272     {
11273         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11274         ok(color_match(color, expected_colors[i].color, 1),
11275                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11276                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11277     }
11278
11279     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11280     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11281
11282     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11283     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11284     IDirect3DSurface9_Release(original_ds);
11285     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11286     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11287     IDirect3DTexture9_Release(texture);
11288     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11289     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11290     IDirect3DPixelShader9_Release(ps);
11291
11292     IDirect3DSurface9_Release(original_rt);
11293     IDirect3DSurface9_Release(rt);
11294 }
11295
11296 static void shadow_test(IDirect3DDevice9 *device)
11297 {
11298     static const DWORD ps_code[] =
11299     {
11300         0xffff0200,                                                             /* ps_2_0                       */
11301         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
11302         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
11303         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
11304         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
11305         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
11306         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
11307         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
11308         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
11309         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov 0C0, r1                  */
11310         0x0000ffff,                                                             /* end                          */
11311     };
11312     struct
11313     {
11314         D3DFORMAT format;
11315         const char *name;
11316     }
11317     formats[] =
11318     {
11319         {D3DFMT_D16_LOCKABLE,   "D3DFMT_D16_LOCKABLE"},
11320         {D3DFMT_D32,            "D3DFMT_D32"},
11321         {D3DFMT_D15S1,          "D3DFMT_D15S1"},
11322         {D3DFMT_D24S8,          "D3DFMT_D24S8"},
11323         {D3DFMT_D24X8,          "D3DFMT_D24X8"},
11324         {D3DFMT_D24X4S4,        "D3DFMT_D24X4S4"},
11325         {D3DFMT_D16,            "D3DFMT_D16"},
11326         {D3DFMT_D32F_LOCKABLE,  "D3DFMT_D32F_LOCKABLE"},
11327         {D3DFMT_D24FS8,         "D3DFMT_D24FS8"},
11328     };
11329     struct
11330     {
11331         float x, y, z;
11332         float s, t, p, q;
11333     }
11334     quad[] =
11335     {
11336         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
11337         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
11338         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
11339         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
11340     };
11341     struct
11342     {
11343         UINT x, y;
11344         D3DCOLOR color;
11345     }
11346     expected_colors[] =
11347     {
11348         {400,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11349         {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11350         {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11351         {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11352         {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11353         { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11354         { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11355         {240,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11356     };
11357
11358     IDirect3DSurface9 *original_ds, *original_rt, *rt;
11359     IDirect3DPixelShader9 *ps;
11360     IDirect3D9 *d3d9;
11361     D3DCAPS9 caps;
11362     HRESULT hr;
11363     UINT i;
11364
11365     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11366     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11367     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11368     {
11369         skip("No pixel shader 2.0 support, skipping shadow test.\n");
11370         return;
11371     }
11372
11373     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11374     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11375     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11376     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11377     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11378     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11379
11380     hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
11381             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11382     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11383     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11384     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11385
11386     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11387     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11388     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11389     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11390     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11391     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11392     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11393     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11394     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11395     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11396
11397     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11398     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11399     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11400     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11401     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11402     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11403     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11404     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11405     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11406     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11407
11408     for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
11409     {
11410         D3DFORMAT format = formats[i].format;
11411         IDirect3DTexture9 *texture;
11412         IDirect3DSurface9 *ds;
11413         unsigned int j;
11414
11415         hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11416                 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
11417         if (FAILED(hr)) continue;
11418
11419         hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
11420                 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
11421         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11422
11423         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11424         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11425
11426         hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11427         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11428
11429         hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11430         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11431
11432         IDirect3DDevice9_SetPixelShader(device, NULL);
11433         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11434
11435         /* Setup the depth/stencil surface. */
11436         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11437         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11438
11439         hr = IDirect3DDevice9_BeginScene(device);
11440         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11441         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11442         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11443         hr = IDirect3DDevice9_EndScene(device);
11444         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11445
11446         hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11447         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11448         IDirect3DSurface9_Release(ds);
11449
11450         hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11451         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11452
11453         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11454         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11455
11456         hr = IDirect3DDevice9_SetPixelShader(device, ps);
11457         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11458
11459         /* Do the actual shadow mapping. */
11460         hr = IDirect3DDevice9_BeginScene(device);
11461         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11462         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11463         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11464         hr = IDirect3DDevice9_EndScene(device);
11465         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11466
11467         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11468         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11469         IDirect3DTexture9_Release(texture);
11470
11471         for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
11472         {
11473             D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
11474             ok(color_match(color, expected_colors[j].color, 0),
11475                     "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
11476                     expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
11477                     formats[i].name, color);
11478         }
11479
11480         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11481         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11482     }
11483
11484     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11485     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11486     IDirect3DPixelShader9_Release(ps);
11487
11488     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11489     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11490     IDirect3DSurface9_Release(original_ds);
11491
11492     IDirect3DSurface9_Release(original_rt);
11493     IDirect3DSurface9_Release(rt);
11494
11495     IDirect3D9_Release(d3d9);
11496 }
11497
11498 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
11499 {
11500     const struct vertex quad1[] =
11501     {
11502         {-1.0f, -1.0f, 0.0f, 0xfff9e814},
11503         { 1.0f, -1.0f, 0.0f, 0xfff9e814},
11504         {-1.0f,  1.0f, 0.0f, 0xfff9e814},
11505         { 1.0f,  1.0f, 0.0f, 0xfff9e814},
11506     };
11507     const struct vertex quad2[] =
11508     {
11509         {-1.0f, -1.0f, 0.0f, 0xff002b7f},
11510         { 1.0f, -1.0f, 0.0f, 0xff002b7f},
11511         {-1.0f,  1.0f, 0.0f, 0xff002b7f},
11512         { 1.0f,  1.0f, 0.0f, 0xff002b7f},
11513     };
11514     D3DCOLOR color;
11515     HRESULT hr;
11516
11517     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
11518     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11519
11520     hr = IDirect3DDevice9_BeginScene(device);
11521     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11522
11523     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11524     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11525
11526     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
11527     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11528     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11529     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11530
11531     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
11532     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11533     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11534     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11535
11536     hr = IDirect3DDevice9_EndScene(device);
11537     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11538
11539     color = getPixelColor(device, 1, 240);
11540     ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
11541     color = getPixelColor(device, 638, 240);
11542     ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
11543
11544     color = getPixelColor(device, 1, 241);
11545     ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
11546     color = getPixelColor(device, 638, 241);
11547     ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
11548 }
11549
11550 static void clip_planes_test(IDirect3DDevice9 *device)
11551 {
11552     const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
11553
11554     const DWORD shader_code[] = {
11555         0xfffe0200, /* vs_2_0 */
11556         0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11557         0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
11558         0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
11559         0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
11560         0x0000ffff /* end */
11561     };
11562     IDirect3DVertexShader9 *shader;
11563
11564     IDirect3DTexture9 *offscreen = NULL;
11565     IDirect3DSurface9 *offscreen_surface, *original_rt;
11566     HRESULT hr;
11567
11568     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11569     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11570
11571     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11572     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11573     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
11574     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11575     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11576     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11577     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
11578     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11579
11580     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11581     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
11582     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11583     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
11584
11585     IDirect3DDevice9_SetClipPlane(device, 0, plane0);
11586
11587     clip_planes(device, "Onscreen FFP");
11588
11589     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
11590     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11591     hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
11592     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11593     hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
11594     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11595
11596     clip_planes(device, "Offscreen FFP");
11597
11598     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11599     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11600
11601     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
11602     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
11603     IDirect3DDevice9_SetVertexShader(device, shader);
11604     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
11605
11606     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11607     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11608
11609     clip_planes(device, "Onscreen vertex shader");
11610
11611     hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
11612     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11613
11614     clip_planes(device, "Offscreen vertex shader");
11615
11616     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11617     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11618
11619     IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
11620     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11621     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
11622     IDirect3DVertexShader9_Release(shader);
11623     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11624     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11625     IDirect3DSurface9_Release(original_rt);
11626     IDirect3DSurface9_Release(offscreen_surface);
11627     IDirect3DTexture9_Release(offscreen);
11628 }
11629
11630 static void fp_special_test(IDirect3DDevice9 *device)
11631 {
11632     static const DWORD vs_header[] =
11633     {
11634         0xfffe0200,                                                             /* vs_2_0                       */
11635         0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0   */
11636         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
11637         0x0200001f, 0x80000005, 0x900f0001,                                     /* dcl_texcoord0 v1             */
11638     };
11639
11640     static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001};         /* log r0.x, v1.x               */
11641     static const DWORD vs_pow[] =
11642             {0x03000020, 0x80010000, 0x90000001, 0x90000001};                   /* pow r0.x, v1.x, v1.x         */
11643     static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001};         /* nrm r0.xyz, v1.x             */
11644     static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001};        /* rcp r0.x, v1.x               */
11645     static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001};        /* rcp r0.x, -v1.x              */
11646     static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001};        /* rsq r0.x, v1.x               */
11647     static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001};        /* rsq r0.x, -v1.x              */
11648
11649     static const DWORD vs_footer[] =
11650     {
11651         0x03000005, 0x80020000, 0x80000000, 0xa0ff0000,                         /* mul r0.y, r0.x, c0.w         */
11652         0x0300000d, 0x80040000, 0x80000000, 0x80550000,                         /* sge r0.z, r0.x, r0.y         */
11653         0x0300000d, 0x80020000, 0x80e40000, 0x80000000,                         /* sge r0.y, r0, r0.x           */
11654         0x03000005, 0x80040000, 0x80550000, 0x80e40000,                         /* mul r0.z, r0.y, r0           */
11655         0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000,                         /* max r0.w, -r0.z, r0.z        */
11656         0x0300000c, 0x80020000, 0x80000000, 0x80000000,                         /* slt r0.y, r0.x, r0.x         */
11657         0x03000002, 0x80040000, 0x80550000, 0x80550000,                         /* add r0.z, r0.y, r0.y         */
11658         0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000,                         /* slt r0.y, c0.x, r0.w         */
11659         0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000,                         /* max r0.w, -r0.z, r0.z        */
11660         0x03000002, 0x80040000, 0x81550000, 0xa0e40000,                         /* add r0.z, -r0.y, c0          */
11661         0x0300000c, 0x80080000, 0xa0000000, 0x80e40000,                         /* slt r0.w, c0.x, r0           */
11662         0x03000005, 0x80040000, 0x80ff0000, 0x80e40000,                         /* mul r0.z, r0.w, r0           */
11663         0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000,             /* mad r0.y, r0.z, c0, r0       */
11664         0x02000001, 0xe0030000, 0x80e40000,                                     /* mov oT0.xy, r0               */
11665         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
11666         0x0000ffff,                                                             /* end                          */
11667     };
11668
11669     static const struct
11670     {
11671         const char *name;
11672         const DWORD *ops;
11673         DWORD size;
11674         D3DCOLOR r600;
11675         D3DCOLOR nv40;
11676         D3DCOLOR nv50;
11677     }
11678     vs_body[] =
11679     {
11680         /* The basic ideas here are:
11681          *     2.0 * +/-INF == +/-INF
11682          *     NAN != NAN
11683          *
11684          * The vertex shader value is written to the red component, with 0.0
11685          * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
11686          * result in 0x00. The pixel shader value is written to the green
11687          * component, but here 0.0 also results in 0x00. The actual value is
11688          * written to the blue component.
11689          *
11690          * There are considerable differences between graphics cards in how
11691          * these are handled, but pow and nrm never generate INF or NAN. */
11692         {"log",     vs_log,     sizeof(vs_log),     0x00000000, 0x00ff0000, 0x00ff7f00},
11693         {"pow",     vs_pow,     sizeof(vs_pow),     0x000000ff, 0x0000ff00, 0x000000ff},
11694         {"nrm",     vs_nrm,     sizeof(vs_nrm),     0x00ff0000, 0x0000ff00, 0x00ff0000},
11695         {"rcp1",    vs_rcp1,    sizeof(vs_rcp1),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
11696         {"rcp2",    vs_rcp2,    sizeof(vs_rcp2),    0x00000000, 0x00ff0000, 0x00ff7f00},
11697         {"rsq1",    vs_rsq1,    sizeof(vs_rsq1),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
11698         {"rsq2",    vs_rsq2,    sizeof(vs_rsq2),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
11699     };
11700
11701     static const DWORD ps_code[] =
11702     {
11703         0xffff0200,                                                             /* ps_2_0                       */
11704         0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0   */
11705         0x0200001f, 0x80000000, 0xb0030000,                                     /* dcl t0.xy                    */
11706         0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000,                         /* max r1.x, t0, c0             */
11707         0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000,                         /* min r0.x, t0, c0             */
11708         0x03000002, 0x80010000, 0x80e40000, 0x81e40001,                         /* add r0.x, r0, -r1            */
11709         0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000,             /* mad r1.x, t0, c0.w. -t0      */
11710         0x02000023, 0x80010002, 0x80e40001,                                     /* abs r2.x, r1                 */
11711         0x02000023, 0x80010000, 0x80e40000,                                     /* abs r0.x, r0                 */
11712         0x02000023, 0x80010001, 0xb0e40000,                                     /* abs r1.x, t0                 */
11713         0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000,             /* cmp r2.x, -r2, c0.z, c0      */
11714         0x02000023, 0x80010002, 0x80e40002,                                     /* abs r2.x, r2                 */
11715         0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000,             /* cmp r1.x, -r1, c0.z, c0      */
11716         0x02000023, 0x80010001, 0x80e40001,                                     /* abs r1.x, r1                 */
11717         0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000,             /* cmp r3.x, -r2, c0.z, c0      */
11718         0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000,             /* cmp r2.x, -r1, c0.z, c0      */
11719         0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000,             /* cmp r0.x, -r0, c0.y, c0      */
11720         0x03000005, 0x80010002, 0x80e40002, 0x80e40003,                         /* mul r2.x, r2, r3             */
11721         0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000,             /* cmp r0.x, -r2, c0.z, r0      */
11722         0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000,             /* cmp r0.y, -r1.x, r0.x, c0.x  */
11723         0x02000001, 0x80050000, 0xb0c90000,                                     /* mov r0.xz, t0.yzxw           */
11724         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.w, c0.z               */
11725         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
11726         0x0000ffff,                                                             /* end                          */
11727     };
11728
11729     struct
11730     {
11731         float x, y, z;
11732         float s;
11733     }
11734     quad[] =
11735     {
11736         { -1.0f,  1.0f, 0.0f, 0.0f},
11737         {  1.0f,  1.0f, 1.0f, 0.0f},
11738         { -1.0f, -1.0f, 0.0f, 0.0f},
11739         {  1.0f, -1.0f, 1.0f, 0.0f},
11740     };
11741
11742     IDirect3DPixelShader9 *ps;
11743     UINT body_size = 0;
11744     DWORD *vs_code;
11745     D3DCAPS9 caps;
11746     HRESULT hr;
11747     UINT i;
11748
11749     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11750     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11751     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
11752     {
11753         skip("No shader model 2.0 support, skipping floating point specials test.\n");
11754         return;
11755     }
11756
11757     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
11758     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11759
11760     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11761     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11762     IDirect3DDevice9_SetPixelShader(device, ps);
11763     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11764
11765     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
11766     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11767
11768     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
11769     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11770
11771     for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
11772     {
11773         if (vs_body[i].size > body_size) body_size = vs_body[i].size;
11774     }
11775
11776     vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
11777     memcpy(vs_code, vs_header, sizeof(vs_header));
11778
11779     for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
11780     {
11781         DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
11782         IDirect3DVertexShader9 *vs;
11783         D3DCOLOR color;
11784
11785         memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
11786         offset += vs_body[i].size / sizeof(*vs_body[i].ops);
11787         memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
11788
11789         hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
11790         ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
11791         IDirect3DDevice9_SetVertexShader(device, vs);
11792         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
11793
11794         hr = IDirect3DDevice9_BeginScene(device);
11795         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11796         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11797         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11798         hr = IDirect3DDevice9_EndScene(device);
11799         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11800
11801         color = getPixelColor(device, 320, 240);
11802         ok(color_match(color, vs_body[i].r600, 1)
11803                 || color_match(color, vs_body[i].nv40, 1)
11804                 || color_match(color, vs_body[i].nv50, 1),
11805                 "Expected color 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
11806                 vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
11807
11808         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11809         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11810
11811         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11812         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
11813         IDirect3DVertexShader9_Release(vs);
11814     }
11815
11816     HeapFree(GetProcessHeap(), 0, vs_code);
11817
11818     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11819     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11820     IDirect3DPixelShader9_Release(ps);
11821 }
11822
11823 static void srgbwrite_format_test(IDirect3DDevice9 *device)
11824 {
11825     IDirect3D9 *d3d;
11826     IDirect3DSurface9 *rt, *backbuffer;
11827     IDirect3DTexture9 *texture;
11828     HRESULT hr;
11829     int i;
11830     DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
11831     static const struct
11832     {
11833         D3DFORMAT fmt;
11834         const char *name;
11835     }
11836     formats[] =
11837     {
11838         { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
11839         { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
11840         { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
11841         { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
11842         { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
11843     };
11844     static const struct
11845     {
11846         float x, y, z;
11847         float u, v;
11848     }
11849     quad[] =
11850     {
11851         {-1.0f,  -1.0f,  0.1f,   0.0f,   0.0f},
11852         {-1.0f,   1.0f,  0.1f,   1.0f,   0.0f},
11853         { 1.0f,  -1.0f,  0.1f,   0.0f,   1.0f},
11854         { 1.0f,   1.0f,  0.1f,   1.0f,   1.0f}
11855     };
11856
11857     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
11858     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11859     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11860     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11861     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
11862     ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
11863     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11864     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
11865     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
11866     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11867
11868     for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
11869     {
11870         if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11871                 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
11872         {
11873             skip("Format %s not supported as render target, skipping test.\n",
11874                     formats[i].name);
11875             continue;
11876         }
11877
11878         hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET, formats[i].fmt,
11879                                             D3DPOOL_DEFAULT, &texture, NULL);
11880         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11881         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
11882         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11883
11884         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
11885         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11886         hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11887         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11888         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
11889         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11890
11891         hr = IDirect3DDevice9_BeginScene(device);
11892         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11893         if(SUCCEEDED(hr))
11894         {
11895             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
11896             ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11897             hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
11898             ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
11899             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11900             ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
11901
11902             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
11903             ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11904             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11905             ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11906             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
11907             ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11908             hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
11909             ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
11910             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11911             ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
11912             hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11913             ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11914
11915             hr = IDirect3DDevice9_EndScene(device);
11916             ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11917         }
11918
11919         IDirect3DSurface9_Release(rt);
11920         IDirect3DTexture9_Release(texture);
11921
11922         color = getPixelColor(device, 360, 240);
11923         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11924                                     D3DUSAGE_QUERY_SRGBWRITE,
11925                                     D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
11926         {
11927             /* Big slop for R5G6B5 */
11928             ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
11929                 formats[i].name, color_srgb, color);
11930         }
11931         else
11932         {
11933             /* Big slop for R5G6B5 */
11934             ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
11935                 formats[i].name, color_rgb, color);
11936         }
11937
11938         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11939         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11940     }
11941
11942     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
11943     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
11944
11945     IDirect3D9_Release(d3d);
11946     IDirect3DSurface9_Release(backbuffer);
11947 }
11948
11949 static void ds_size_test(IDirect3DDevice9 *device)
11950 {
11951     IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
11952     HRESULT hr;
11953     DWORD color;
11954     DWORD num_passes;
11955     struct
11956     {
11957         float x, y, z;
11958     }
11959     quad[] =
11960     {
11961         {-1.0,  -1.0,   0.0 },
11962         {-1.0,   1.0,   0.0 },
11963         { 1.0,  -1.0,   0.0 },
11964         { 1.0,   1.0,   0.0 }
11965     };
11966
11967     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11968     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
11969     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
11970     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#x.\n", hr);
11971     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
11972     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
11973
11974     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
11975     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
11976     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
11977     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
11978     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11979     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
11980     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
11981     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
11982     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
11983     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
11984     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
11985     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#x.\n", hr);
11986     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11987     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
11988     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11989     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
11990     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
11991     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
11992
11993     /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
11994      * but does not change the surface's contents. */
11995     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
11996     ok(SUCCEEDED(hr), "Target clear failed, hr %#x.\n", hr);
11997     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
11998     ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#x.\n", hr);
11999     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
12000     ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#x.\n", hr);
12001
12002     hr = IDirect3DDevice9_GetRenderTargetData(device, rt, readback);
12003     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTargetData failed, hr %#x.\n", hr);
12004     color = getPixelColorFromSurface(readback, 2, 2);
12005     ok(color == 0x000000FF, "DS size test: Pixel (2, 2) after clear is %#x, expected 0x000000FF\n", color);
12006     color = getPixelColorFromSurface(readback, 31, 31);
12007     ok(color == 0x000000FF, "DS size test: Pixel (31, 31) after clear is %#x, expected 0x000000FF\n", color);
12008     color = getPixelColorFromSurface(readback, 32, 32);
12009     ok(color == 0x000000FF, "DS size test: Pixel (32, 32) after clear is %#x, expected 0x000000FF\n", color);
12010     color = getPixelColorFromSurface(readback, 63, 63);
12011     ok(color == 0x000000FF, "DS size test: Pixel (63, 63) after clear is %#x, expected 0x000000FF\n", color);
12012
12013     /* Turning on any depth-related state results in a ValidateDevice failure */
12014     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12015     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12016     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12017     ok(hr == D3DERR_CONFLICTINGRENDERSTATE, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12018         "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12019     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12020     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12021     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12022     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12023     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12024     ok(hr == D3DERR_CONFLICTINGRENDERSTATE, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12025         "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12026
12027     /* Try to draw with the device in an invalid state */
12028     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12029     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12030     hr = IDirect3DDevice9_BeginScene(device);
12031     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12032     if(SUCCEEDED(hr))
12033     {
12034         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12035         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12036         hr = IDirect3DDevice9_EndScene(device);
12037         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12038     }
12039
12040     hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12041     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12042     hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
12043     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12044     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12045     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12046
12047     IDirect3DSurface9_Release(readback);
12048     IDirect3DSurface9_Release(ds);
12049     IDirect3DSurface9_Release(rt);
12050     IDirect3DSurface9_Release(old_rt);
12051     IDirect3DSurface9_Release(old_ds);
12052 }
12053
12054 static void unbound_sampler_test(IDirect3DDevice9 *device)
12055 {
12056     HRESULT hr;
12057     IDirect3DPixelShader9 *ps;
12058     IDirect3DSurface9 *rt, *old_rt;
12059     DWORD color;
12060
12061     static const DWORD ps_code[] =
12062     {
12063         0xffff0200,                                     /* ps_2_0           */
12064         0x0200001f, 0x90000000, 0xa00f0800,             /* dcl_2d s0        */
12065         0x0200001f, 0x80000000, 0xb00f0000,             /* dcl t0           */
12066         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12067         0x02000001, 0x800f0800, 0x80e40000,             /* mov oC0, r0      */
12068         0x0000ffff,                                     /* end              */
12069     };
12070
12071     static const struct
12072     {
12073         float x, y, z;
12074         float u, v;
12075     }
12076     quad[] =
12077     {
12078         {-1.0f,  -1.0f,  0.1f,   0.0f,   0.0f},
12079         {-1.0f,   1.0f,  0.1f,   1.0f,   0.0f},
12080         { 1.0f,  -1.0f,  0.1f,   0.0f,   1.0f},
12081         { 1.0f,   1.0f,  0.1f,   1.0f,   1.0f}
12082     };
12083
12084     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12085     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStage failed, %#x.\n", hr);
12086
12087     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12088     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12089
12090     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
12091     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12092
12093     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12094     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12095
12096     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12097     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12098
12099     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 );
12100     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12101
12102     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x56ffffff, 0, 0);
12103     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
12104
12105     hr = IDirect3DDevice9_SetPixelShader(device, ps);
12106     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12107
12108     hr = IDirect3DDevice9_BeginScene(device);
12109     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12110     if(SUCCEEDED(hr))
12111     {
12112         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12113         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12114
12115         hr = IDirect3DDevice9_EndScene(device);
12116         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12117     }
12118
12119     color = getPixelColorFromSurface(rt, 32, 32);
12120     ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12121
12122     hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12123     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12124
12125     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12126     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12127
12128     IDirect3DSurface9_Release(rt);
12129     IDirect3DSurface9_Release(old_rt);
12130     IDirect3DPixelShader9_Release(ps);
12131 }
12132
12133 static void update_surface_test(IDirect3DDevice9 *device)
12134 {
12135     static const BYTE blocks[][8] =
12136     {
12137         {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, /* White */
12138         {0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Red */
12139         {0xe0, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00}, /* Yellow */
12140         {0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Green */
12141         {0xff, 0x07, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Cyan */
12142         {0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Blue */
12143         {0x1f, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Magenta */
12144     };
12145     static const struct
12146     {
12147         UINT x, y;
12148         D3DCOLOR color;
12149     }
12150     expected_colors[] =
12151     {
12152         { 18, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0xff)},
12153         { 57, 240, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff)},
12154         {109, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0xff)},
12155         {184, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
12156         {290, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
12157         {440, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
12158         {584, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
12159     };
12160     static const struct
12161     {
12162         float x, y, z, w;
12163         float u, v;
12164     }
12165     tri[] =
12166     {
12167         {  0.0f, 480.0f, 0.0f,  1.0f,   0.0f, 0.0f},
12168         {  0.0f,   0.0f, 0.0f,  1.0f,   0.0f, 1.0f},
12169         {640.0f, 240.0f, 0.0f, 10.0f, 100.0f, 0.5f},
12170     };
12171     static const RECT rect_2x2 = {0, 0, 2, 2};
12172     static const struct
12173     {
12174         UINT src_level;
12175         UINT dst_level;
12176         const RECT *r;
12177         HRESULT hr;
12178     }
12179     block_size_tests[] =
12180     {
12181         {1, 0, NULL,      D3D_OK},
12182         {0, 1, NULL,      D3DERR_INVALIDCALL},
12183         {5, 4, NULL,      D3DERR_INVALIDCALL},
12184         {4, 5, NULL,      D3DERR_INVALIDCALL},
12185         {4, 5, &rect_2x2, D3DERR_INVALIDCALL},
12186         {5, 5, &rect_2x2, D3D_OK},
12187     };
12188
12189     IDirect3DSurface9 *src_surface, *dst_surface;
12190     IDirect3DTexture9 *src_tex, *dst_tex;
12191     IDirect3D9 *d3d;
12192     UINT count, i;
12193     HRESULT hr;
12194
12195     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
12196     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12197
12198     hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
12199             D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1);
12200     IDirect3D9_Release(d3d);
12201     if (FAILED(hr))
12202     {
12203         skip("DXT1 not supported, skipping test.\n");
12204         return;
12205     }
12206
12207     IDirect3D9_Release(d3d);
12208
12209     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &src_tex, NULL);
12210     ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12211     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &dst_tex, NULL);
12212     ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12213
12214     count = IDirect3DTexture9_GetLevelCount(src_tex);
12215     ok(count == 7, "Got level count %u, expected 7.\n", count);
12216
12217     for (i = 0; i < count; ++i)
12218     {
12219         UINT row_count, block_count, x, y;
12220         D3DSURFACE_DESC desc;
12221         BYTE *row, *block;
12222         D3DLOCKED_RECT r;
12223
12224         hr = IDirect3DTexture9_GetLevelDesc(src_tex, i, &desc);
12225         ok(SUCCEEDED(hr), "Failed to get level desc, hr %#x.\n", hr);
12226
12227         hr = IDirect3DTexture9_LockRect(src_tex, i, &r, NULL, 0);
12228         ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
12229
12230         row_count = ((desc.Height + 3) & ~3) / 4;
12231         block_count = ((desc.Width + 3) & ~3) / 4;
12232         row = r.pBits;
12233
12234         for (y = 0; y < row_count; ++y)
12235         {
12236             block = row;
12237             for (x = 0; x < block_count; ++x)
12238             {
12239                 memcpy(block, blocks[i], sizeof(blocks[i]));
12240                 block += sizeof(blocks[i]);
12241             }
12242             row += r.Pitch;
12243         }
12244
12245         hr = IDirect3DTexture9_UnlockRect(src_tex, i);
12246         ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
12247     }
12248
12249     for (i = 0; i < sizeof(block_size_tests) / sizeof(*block_size_tests); ++i)
12250     {
12251         hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, block_size_tests[i].src_level, &src_surface);
12252         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12253         hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, block_size_tests[i].dst_level, &dst_surface);
12254         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12255
12256         hr = IDirect3DDevice9_UpdateSurface(device, src_surface, block_size_tests[i].r, dst_surface, NULL);
12257         ok(hr == block_size_tests[i].hr, "Update surface returned %#x for test %u, expected %#x.\n",
12258                 hr, i, block_size_tests[i].hr);
12259
12260         IDirect3DSurface9_Release(dst_surface);
12261         IDirect3DSurface9_Release(src_surface);
12262     }
12263
12264     for (i = 0; i < count; ++i)
12265     {
12266         hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, i, &src_surface);
12267         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12268         hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, i, &dst_surface);
12269         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12270
12271         hr = IDirect3DDevice9_UpdateSurface(device, src_surface, NULL, dst_surface, NULL);
12272         ok(SUCCEEDED(hr), "Failed to update surface at level %u, hr %#x.\n", i, hr);
12273
12274         IDirect3DSurface9_Release(dst_surface);
12275         IDirect3DSurface9_Release(src_surface);
12276     }
12277
12278     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12279     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12280     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
12281     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12282     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
12283     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12284     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)dst_tex);
12285     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12286     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12287     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12288     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12289     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12290
12291     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
12292     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12293
12294     hr = IDirect3DDevice9_BeginScene(device);
12295     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12296     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 1, tri, sizeof(*tri));
12297     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12298     hr = IDirect3DDevice9_EndScene(device);
12299     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12300
12301     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
12302     {
12303         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
12304         ok(color_match(color, expected_colors[i].color, 0),
12305                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
12306                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
12307     }
12308
12309     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12310     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12311
12312     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12313     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12314     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
12315     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12316     IDirect3DTexture9_Release(dst_tex);
12317     IDirect3DTexture9_Release(src_tex);
12318 }
12319
12320 START_TEST(visual)
12321 {
12322     IDirect3DDevice9 *device_ptr;
12323     D3DCAPS9 caps;
12324     HRESULT hr;
12325     DWORD color;
12326
12327     d3d9_handle = LoadLibraryA("d3d9.dll");
12328     if (!d3d9_handle)
12329     {
12330         skip("Could not load d3d9.dll\n");
12331         return;
12332     }
12333
12334     device_ptr = init_d3d9();
12335     if (!device_ptr)
12336     {
12337         skip("Creating the device failed\n");
12338         return;
12339     }
12340
12341     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
12342
12343     /* Check for the reliability of the returned data */
12344     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
12345     if(FAILED(hr))
12346     {
12347         skip("Clear failed, can't assure correctness of the test results, skipping\n");
12348         goto cleanup;
12349     }
12350
12351     color = getPixelColor(device_ptr, 1, 1);
12352     if(color !=0x00ff0000)
12353     {
12354         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
12355         goto cleanup;
12356     }
12357     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
12358
12359     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
12360     if(FAILED(hr))
12361     {
12362         skip("Clear failed, can't assure correctness of the test results, skipping\n");
12363         goto cleanup;
12364     }
12365
12366     color = getPixelColor(device_ptr, 639, 479);
12367     if(color != 0x0000ddee)
12368     {
12369         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
12370         goto cleanup;
12371     }
12372     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
12373
12374     /* Now execute the real tests */
12375     depth_clamp_test(device_ptr);
12376     stretchrect_test(device_ptr);
12377     lighting_test(device_ptr);
12378     clear_test(device_ptr);
12379     color_fill_test(device_ptr);
12380     fog_test(device_ptr);
12381     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
12382     {
12383         test_cube_wrap(device_ptr);
12384     } else {
12385         skip("No cube texture support\n");
12386     }
12387     z_range_test(device_ptr);
12388     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
12389     {
12390         maxmip_test(device_ptr);
12391     }
12392     else
12393     {
12394         skip("No mipmap support\n");
12395     }
12396     offscreen_test(device_ptr);
12397     ds_size_test(device_ptr);
12398     alpha_test(device_ptr);
12399     shademode_test(device_ptr);
12400     srgbtexture_test(device_ptr);
12401     release_buffer_test(device_ptr);
12402     float_texture_test(device_ptr);
12403     g16r16_texture_test(device_ptr);
12404     pixelshader_blending_test(device_ptr);
12405     texture_transform_flags_test(device_ptr);
12406     autogen_mipmap_test(device_ptr);
12407     fixed_function_decl_test(device_ptr);
12408     conditional_np2_repeat_test(device_ptr);
12409     fixed_function_bumpmap_test(device_ptr);
12410     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
12411         stencil_cull_test(device_ptr);
12412     } else {
12413         skip("No two sided stencil support\n");
12414     }
12415     pointsize_test(device_ptr);
12416     tssargtemp_test(device_ptr);
12417     np2_stretch_rect_test(device_ptr);
12418     yuv_color_test(device_ptr);
12419     zwriteenable_test(device_ptr);
12420     alphatest_test(device_ptr);
12421     viewport_test(device_ptr);
12422
12423     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
12424     {
12425         test_constant_clamp_vs(device_ptr);
12426         test_compare_instructions(device_ptr);
12427     }
12428     else skip("No vs_1_1 support\n");
12429
12430     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
12431     {
12432         test_mova(device_ptr);
12433         loop_index_test(device_ptr);
12434         sincos_test(device_ptr);
12435         sgn_test(device_ptr);
12436         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
12437             test_vshader_input(device_ptr);
12438             test_vshader_float16(device_ptr);
12439             stream_test(device_ptr);
12440         } else {
12441             skip("No vs_3_0 support\n");
12442         }
12443     }
12444     else skip("No vs_2_0 support\n");
12445
12446     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
12447     {
12448         fog_with_shader_test(device_ptr);
12449     }
12450     else skip("No vs_1_1 and ps_1_1 support\n");
12451
12452     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
12453     {
12454         texbem_test(device_ptr);
12455         texdepth_test(device_ptr);
12456         texkill_test(device_ptr);
12457         x8l8v8u8_test(device_ptr);
12458         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
12459             constant_clamp_ps_test(device_ptr);
12460             cnd_test(device_ptr);
12461             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
12462                 dp2add_ps_test(device_ptr);
12463                 unbound_sampler_test(device_ptr);
12464                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0) && caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
12465                     nested_loop_test(device_ptr);
12466                     pretransformed_varying_test(device_ptr);
12467                     vFace_register_test(device_ptr);
12468                     vpos_register_test(device_ptr);
12469                     multiple_rendertargets_test(device_ptr);
12470                 } else {
12471                     skip("No ps_3_0 or vs_3_0 support\n");
12472                 }
12473             } else {
12474                 skip("No ps_2_0 support\n");
12475             }
12476         }
12477     }
12478     else skip("No ps_1_1 support\n");
12479
12480     texop_test(device_ptr);
12481     texop_range_test(device_ptr);
12482     alphareplicate_test(device_ptr);
12483     dp3_alpha_test(device_ptr);
12484     depth_buffer_test(device_ptr);
12485     depth_buffer2_test(device_ptr);
12486     depth_blit_test(device_ptr);
12487     intz_test(device_ptr);
12488     shadow_test(device_ptr);
12489     fp_special_test(device_ptr);
12490     depth_bounds_test(device_ptr);
12491     srgbwrite_format_test(device_ptr);
12492     clip_planes_test(device_ptr);
12493     update_surface_test(device_ptr);
12494
12495 cleanup:
12496     if(device_ptr) {
12497         D3DPRESENT_PARAMETERS present_parameters;
12498         IDirect3DSwapChain9 *swapchain;
12499         ULONG ref;
12500
12501         IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
12502         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
12503         IDirect3DSwapChain9_Release(swapchain);
12504         ref = IDirect3DDevice9_Release(device_ptr);
12505         ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
12506         DestroyWindow(present_parameters.hDeviceWindow);
12507     }
12508 }