mshtml: Added IHTMLElement2::get_readyState implementation.
[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_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8, 0, 0, TRUE, &surf, NULL);
114     if(FAILED(hr) || !surf )  /* This is not a test */
115     {
116         trace("Can't create an offscreen plain surface to read the render target data, hr=%08x\n", hr);
117         return 0xdeadbeef;
118     }
119
120     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
121     if(FAILED(hr))
122     {
123         trace("Can't get the render target, hr=%08x\n", hr);
124         ret = 0xdeadbeed;
125         goto out;
126     }
127
128     hr = IDirect3DDevice9_StretchRect(device, target, NULL, surf, NULL, D3DTEXF_POINT);
129     if(FAILED(hr))
130     {
131         trace("Can't read the render target data, hr=%08x\n", hr);
132         ret = 0xdeadbeec;
133         goto out;
134     }
135
136     hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
137     if(FAILED(hr))
138     {
139         trace("Can't lock the offscreen surface, hr=%08x\n", hr);
140         ret = 0xdeadbeeb;
141         goto out;
142     }
143
144     /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
145      * really important for these tests
146      */
147     ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
148     hr = IDirect3DSurface9_UnlockRect(surf);
149     if(FAILED(hr))
150     {
151         trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
152     }
153
154 out:
155     if(target) IDirect3DSurface9_Release(target);
156     if(surf) IDirect3DSurface9_Release(surf);
157     return ret;
158 }
159
160 static IDirect3DDevice9 *init_d3d9(void)
161 {
162     IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
163     IDirect3D9 *d3d9_ptr = 0;
164     IDirect3DDevice9 *device_ptr = 0;
165     D3DPRESENT_PARAMETERS present_parameters;
166     HRESULT hr;
167     D3DADAPTER_IDENTIFIER9 identifier;
168
169     d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
170     ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
171     if (!d3d9_create) return NULL;
172
173     d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
174     if (!d3d9_ptr)
175     {
176         skip("could not create D3D9\n");
177         return NULL;
178     }
179
180     ZeroMemory(&present_parameters, sizeof(present_parameters));
181     present_parameters.Windowed = TRUE;
182     present_parameters.hDeviceWindow = create_window();
183     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
184     present_parameters.BackBufferWidth = 640;
185     present_parameters.BackBufferHeight = 480;
186     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
187     present_parameters.EnableAutoDepthStencil = TRUE;
188     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
189
190     memset(&identifier, 0, sizeof(identifier));
191     hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
192     ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
193     trace("Driver string: \"%s\"\n", identifier.Driver);
194     trace("Description string: \"%s\"\n", identifier.Description);
195     ok(identifier.Description[0] != '\0', "Empty driver description\n");
196     trace("Device name string: \"%s\"\n", identifier.DeviceName);
197     ok(identifier.DeviceName[0]  != '\0', "Empty device name\n");
198     trace("Driver version %d.%d.%d.%d\n",
199           HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
200           HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
201
202     hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
203     if(FAILED(hr)) {
204         present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
205         hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
206         if(FAILED(hr)) {
207             hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
208         }
209     }
210     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %08x\n", hr);
211
212     return device_ptr;
213 }
214
215 struct vertex
216 {
217     float x, y, z;
218     DWORD diffuse;
219 };
220
221 struct tvertex
222 {
223     float x, y, z, rhw;
224     DWORD diffuse;
225 };
226
227 struct nvertex
228 {
229     float x, y, z;
230     float nx, ny, nz;
231     DWORD diffuse;
232 };
233
234 static void lighting_test(IDirect3DDevice9 *device)
235 {
236     HRESULT hr;
237     DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
238     DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
239     DWORD color;
240     D3DMATERIAL9 material, old_material;
241     DWORD cop, carg;
242
243     float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
244                       0.0f, 1.0f, 0.0f, 0.0f,
245                       0.0f, 0.0f, 1.0f, 0.0f,
246                       0.0f, 0.0f, 0.0f, 1.0f };
247
248     struct vertex unlitquad[] =
249     {
250         {-1.0f, -1.0f,   0.1f,                          0xffff0000},
251         {-1.0f,  0.0f,   0.1f,                          0xffff0000},
252         { 0.0f,  0.0f,   0.1f,                          0xffff0000},
253         { 0.0f, -1.0f,   0.1f,                          0xffff0000},
254     };
255     struct vertex litquad[] =
256     {
257         {-1.0f,  0.0f,   0.1f,                          0xff00ff00},
258         {-1.0f,  1.0f,   0.1f,                          0xff00ff00},
259         { 0.0f,  1.0f,   0.1f,                          0xff00ff00},
260         { 0.0f,  0.0f,   0.1f,                          0xff00ff00},
261     };
262     struct nvertex unlitnquad[] =
263     {
264         { 0.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
265         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
266         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
267         { 1.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
268     };
269     struct nvertex litnquad[] =
270     {
271         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
272         { 0.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
273         { 1.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
274         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
275     };
276     WORD Indices[] = {0, 1, 2, 2, 3, 0};
277
278     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
279     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
280
281     /* Setup some states that may cause issues */
282     hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
283     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
284     hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
285     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
286     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
287     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
288     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
289     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
290     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
291     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
292     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
293     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
294     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
295     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
296     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
297     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
298     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
299     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
300     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
301     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
302     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
303     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
304     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
305     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
306
307     hr = IDirect3DDevice9_SetFVF(device, 0);
308     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
309
310     hr = IDirect3DDevice9_SetFVF(device, fvf);
311     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
312
313     hr = IDirect3DDevice9_BeginScene(device);
314     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
315     if(hr == D3D_OK)
316     {
317         /* No lights are defined... That means, lit vertices should be entirely black */
318         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
319         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
320         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
321                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
322         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
323
324         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
325         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
326         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
327                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
328         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
329
330         hr = IDirect3DDevice9_SetFVF(device, nfvf);
331         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
332
333         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
334         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
335         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
336                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
337         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
338
339         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
340         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
341         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
342                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
343         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
344
345         IDirect3DDevice9_EndScene(device);
346         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
347     }
348
349     color = getPixelColor(device, 160, 360); /* lower left quad - unlit without normals */
350     ok(color == 0x00ff0000, "Unlit quad without normals has color %08x\n", color);
351     color = getPixelColor(device, 160, 120); /* upper left quad - lit without normals */
352     ok(color == 0x00000000, "Lit quad without normals has color %08x\n", color);
353     color = getPixelColor(device, 480, 360); /* lower left quad - unlit with normals */
354     ok(color == 0x000000ff, "Unlit quad with normals has color %08x\n", color);
355     color = getPixelColor(device, 480, 120); /* upper left quad - lit with normals */
356     ok(color == 0x00000000, "Lit quad with normals has color %08x\n", color);
357
358     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
359
360     hr = IDirect3DDevice9_GetMaterial(device, &old_material);
361     ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
362     memset(&material, 0, sizeof(material));
363     material.Diffuse.r = 0.0;
364     material.Diffuse.g = 0.0;
365     material.Diffuse.b = 0.0;
366     material.Diffuse.a = 1.0;
367     material.Ambient.r = 0.0;
368     material.Ambient.g = 0.0;
369     material.Ambient.b = 0.0;
370     material.Ambient.a = 0.0;
371     material.Specular.r = 0.0;
372     material.Specular.g = 0.0;
373     material.Specular.b = 0.0;
374     material.Specular.a = 0.0;
375     material.Emissive.r = 0.0;
376     material.Emissive.g = 0.0;
377     material.Emissive.b = 0.0;
378     material.Emissive.a = 0.0;
379     material.Power = 0.0;
380     IDirect3DDevice9_SetMaterial(device, &material);
381     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
382
383     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
384     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
385     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
386     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
387
388     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
389     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
390     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
391     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
392     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
393     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
394     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
395     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
396
397     hr = IDirect3DDevice9_BeginScene(device);
398     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
399     if(SUCCEEDED(hr)) {
400         struct vertex lighting_test[] = {
401             {-1.0,   -1.0,   0.1,    0x8000ff00},
402             { 1.0,   -1.0,   0.1,    0x80000000},
403             {-1.0,    1.0,   0.1,    0x8000ff00},
404             { 1.0,    1.0,   0.1,    0x80000000}
405         };
406         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
407         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
408         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
409         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
410
411         hr = IDirect3DDevice9_EndScene(device);
412         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
413     }
414
415     color = getPixelColor(device, 320, 240);
416     ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
417     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
418
419     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
420     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
421     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
422     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
423     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
424     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
425     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
426     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
427     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
428     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
429     hr = IDirect3DDevice9_SetMaterial(device, &old_material);
430     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
431 }
432
433 static void clear_test(IDirect3DDevice9 *device)
434 {
435     /* Tests the correctness of clearing parameters */
436     HRESULT hr;
437     D3DRECT rect[2];
438     D3DRECT rect_negneg;
439     DWORD color;
440     D3DVIEWPORT9 old_vp, vp;
441     RECT scissor;
442     DWORD oldColorWrite;
443     BOOL invalid_clear_failed = FALSE;
444
445     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
446     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
447
448     /* Positive x, negative y */
449     rect[0].x1 = 0;
450     rect[0].y1 = 480;
451     rect[0].x2 = 320;
452     rect[0].y2 = 240;
453
454     /* Positive x, positive y */
455     rect[1].x1 = 0;
456     rect[1].y1 = 0;
457     rect[1].x2 = 320;
458     rect[1].y2 = 240;
459     /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
460      * returns D3D_OK, but ignores the rectangle silently
461      */
462     hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
463     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
464     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
465
466     /* negative x, negative y */
467     rect_negneg.x1 = 640;
468     rect_negneg.y1 = 240;
469     rect_negneg.x2 = 320;
470     rect_negneg.y2 = 0;
471     hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
472     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
473     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
474
475     color = getPixelColor(device, 160, 360); /* lower left quad */
476     ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
477     color = getPixelColor(device, 160, 120); /* upper left quad */
478     if(invalid_clear_failed) {
479         /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
480         ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
481     } else {
482         /* If the negative rectangle was dropped silently, the correct ones are cleared */
483         ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
484     }
485     color = getPixelColor(device, 480, 360); /* lower right quad  */
486     ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
487     color = getPixelColor(device, 480, 120); /* upper right quad */
488     ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
489
490     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
491
492     /* Test how the viewport affects clears */
493     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
494     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
495     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
496     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
497
498     vp.X = 160;
499     vp.Y = 120;
500     vp.Width = 160;
501     vp.Height = 120;
502     vp.MinZ = 0.0;
503     vp.MaxZ = 1.0;
504     hr = IDirect3DDevice9_SetViewport(device, &vp);
505     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
506     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
507     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
508
509     vp.X = 320;
510     vp.Y = 240;
511     vp.Width = 320;
512     vp.Height = 240;
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     rect[0].x1 = 160;
518     rect[0].y1 = 120;
519     rect[0].x2 = 480;
520     rect[0].y2 = 360;
521     hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
522     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
523
524     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
525     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
526
527     color = getPixelColor(device, 158, 118);
528     ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
529     color = getPixelColor(device, 162, 118);
530     ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
531     color = getPixelColor(device, 158, 122);
532     ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
533     color = getPixelColor(device, 162, 122);
534     ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
535
536     color = getPixelColor(device, 318, 238);
537     ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
538     color = getPixelColor(device, 322, 238);
539     ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
540     color = getPixelColor(device, 318, 242);
541     ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
542     color = getPixelColor(device, 322, 242);
543     ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
544
545     color = getPixelColor(device, 478, 358);
546     ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
547     color = getPixelColor(device, 482, 358);
548     ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
549     color = getPixelColor(device, 478, 362);
550     ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
551     color = getPixelColor(device, 482, 362);
552     ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
553
554     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
555
556     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
557     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
558
559     scissor.left = 160;
560     scissor.right = 480;
561     scissor.top = 120;
562     scissor.bottom = 360;
563     hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
564     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
565     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
566     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
567
568     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
569     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
570     hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
571     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
572
573     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
574     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
575
576     color = getPixelColor(device, 158, 118);
577     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
578     color = getPixelColor(device, 162, 118);
579     ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
580     color = getPixelColor(device, 158, 122);
581     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
582     color = getPixelColor(device, 162, 122);
583     ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
584
585     color = getPixelColor(device, 158, 358);
586     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
587     color = getPixelColor(device, 162, 358);
588     ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
589     color = getPixelColor(device, 158, 358);
590     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
591     color = getPixelColor(device, 162, 362);
592     ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
593
594     color = getPixelColor(device, 478, 118);
595     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
596     color = getPixelColor(device, 478, 122);
597     ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
598     color = getPixelColor(device, 482, 122);
599     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
600     color = getPixelColor(device, 482, 358);
601     ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
602
603     color = getPixelColor(device, 478, 358);
604     ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
605     color = getPixelColor(device, 478, 362);
606     ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
607     color = getPixelColor(device, 482, 358);
608     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
609     color = getPixelColor(device, 482, 362);
610     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
611
612     color = getPixelColor(device, 318, 238);
613     ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
614     color = getPixelColor(device, 318, 242);
615     ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
616     color = getPixelColor(device, 322, 238);
617     ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
618     color = getPixelColor(device, 322, 242);
619     ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
620
621     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
622
623     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
624     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
625     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
626     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
627
628     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
629     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
630
631     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
632     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
633
634     /* Colorwriteenable does not affect the clear */
635     color = getPixelColor(device, 320, 240);
636     ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
637
638     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
639 }
640
641 typedef struct {
642     float in[4];
643     DWORD out;
644 } test_data_t;
645
646 /*
647  *  c7      mova    ARGB            mov     ARGB
648  * -2.4     -2      0x00ffff00      -3      0x00ff0000
649  * -1.6     -2      0x00ffff00      -2      0x00ffff00
650  * -0.4      0      0x0000ffff      -1      0x0000ff00
651  *  0.4      0      0x0000ffff       0      0x0000ffff
652  *  1.6      2      0x00ff00ff       1      0x000000ff
653  *  2.4      2      0x00ff00ff       2      0x00ff00ff
654  */
655 static void test_mova(IDirect3DDevice9 *device)
656 {
657     static const DWORD mova_test[] = {
658         0xfffe0200,                                                             /* vs_2_0                       */
659         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
660         0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
661         0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
662         0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
663         0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
664         0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
665         0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
666         0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
667         0x0200002e, 0xb0010000, 0xa0000007,                                     /* mova a0.x, c7.x              */
668         0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000,                         /* mov oD0, c[a0.x + 3]         */
669         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
670         0x0000ffff                                                              /* END                          */
671     };
672     static const DWORD mov_test[] = {
673         0xfffe0101,                                                             /* vs_1_1                       */
674         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
675         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
676         0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
677         0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
678         0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
679         0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
680         0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
681         0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
682         0x00000001, 0xb0010000, 0xa0000007,                                     /* mov a0.x, c7.x               */
683         0x00000001, 0xd00f0000, 0xa0e42003,                                     /* mov oD0, c[a0.x + 3]         */
684         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
685         0x0000ffff                                                              /* END                          */
686     };
687
688     static const test_data_t test_data[2][6] = {
689         {
690             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
691             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
692             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
693             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
694             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
695             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
696         },
697         {
698             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
699             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
700             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
701             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
702             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
703             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
704         }
705     };
706
707     static const float quad[][3] = {
708         {-1.0f, -1.0f, 0.0f},
709         {-1.0f,  1.0f, 0.0f},
710         { 1.0f, -1.0f, 0.0f},
711         { 1.0f,  1.0f, 0.0f},
712     };
713
714     static const D3DVERTEXELEMENT9 decl_elements[] = {
715         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
716         D3DDECL_END()
717     };
718
719     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
720     IDirect3DVertexShader9 *mova_shader = NULL;
721     IDirect3DVertexShader9 *mov_shader = NULL;
722     HRESULT hr;
723     UINT i, j;
724
725     hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
726     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
727     hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
728     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
729     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
730     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
731     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
732     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
733
734     hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
735     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
736     for(j = 0; j < 2; ++j)
737     {
738         for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
739         {
740             DWORD color;
741
742             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
743             ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
744
745             hr = IDirect3DDevice9_BeginScene(device);
746             ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
747
748             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
749             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
750
751             hr = IDirect3DDevice9_EndScene(device);
752             ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
753
754             color = getPixelColor(device, 320, 240);
755             ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
756                test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
757
758             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
759             ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
760
761             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
762             ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
763         }
764         hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
765         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
766     }
767
768     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
769     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
770
771     IDirect3DVertexDeclaration9_Release(vertex_declaration);
772     IDirect3DVertexShader9_Release(mova_shader);
773     IDirect3DVertexShader9_Release(mov_shader);
774 }
775
776 struct sVertex {
777     float x, y, z;
778     DWORD diffuse;
779     DWORD specular;
780 };
781
782 struct sVertexT {
783     float x, y, z, rhw;
784     DWORD diffuse;
785     DWORD specular;
786 };
787
788 static void fog_test(IDirect3DDevice9 *device)
789 {
790     HRESULT hr;
791     D3DCOLOR color;
792     float start = 0.0f, end = 1.0f;
793     D3DCAPS9 caps;
794     int i;
795
796     /* Gets full z based fog with linear fog, no fog with specular color */
797     struct sVertex unstransformed_1[] = {
798         {-1,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
799         {-1,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
800         { 0,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
801         { 0,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
802     };
803     /* Ok, I am too lazy to deal with transform matrices */
804     struct sVertex unstransformed_2[] = {
805         {-1,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
806         {-1,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
807         { 0,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
808         { 0,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
809     };
810     /* Untransformed ones. Give them a different diffuse color to make the test look
811      * nicer. It also makes making sure that they are drawn correctly easier.
812      */
813     struct sVertexT transformed_1[] = {
814         {320,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
815         {640,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
816         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
817         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
818     };
819     struct sVertexT transformed_2[] = {
820         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
821         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
822         {640,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
823         {320,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
824     };
825     struct vertex rev_fog_quads[] = {
826        {-1.0,   -1.0,   0.1,    0x000000ff},
827        {-1.0,    0.0,   0.1,    0x000000ff},
828        { 0.0,    0.0,   0.1,    0x000000ff},
829        { 0.0,   -1.0,   0.1,    0x000000ff},
830
831        { 0.0,   -1.0,   0.9,    0x000000ff},
832        { 0.0,    0.0,   0.9,    0x000000ff},
833        { 1.0,    0.0,   0.9,    0x000000ff},
834        { 1.0,   -1.0,   0.9,    0x000000ff},
835
836        { 0.0,    0.0,   0.4,    0x000000ff},
837        { 0.0,    1.0,   0.4,    0x000000ff},
838        { 1.0,    1.0,   0.4,    0x000000ff},
839        { 1.0,    0.0,   0.4,    0x000000ff},
840
841        {-1.0,    0.0,   0.7,    0x000000ff},
842        {-1.0,    1.0,   0.7,    0x000000ff},
843        { 0.0,    1.0,   0.7,    0x000000ff},
844        { 0.0,    0.0,   0.7,    0x000000ff},
845     };
846     WORD Indices[] = {0, 1, 2, 2, 3, 0};
847
848     memset(&caps, 0, sizeof(caps));
849     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
850     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
851     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
852     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
853
854     /* Setup initial states: No lighting, fog on, fog color */
855     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
856     ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
857     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
858     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
859     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
860     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
861
862     /* First test: Both table fog and vertex fog off */
863     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
864     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
865     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
866     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
867
868     /* Start = 0, end = 1. Should be default, but set them */
869     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
870     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
871     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
872     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
873
874     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
875     {
876         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
877         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
878         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
879         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
880                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
881                                                      sizeof(unstransformed_1[0]));
882         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
883
884         /* That makes it use the Z value */
885         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
886         ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
887         /* Untransformed, vertex fog != none (or table fog != none):
888          * Use the Z value as input into the equation
889          */
890         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
891                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
892                                                      sizeof(unstransformed_1[0]));
893         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
894
895         /* transformed verts */
896         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
897         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
898         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
899         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
900                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
901                                                      sizeof(transformed_1[0]));
902         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
903
904         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
905         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
906         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
907          * equation
908          */
909         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
910                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
911                                                      sizeof(transformed_2[0]));
912         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
913
914         hr = IDirect3DDevice9_EndScene(device);
915         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
916     }
917     else
918     {
919         ok(FALSE, "BeginScene failed\n");
920     }
921
922     color = getPixelColor(device, 160, 360);
923     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
924     color = getPixelColor(device, 160, 120);
925     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
926     color = getPixelColor(device, 480, 120);
927     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
928     if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
929     {
930         color = getPixelColor(device, 480, 360);
931         ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
932     }
933     else
934     {
935         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
936          * The settings above result in no fogging with vertex fog
937          */
938         color = getPixelColor(device, 480, 120);
939         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
940         trace("Info: Table fog not supported by this device\n");
941     }
942     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
943
944     /* Now test the special case fogstart == fogend */
945     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
946     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
947
948     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
949     {
950         start = 512;
951         end = 512;
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         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
958         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
959         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
960         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
961         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
962         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
963
964         /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
965          * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
966          * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
967          * The third transformed quad remains unfogged because the fogcoords are read from the specular
968          * color and has fixed fogstart and fogend.
969          */
970         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
971                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
972                 sizeof(unstransformed_1[0]));
973         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
974         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
975                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
976                 sizeof(unstransformed_1[0]));
977         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
978
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_EndScene(device);
988         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
989     }
990     else
991     {
992         ok(FALSE, "BeginScene failed\n");
993     }
994     color = getPixelColor(device, 160, 360);
995     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
996     color = getPixelColor(device, 160, 120);
997     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
998     color = getPixelColor(device, 480, 120);
999     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1000     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1001
1002     /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1003      * but without shaders it seems to work everywhere
1004      */
1005     end = 0.2;
1006     start = 0.8;
1007     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1008     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1009     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1010     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1011     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1012     ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1013
1014     /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1015      * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1016      * so skip this for now
1017      */
1018     for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1019         const char *mode = (i ? "table" : "vertex");
1020         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1021         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1022         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1023         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1024         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1025         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1026         hr = IDirect3DDevice9_BeginScene(device);
1027         ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1028         if(SUCCEEDED(hr)) {
1029             WORD Indices2[] = { 0,  1,  2,  2,  3, 0,
1030                                 4,  5,  6,  6,  7, 4,
1031                                 8,  9, 10, 10, 11, 8,
1032                             12, 13, 14, 14, 15, 12};
1033
1034             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1035                     16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1036                     sizeof(rev_fog_quads[0]));
1037             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1038
1039             hr = IDirect3DDevice9_EndScene(device);
1040             ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1041         }
1042         color = getPixelColor(device, 160, 360);
1043         ok(color_match(color, 0x0000ff00, 1),
1044                 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1045
1046         color = getPixelColor(device, 160, 120);
1047         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1048                 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1049
1050         color = getPixelColor(device, 480, 120);
1051         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1052                 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1053
1054         color = getPixelColor(device, 480, 360);
1055         ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1056
1057         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1058
1059         if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1060             skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1061             break;
1062         }
1063     }
1064     /* Turn off the fog master switch to avoid confusing other tests */
1065     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1066     ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1067     start = 0.0;
1068     end = 1.0;
1069     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1070     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1071     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1072     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1073     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1074     ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1075     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1076     ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1077 }
1078
1079 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1080  * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1081  * regardless of the actual addressing mode set. */
1082 static void test_cube_wrap(IDirect3DDevice9 *device)
1083 {
1084     static const float quad[][6] = {
1085         {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1086         {-1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1087         { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1088         { 1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1089     };
1090
1091     static const D3DVERTEXELEMENT9 decl_elements[] = {
1092         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1093         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1094         D3DDECL_END()
1095     };
1096
1097     static const struct {
1098         D3DTEXTUREADDRESS mode;
1099         const char *name;
1100     } address_modes[] = {
1101         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1102         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1103         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1104         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1105         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1106     };
1107
1108     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1109     IDirect3DCubeTexture9 *texture = NULL;
1110     IDirect3DSurface9 *surface = NULL;
1111     D3DLOCKED_RECT locked_rect;
1112     HRESULT hr;
1113     UINT x;
1114     INT y, face;
1115
1116     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1117     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1118     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1119     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1120
1121     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1122             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1123     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1124
1125     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1126     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1127
1128     for (y = 0; y < 128; ++y)
1129     {
1130         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1131         for (x = 0; x < 64; ++x)
1132         {
1133             *ptr++ = 0xffff0000;
1134         }
1135         for (x = 64; x < 128; ++x)
1136         {
1137             *ptr++ = 0xff0000ff;
1138         }
1139     }
1140
1141     hr = IDirect3DSurface9_UnlockRect(surface);
1142     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1143
1144     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1145             D3DPOOL_DEFAULT, &texture, NULL);
1146     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1147
1148     /* Create cube faces */
1149     for (face = 0; face < 6; ++face)
1150     {
1151         IDirect3DSurface9 *face_surface = NULL;
1152
1153         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1154         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1155
1156         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1157         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1158
1159         IDirect3DSurface9_Release(face_surface);
1160     }
1161
1162     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1163     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1164
1165     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1166     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1167     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1168     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1169     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1170     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1171
1172     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1173     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1174
1175     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1176     {
1177         DWORD color;
1178
1179         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1180         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1181         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1182         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1183
1184         hr = IDirect3DDevice9_BeginScene(device);
1185         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1186
1187         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1188         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1189
1190         hr = IDirect3DDevice9_EndScene(device);
1191         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1192
1193         /* Due to the nature of this test, we sample essentially at the edge
1194          * between two faces. Because of this it's undefined from which face
1195          * the driver will sample. Fortunately that's not important for this
1196          * test, since all we care about is that it doesn't sample from the
1197          * other side of the surface or from the border. */
1198         color = getPixelColor(device, 320, 240);
1199         ok(color == 0x00ff0000 || color == 0x000000ff,
1200                 "Got color 0x%08x for addressing mode %s, expected 0x00ff0000 or 0x000000ff.\n",
1201                 color, address_modes[x].name);
1202
1203         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1204         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1205
1206         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1207         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1208     }
1209
1210     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1211     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1212
1213     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1214     IDirect3DCubeTexture9_Release(texture);
1215     IDirect3DSurface9_Release(surface);
1216 }
1217
1218 static void offscreen_test(IDirect3DDevice9 *device)
1219 {
1220     HRESULT hr;
1221     IDirect3DTexture9 *offscreenTexture = NULL;
1222     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1223     DWORD color;
1224
1225     static const float quad[][5] = {
1226         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1227         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1228         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1229         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1230     };
1231
1232     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1233     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1234
1235     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1236     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1237     if(!offscreenTexture) {
1238         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1239         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1240         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1241         if(!offscreenTexture) {
1242             skip("Cannot create an offscreen render target\n");
1243             goto out;
1244         }
1245     }
1246
1247     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1248     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1249     if(!backbuffer) {
1250         goto out;
1251     }
1252
1253     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1254     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1255     if(!offscreen) {
1256         goto out;
1257     }
1258
1259     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1260     ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1261
1262     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1263     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1264     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1265     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1266     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1267     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1268     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1269     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1270     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1271     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1272
1273     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1274         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1275         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1276         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1277         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1278
1279         /* Draw without textures - Should result in a white quad */
1280         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1281         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1282
1283         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1284         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1285         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1286         ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1287
1288         /* This time with the texture */
1289         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1290         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1291
1292         IDirect3DDevice9_EndScene(device);
1293     }
1294
1295     /* Center quad - should be white */
1296     color = getPixelColor(device, 320, 240);
1297     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1298     /* Some quad in the cleared part of the texture */
1299     color = getPixelColor(device, 170, 240);
1300     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1301     /* Part of the originally cleared back buffer */
1302     color = getPixelColor(device, 10, 10);
1303     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1304     if(0) {
1305         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1306          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1307          * the offscreen rendering mode this test would succeed or fail
1308          */
1309         color = getPixelColor(device, 10, 470);
1310         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1311     }
1312
1313     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1314
1315 out:
1316     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1317     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1318
1319     /* restore things */
1320     if(backbuffer) {
1321         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1322         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1323         IDirect3DSurface9_Release(backbuffer);
1324     }
1325     if(offscreenTexture) {
1326         IDirect3DTexture9_Release(offscreenTexture);
1327     }
1328     if(offscreen) {
1329         IDirect3DSurface9_Release(offscreen);
1330     }
1331 }
1332
1333 /* This test tests fog in combination with shaders.
1334  * What's tested: linear fog (vertex and table) with pixel shader
1335  *                linear table fog with non foggy vertex shader
1336  *                vertex fog with foggy vertex shader, non-linear
1337  *                fog with shader, non-linear fog with foggy shader,
1338  *                linear table fog with foggy shader
1339  */
1340 static void fog_with_shader_test(IDirect3DDevice9 *device)
1341 {
1342     HRESULT hr;
1343     DWORD color;
1344     union {
1345         float f;
1346         DWORD i;
1347     } start, end;
1348     unsigned int i, j;
1349
1350     /* basic vertex shader without fog computation ("non foggy") */
1351     static const DWORD vertex_shader_code1[] = {
1352         0xfffe0101,                                                             /* vs_1_1                       */
1353         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1354         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1355         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1356         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1357         0x0000ffff
1358     };
1359     /* basic vertex shader with reversed fog computation ("foggy") */
1360     static const DWORD vertex_shader_code2[] = {
1361         0xfffe0101,                                                             /* vs_1_1                        */
1362         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1363         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1364         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1365         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1366         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1367         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1368         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1369         0x0000ffff
1370     };
1371     /* basic pixel shader */
1372     static const DWORD pixel_shader_code[] = {
1373         0xffff0101,                                                             /* ps_1_1     */
1374         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, vo */
1375         0x0000ffff
1376     };
1377
1378     static struct vertex quad[] = {
1379         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1380         {-1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1381         { 1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1382         { 1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1383     };
1384
1385     static const D3DVERTEXELEMENT9 decl_elements[] = {
1386         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1387         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1388         D3DDECL_END()
1389     };
1390
1391     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1392     IDirect3DVertexShader9      *vertex_shader[3]   = {NULL, NULL, NULL};
1393     IDirect3DPixelShader9       *pixel_shader[2]    = {NULL, NULL};
1394
1395     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1396     static const struct test_data_t {
1397         int vshader;
1398         int pshader;
1399         D3DFOGMODE vfog;
1400         D3DFOGMODE tfog;
1401         unsigned int color[11];
1402     } test_data[] = {
1403         /* only pixel shader: */
1404         {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1405         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1406         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1407         {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1408         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1409         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1410         {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1411         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1412         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1413         {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1414         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1415         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1416         {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1417         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1418         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1419
1420         /* vertex shader */
1421         {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1422         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1423          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1424         {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1425         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1426         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1427         {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1428         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1429         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1430
1431         {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1432         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1433         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1434         {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1435         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1436         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1437
1438         /* vertex shader and pixel shader */
1439         /* The next 4 tests would read the fog coord output, but it isn't available.
1440          * The result is a fully fogged quad, no matter what the Z coord is. This is on
1441          * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1442          * These tests should be disabled if some other hardware behaves differently
1443          */
1444         {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1445         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1446         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1447         {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1448         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1449         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1450         {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1451         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1452         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1453         {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1454         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1455         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1456
1457         /* These use the Z coordinate with linear table fog */
1458         {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1459         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1460         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1461         {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1462         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1463         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1464         {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1465         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1466         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1467         {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1468         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1469         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1470
1471         /* Non-linear table fog without fog coord */
1472         {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1473         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1474         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1475         {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1476         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1477         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1478
1479 #if 0  /* FIXME: these fail on GeForce 8500 */
1480         /* foggy vertex shader */
1481         {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1482         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1483          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1484         {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1485         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1486          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1487         {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1488         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1489          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1490         {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1491         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1492          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1493 #endif
1494
1495         /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1496          * all using the fixed fog-coord linear fog
1497          */
1498         {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1499         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1500          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1501         {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1502         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1503          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1504         {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1505         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1506          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1507         {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1508         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1509          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1510
1511         /* These use table fog. Here the shader-provided fog coordinate is
1512          * ignored and the z coordinate used instead
1513          */
1514         {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1515         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1516         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1517         {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1518         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1519         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1520         {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1521         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1522         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1523     };
1524
1525     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1526     start.f=0.1f;
1527     end.f=0.9f;
1528
1529     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1530     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1531     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1532     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1533     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1534     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1535     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1536     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1537
1538     /* Setup initial states: No lighting, fog on, fog color */
1539     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1540     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1541     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1542     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1543     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1544     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1545     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1546     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1547
1548     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1549     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1550     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1551     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1552
1553     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1554     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1555     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1556     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1557     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1558
1559     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1560     {
1561         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1562         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1563         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1564         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1565         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1566         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1567         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1568         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1569
1570         for(j=0; j < 11; j++)
1571         {
1572             /* Don't use the whole zrange to prevent rounding errors */
1573             quad[0].z = 0.001f + (float)j / 10.02f;
1574             quad[1].z = 0.001f + (float)j / 10.02f;
1575             quad[2].z = 0.001f + (float)j / 10.02f;
1576             quad[3].z = 0.001f + (float)j / 10.02f;
1577
1578             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1579             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1580
1581             hr = IDirect3DDevice9_BeginScene(device);
1582             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1583
1584             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1585             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1586
1587             hr = IDirect3DDevice9_EndScene(device);
1588             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1589
1590             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1591             color = getPixelColor(device, 128, 240);
1592             ok(color_match(color, test_data[i].color[j], 13),
1593                 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1594                 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1595
1596             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1597         }
1598     }
1599
1600     /* reset states */
1601     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1602     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1603     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1604     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1605     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1606     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1607     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1608     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1609
1610     IDirect3DVertexShader9_Release(vertex_shader[1]);
1611     IDirect3DVertexShader9_Release(vertex_shader[2]);
1612     IDirect3DPixelShader9_Release(pixel_shader[1]);
1613     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1614 }
1615
1616 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1617     unsigned int i, x, y;
1618     HRESULT hr;
1619     IDirect3DTexture9 *texture[2] = {NULL, NULL};
1620     D3DLOCKED_RECT locked_rect;
1621
1622     /* Generate the textures */
1623     for(i=0; i<2; i++)
1624     {
1625         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1626                                             D3DPOOL_MANAGED, &texture[i], NULL);
1627         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1628
1629         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1630         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1631         for (y = 0; y < 128; ++y)
1632         {
1633             if(i)
1634             { /* Set up black texture with 2x2 texel white spot in the middle */
1635                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1636                 for (x = 0; x < 128; ++x)
1637                 {
1638                     if(y>62 && y<66 && x>62 && x<66)
1639                         *ptr++ = 0xffffffff;
1640                     else
1641                         *ptr++ = 0xff000000;
1642                 }
1643             }
1644             else
1645             { /* Set up a displacement map which points away from the center parallel to the closest axis.
1646                * (if multiplied with bumpenvmat)
1647               */
1648                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1649                 for (x = 0; x < 128; ++x)
1650                 {
1651                     if(abs(x-64)>abs(y-64))
1652                     {
1653                         if(x < 64)
1654                             *ptr++ = 0xc000;
1655                         else
1656                             *ptr++ = 0x4000;
1657                     }
1658                     else
1659                     {
1660                         if(y < 64)
1661                             *ptr++ = 0x0040;
1662                         else
1663                             *ptr++ = 0x00c0;
1664                     }
1665                 }
1666             }
1667         }
1668         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1669         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1670
1671         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1672         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1673
1674         /* Disable texture filtering */
1675         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1676         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1677         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1678         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1679
1680         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1681         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1682         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1683         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1684     }
1685 }
1686
1687 /* test the behavior of the texbem instruction
1688  * with normal 2D and projective 2D textures
1689  */
1690 static void texbem_test(IDirect3DDevice9 *device)
1691 {
1692     HRESULT hr;
1693     DWORD color;
1694     int i;
1695
1696     static const DWORD pixel_shader_code[] = {
1697         0xffff0101,                         /* ps_1_1*/
1698         0x00000042, 0xb00f0000,             /* tex t0*/
1699         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1700         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1701         0x0000ffff
1702     };
1703     static const DWORD double_texbem_code[] =  {
1704         0xffff0103,                                         /* ps_1_3           */
1705         0x00000042, 0xb00f0000,                             /* tex t0           */
1706         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
1707         0x00000042, 0xb00f0002,                             /* tex t2           */
1708         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
1709         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
1710         0x0000ffff                                          /* end              */
1711     };
1712
1713
1714     static const float quad[][7] = {
1715         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1716         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1717         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1718         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1719     };
1720     static const float quad_proj[][9] = {
1721         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
1722         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
1723         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
1724         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1725     };
1726
1727     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1728         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1729         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1730         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1731         D3DDECL_END()
1732     },{
1733         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1734         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1735         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1736         D3DDECL_END()
1737     } };
1738
1739     /* use asymmetric matrix to test loading */
1740     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1741
1742     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1743     IDirect3DPixelShader9       *pixel_shader       = NULL;
1744     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
1745     D3DLOCKED_RECT locked_rect;
1746
1747     generate_bumpmap_textures(device);
1748
1749     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1750     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1751     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1752     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1753     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1754
1755     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1756     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1757
1758     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1759     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1760
1761     for(i=0; i<2; i++)
1762     {
1763         if(i)
1764         {
1765             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1766             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1767         }
1768
1769         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1770         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1771         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1772         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1773
1774         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1775         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1776         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1777         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1778
1779         hr = IDirect3DDevice9_BeginScene(device);
1780         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1781
1782         if(!i)
1783             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1784         else
1785             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1786         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1787
1788         hr = IDirect3DDevice9_EndScene(device);
1789         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1790
1791         color = getPixelColor(device, 320-32, 240);
1792         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1793         color = getPixelColor(device, 320+32, 240);
1794         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1795         color = getPixelColor(device, 320, 240-32);
1796         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1797         color = getPixelColor(device, 320, 240+32);
1798         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1799
1800         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1801         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1802
1803         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1804         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1805         IDirect3DPixelShader9_Release(pixel_shader);
1806
1807         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1808         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1809         IDirect3DVertexDeclaration9_Release(vertex_declaration);
1810     }
1811
1812     /* clean up */
1813     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1814     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1815
1816     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1817     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1818
1819     for(i=0; i<2; i++)
1820     {
1821         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1822         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1823         IDirect3DTexture9_Release(texture); /* For the GetTexture */
1824         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1825         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1826         IDirect3DTexture9_Release(texture);
1827     }
1828
1829     /* Test double texbem */
1830     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1831     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1832     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1833     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1834     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1835     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1836     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1837     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1838
1839     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1840     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1841     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1842     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1843
1844     hr = IDirect3DTexture9_UnlockRect(texture, 0);
1845     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1846
1847     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1848     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1849     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1850     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1851     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1852     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1853
1854     {
1855         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1856 #define tex  0x00ff0000
1857 #define tex1 0x0000ff00
1858 #define origin 0x000000ff
1859         static const DWORD pixel_data[] = {
1860             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1861             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1862             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1863             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1864             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
1865             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1866             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1867             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1868         };
1869 #undef tex1
1870 #undef tex2
1871 #undef origin
1872
1873         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1874         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1875         for(i = 0; i < 8; i++) {
1876             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1877         }
1878         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1879         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1880     }
1881
1882     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1883     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1884     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1885     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1886     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1887     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1888     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1889     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1890     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1891     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1892     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1893     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1894
1895     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
1896     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
1897     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1898     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1899     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1900     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1901     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1902     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1903     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1904     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1905
1906     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
1907     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
1908     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1909     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1910     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1911     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1912     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1913     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1914     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1915     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1916
1917     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1918     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1919     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1920     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1921     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1922     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1923     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1924     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1925     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1926     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1927     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1928     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1929     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1930     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1931     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1932     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1933
1934     hr = IDirect3DDevice9_BeginScene(device);
1935     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1936     if(SUCCEEDED(hr)) {
1937         static const float double_quad[] = {
1938             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1939              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1940             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1941              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1942         };
1943
1944         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
1945         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1946         hr = IDirect3DDevice9_EndScene(device);
1947         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1948     }
1949     color = getPixelColor(device, 320, 240);
1950     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1951
1952     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1953     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1954     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
1955     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1956     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
1957     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1958     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
1959     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1960     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1961     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1962
1963     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1964     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1965
1966     IDirect3DPixelShader9_Release(pixel_shader);
1967     IDirect3DTexture9_Release(texture);
1968     IDirect3DTexture9_Release(texture1);
1969     IDirect3DTexture9_Release(texture2);
1970 }
1971
1972 static void z_range_test(IDirect3DDevice9 *device)
1973 {
1974     const struct vertex quad[] =
1975     {
1976         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
1977         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
1978         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
1979         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
1980     };
1981     const struct vertex quad2[] =
1982     {
1983         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
1984         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
1985         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
1986         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
1987     };
1988
1989     const struct tvertex quad3[] =
1990     {
1991         {    0,   240,   1.1f,  1.0,                    0xffffff00},
1992         {    0,   480,   1.1f,  1.0,                    0xffffff00},
1993         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
1994         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
1995     };
1996     const struct tvertex quad4[] =
1997     {
1998         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
1999         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
2000         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
2001         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
2002     };
2003     HRESULT hr;
2004     DWORD color;
2005     IDirect3DVertexShader9 *shader;
2006     IDirect3DVertexDeclaration9 *decl;
2007     D3DCAPS9 caps;
2008     const DWORD shader_code[] = {
2009         0xfffe0101,                                     /* vs_1_1           */
2010         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
2011         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
2012         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
2013         0x0000ffff                                      /* end              */
2014     };
2015     static const D3DVERTEXELEMENT9 decl_elements[] = {
2016         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2017         D3DDECL_END()
2018     };
2019     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2020      * then call Present. Then clear the color buffer to make sure it has some defined content
2021      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2022      * by the depth value.
2023      */
2024     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2025     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2026     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2027     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2028     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2029     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2030
2031     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2032     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2033     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2034     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2035     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2036     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2037     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2038     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2039     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2040     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2041
2042     hr = IDirect3DDevice9_BeginScene(device);
2043     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2044     if(hr == D3D_OK)
2045     {
2046         /* Test the untransformed vertex path */
2047         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2048         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2049         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2050         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2051         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2052         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2053
2054         /* Test the transformed vertex path */
2055         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2056         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2057
2058         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2059         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2060         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2061         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2062         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2063         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2064
2065         hr = IDirect3DDevice9_EndScene(device);
2066         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2067     }
2068
2069     /* Do not test the exact corner pixels, but go pretty close to them */
2070
2071     /* Clipped because z > 1.0 */
2072     color = getPixelColor(device, 28, 238);
2073     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2074     color = getPixelColor(device, 28, 241);
2075     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2076
2077     /* Not clipped, > z buffer clear value(0.75) */
2078     color = getPixelColor(device, 31, 238);
2079     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2080     color = getPixelColor(device, 31, 241);
2081     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2082     color = getPixelColor(device, 100, 238);
2083     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2084     color = getPixelColor(device, 100, 241);
2085     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2086
2087     /* Not clipped, < z buffer clear value */
2088     color = getPixelColor(device, 104, 238);
2089     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2090     color = getPixelColor(device, 104, 241);
2091     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2092     color = getPixelColor(device, 318, 238);
2093     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2094     color = getPixelColor(device, 318, 241);
2095     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2096
2097     /* Clipped because z < 0.0 */
2098     color = getPixelColor(device, 321, 238);
2099     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2100     color = getPixelColor(device, 321, 241);
2101     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2102
2103     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2104     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2105
2106     /* Test the shader path */
2107     IDirect3DDevice9_GetDeviceCaps(device, &caps);
2108     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2109         skip("Vertex shaders not supported\n");
2110         goto out;
2111     }
2112     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2113     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2114     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2115     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2116
2117     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2118
2119     IDirect3DDevice9_SetVertexDeclaration(device, decl);
2120     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2121     IDirect3DDevice9_SetVertexShader(device, shader);
2122     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2123
2124     hr = IDirect3DDevice9_BeginScene(device);
2125     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2126     if(hr == D3D_OK)
2127     {
2128         float colorf[] = {1.0, 0.0, 0.0, 1.0};
2129         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2130         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2131         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2132         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2133         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2134         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2135         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2136         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2137         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2138
2139         hr = IDirect3DDevice9_EndScene(device);
2140         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2141     }
2142
2143     IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2144     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2145     IDirect3DDevice9_SetVertexShader(device, NULL);
2146     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2147
2148     IDirect3DVertexDeclaration9_Release(decl);
2149     IDirect3DVertexShader9_Release(shader);
2150
2151     /* Z < 1.0 */
2152     color = getPixelColor(device, 28, 238);
2153     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2154
2155     /* 1.0 < z < 0.75 */
2156     color = getPixelColor(device, 31, 238);
2157     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2158     color = getPixelColor(device, 100, 238);
2159     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2160
2161     /* 0.75 < z < 0.0 */
2162     color = getPixelColor(device, 104, 238);
2163     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2164     color = getPixelColor(device, 318, 238);
2165     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2166
2167     /* 0.0 < z */
2168     color = getPixelColor(device, 321, 238);
2169     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2170
2171     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2172     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2173
2174     out:
2175     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2176     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2177     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2178     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2179     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2180     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2181 }
2182
2183 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2184 {
2185     D3DSURFACE_DESC desc;
2186     D3DLOCKED_RECT l;
2187     HRESULT hr;
2188     unsigned int x, y;
2189     DWORD *mem;
2190
2191     memset(&desc, 0, sizeof(desc));
2192     memset(&l, 0, sizeof(l));
2193     hr = IDirect3DSurface9_GetDesc(surface, &desc);
2194     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2195     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2196     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2197     if(FAILED(hr)) return;
2198
2199     for(y = 0; y < desc.Height; y++)
2200     {
2201         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2202         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2203         {
2204             mem[x] = color;
2205         }
2206     }
2207     hr = IDirect3DSurface9_UnlockRect(surface);
2208     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2209 }
2210
2211 /* This tests a variety of possible StretchRect() situations */
2212 static void stretchrect_test(IDirect3DDevice9 *device)
2213 {
2214     HRESULT hr;
2215     IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL;
2216     IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL;
2217     IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2218     IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2219     IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2220     IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2221     IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2222     IDirect3DSurface9 *orig_rt = NULL;
2223     DWORD color;
2224
2225     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2226     ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2227     if(!orig_rt) {
2228         goto out;
2229     }
2230
2231     /* Create our temporary surfaces in system memory */
2232     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2233     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2234     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2235     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2236
2237     /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2238     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2239     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2240     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2241     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2242     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2243     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2244
2245     /* Create render target surfaces */
2246     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2247     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2248     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2249     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2250     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2251     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2252
2253     /* Create render target textures */
2254     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2255     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2256     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2257     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2258     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2259     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2260     if (tex_rt32) {
2261         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2262         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2263     }
2264     if (tex_rt64) {
2265         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2266         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2267     }
2268     if (tex_rt_dest64) {
2269         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2270         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2271     }
2272
2273     /* Create regular textures in D3DPOOL_DEFAULT */
2274     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2275     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2276     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2277     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2278     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2279     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2280     if (tex32) {
2281         hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2282         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2283     }
2284     if (tex64) {
2285         hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2286         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2287     }
2288     if (tex_dest64) {
2289         hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2290         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2291     }
2292
2293     /*********************************************************************
2294      * Tests for when the source parameter is an offscreen plain surface *
2295      *********************************************************************/
2296
2297     /* Fill the offscreen 64x64 surface with green */
2298     if (surf_offscreen64)
2299         fill_surface(surf_offscreen64, 0xff00ff00);
2300
2301     /* offscreenplain ==> offscreenplain, same size */
2302     if(surf_offscreen64 && surf_offscreen_dest64) {
2303         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2304         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2305
2306         if (hr == D3D_OK) {
2307             color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2308             ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2309         }
2310     }
2311
2312     /* offscreenplain ==> rendertarget texture, same size */
2313     if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2314         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2315         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2316
2317         /* We can't lock rendertarget textures, so copy to our temp surface first */
2318         if (hr == D3D_OK) {
2319             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2320             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2321         }
2322
2323         if (hr == D3D_OK) {
2324             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2325             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2326         }
2327     }
2328
2329     /* offscreenplain ==> rendertarget surface, same size */
2330     if(surf_offscreen64 && surf_rt_dest64) {
2331         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2332         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2333
2334         if (hr == D3D_OK) {
2335             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2336             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2337         }
2338     }
2339
2340     /* offscreenplain ==> texture, same size (should fail) */
2341     if(surf_offscreen64 && surf_tex_dest64) {
2342         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2343         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2344     }
2345
2346     /* Fill the smaller offscreen surface with red */
2347     fill_surface(surf_offscreen32, 0xffff0000);
2348
2349     /* offscreenplain ==> offscreenplain, scaling (should fail) */
2350     if(surf_offscreen32 && surf_offscreen64) {
2351         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2352         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2353     }
2354
2355     /* offscreenplain ==> rendertarget texture, scaling */
2356     if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2357         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2358         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2359
2360         /* We can't lock rendertarget textures, so copy to our temp surface first */
2361         if (hr == D3D_OK) {
2362             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2363             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2364         }
2365
2366         if (hr == D3D_OK) {
2367             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2368             ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2369         }
2370     }
2371
2372     /* offscreenplain ==> rendertarget surface, scaling */
2373     if(surf_offscreen32 && surf_rt_dest64) {
2374         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2375         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2376
2377         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2378         ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2379     }
2380
2381     /* offscreenplain ==> texture, scaling (should fail) */
2382     if(surf_offscreen32 && surf_tex_dest64) {
2383         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2384         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2385     }
2386
2387     /************************************************************
2388      * Tests for when the source parameter is a regular texture *
2389      ************************************************************/
2390
2391     /* Fill the surface of the regular texture with blue */
2392     if (surf_tex64 && surf_temp64) {
2393         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2394         fill_surface(surf_temp64, 0xff0000ff);
2395         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2396         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2397     }
2398
2399     /* texture ==> offscreenplain, same size */
2400     if(surf_tex64 && surf_offscreen64) {
2401         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2402         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2403     }
2404
2405     /* texture ==> rendertarget texture, same size */
2406     if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2407         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2408         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2409
2410         /* We can't lock rendertarget textures, so copy to our temp surface first */
2411         if (hr == D3D_OK) {
2412             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2413             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2414         }
2415
2416         if (hr == D3D_OK) {
2417             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2418             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2419         }
2420     }
2421
2422     /* texture ==> rendertarget surface, same size */
2423     if(surf_tex64 && surf_rt_dest64) {
2424         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2425         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2426
2427         if (hr == D3D_OK) {
2428             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2429             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2430         }
2431     }
2432
2433     /* texture ==> texture, same size (should fail) */
2434     if(surf_tex64 && surf_tex_dest64) {
2435         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2436         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2437     }
2438
2439     /* Fill the surface of the smaller regular texture with red */
2440     if (surf_tex32 && surf_temp32) {
2441         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2442         fill_surface(surf_temp32, 0xffff0000);
2443         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2444         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2445     }
2446
2447     /* texture ==> offscreenplain, scaling (should fail) */
2448     if(surf_tex32 && surf_offscreen64) {
2449         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2450         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2451     }
2452
2453     /* texture ==> rendertarget texture, scaling */
2454     if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2455         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2456         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2457
2458         /* We can't lock rendertarget textures, so copy to our temp surface first */
2459         if (hr == D3D_OK) {
2460             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2461             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2462         }
2463
2464         if (hr == D3D_OK) {
2465             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2466             ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2467         }
2468     }
2469
2470     /* texture ==> rendertarget surface, scaling */
2471     if(surf_tex32 && surf_rt_dest64) {
2472         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2473         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2474
2475         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2476         ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2477     }
2478
2479     /* texture ==> texture, scaling (should fail) */
2480     if(surf_tex32 && surf_tex_dest64) {
2481         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2482         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2483     }
2484
2485     /*****************************************************************
2486      * Tests for when the source parameter is a rendertarget texture *
2487      *****************************************************************/
2488
2489     /* Fill the surface of the rendertarget texture with white */
2490     if (surf_tex_rt64 && surf_temp64) {
2491         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2492         fill_surface(surf_temp64, 0xffffffff);
2493         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2494         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2495     }
2496
2497     /* rendertarget texture ==> offscreenplain, same size */
2498     if(surf_tex_rt64 && surf_offscreen64) {
2499         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2500         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2501     }
2502
2503     /* rendertarget texture ==> rendertarget texture, same size */
2504     if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2505         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2506         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2507
2508         /* We can't lock rendertarget textures, so copy to our temp surface first */
2509         if (hr == D3D_OK) {
2510             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2511             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2512         }
2513
2514         if (hr == D3D_OK) {
2515             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2516             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2517         }
2518     }
2519
2520     /* rendertarget texture ==> rendertarget surface, same size */
2521     if(surf_tex_rt64 && surf_rt_dest64) {
2522         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2523         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2524
2525         if (hr == D3D_OK) {
2526             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2527             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2528         }
2529     }
2530
2531     /* rendertarget texture ==> texture, same size (should fail) */
2532     if(surf_tex_rt64 && surf_tex_dest64) {
2533         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2534         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2535     }
2536
2537     /* Fill the surface of the smaller rendertarget texture with red */
2538     if (surf_tex_rt32 && surf_temp32) {
2539         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2540         fill_surface(surf_temp32, 0xffff0000);
2541         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2542         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2543     }
2544
2545     /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2546     if(surf_tex_rt32 && surf_offscreen64) {
2547         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2548         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2549     }
2550
2551     /* rendertarget texture ==> rendertarget texture, scaling */
2552     if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2553         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2554         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2555
2556         /* We can't lock rendertarget textures, so copy to our temp surface first */
2557         if (hr == D3D_OK) {
2558             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2559             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2560         }
2561
2562         if (hr == D3D_OK) {
2563             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2564             ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2565         }
2566     }
2567
2568     /* rendertarget texture ==> rendertarget surface, scaling */
2569     if(surf_tex_rt32 && surf_rt_dest64) {
2570         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2571         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2572
2573         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2574         ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2575     }
2576
2577     /* rendertarget texture ==> texture, scaling (should fail) */
2578     if(surf_tex_rt32 && surf_tex_dest64) {
2579         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2580         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2581     }
2582
2583     /*****************************************************************
2584      * Tests for when the source parameter is a rendertarget surface *
2585      *****************************************************************/
2586
2587     /* Fill the surface of the rendertarget surface with black */
2588     if (surf_rt64)
2589         fill_surface(surf_rt64, 0xff000000);
2590
2591     /* rendertarget texture ==> offscreenplain, same size */
2592     if(surf_rt64 && surf_offscreen64) {
2593         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2594         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2595     }
2596
2597     /* rendertarget surface ==> rendertarget texture, same size */
2598     if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2599         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2600         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2601
2602         /* We can't lock rendertarget textures, so copy to our temp surface first */
2603         if (hr == D3D_OK) {
2604             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2605             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2606         }
2607
2608         if (hr == D3D_OK) {
2609             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2610             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2611         }
2612     }
2613
2614     /* rendertarget surface ==> rendertarget surface, same size */
2615     if(surf_rt64 && surf_rt_dest64) {
2616         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2617         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2618
2619         if (hr == D3D_OK) {
2620             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2621             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2622         }
2623     }
2624
2625     /* rendertarget surface ==> texture, same size (should fail) */
2626     if(surf_rt64 && surf_tex_dest64) {
2627         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2628         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2629     }
2630
2631     /* Fill the surface of the smaller rendertarget texture with red */
2632     if (surf_rt32)
2633         fill_surface(surf_rt32, 0xffff0000);
2634
2635     /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2636     if(surf_rt32 && surf_offscreen64) {
2637         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2638         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2639     }
2640
2641     /* rendertarget surface ==> rendertarget texture, scaling */
2642     if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2643         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2644         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2645
2646         /* We can't lock rendertarget textures, so copy to our temp surface first */
2647         if (hr == D3D_OK) {
2648             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2649             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2650         }
2651
2652         if (hr == D3D_OK) {
2653             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2654             ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2655         }
2656     }
2657
2658     /* rendertarget surface ==> rendertarget surface, scaling */
2659     if(surf_rt32 && surf_rt_dest64) {
2660         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2661         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2662
2663         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2664         ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2665     }
2666
2667     /* rendertarget surface ==> texture, scaling (should fail) */
2668     if(surf_rt32 && surf_tex_dest64) {
2669         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2670         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2671     }
2672
2673     /* TODO: Test when source and destination RECT parameters are given... */
2674     /* TODO: Test format conversions */
2675
2676
2677 out:
2678     /* Clean up */
2679     if (surf_rt32)
2680         IDirect3DSurface9_Release(surf_rt32);
2681     if (surf_rt64)
2682         IDirect3DSurface9_Release(surf_rt64);
2683     if (surf_rt_dest64)
2684         IDirect3DSurface9_Release(surf_rt_dest64);
2685     if (surf_temp32)
2686         IDirect3DSurface9_Release(surf_temp32);
2687     if (surf_temp64)
2688         IDirect3DSurface9_Release(surf_temp64);
2689     if (surf_offscreen32)
2690         IDirect3DSurface9_Release(surf_offscreen32);
2691     if (surf_offscreen64)
2692         IDirect3DSurface9_Release(surf_offscreen64);
2693     if (surf_offscreen_dest64)
2694         IDirect3DSurface9_Release(surf_offscreen_dest64);
2695
2696     if (tex_rt32) {
2697         if (surf_tex_rt32)
2698             IDirect3DSurface9_Release(surf_tex_rt32);
2699         IDirect3DTexture9_Release(tex_rt32);
2700     }
2701     if (tex_rt64) {
2702         if (surf_tex_rt64)
2703             IDirect3DSurface9_Release(surf_tex_rt64);
2704         IDirect3DTexture9_Release(tex_rt64);
2705     }
2706     if (tex_rt_dest64) {
2707         if (surf_tex_rt_dest64)
2708             IDirect3DSurface9_Release(surf_tex_rt_dest64);
2709         IDirect3DTexture9_Release(tex_rt_dest64);
2710     }
2711     if (tex32) {
2712         if (surf_tex32)
2713             IDirect3DSurface9_Release(surf_tex32);
2714         IDirect3DTexture9_Release(tex32);
2715     }
2716     if (tex64) {
2717         if (surf_tex64)
2718             IDirect3DSurface9_Release(surf_tex64);
2719         IDirect3DTexture9_Release(tex64);
2720     }
2721     if (tex_dest64) {
2722         if (surf_tex_dest64)
2723             IDirect3DSurface9_Release(surf_tex_dest64);
2724         IDirect3DTexture9_Release(tex_dest64);
2725     }
2726
2727     if (orig_rt) {
2728         hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2729         ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
2730         IDirect3DSurface9_Release(orig_rt);
2731     }
2732 }
2733
2734 static void maxmip_test(IDirect3DDevice9 *device)
2735 {
2736     IDirect3DTexture9 *texture = NULL;
2737     IDirect3DSurface9 *surface = NULL;
2738     HRESULT hr;
2739     DWORD color;
2740     const float quads[] = {
2741         -1.0,   -1.0,   0.0,    0.0,    0.0,
2742         -1.0,    0.0,   0.0,    0.0,    1.0,
2743          0.0,   -1.0,   0.0,    1.0,    0.0,
2744          0.0,    0.0,   0.0,    1.0,    1.0,
2745
2746          0.0,   -1.0,   0.0,    0.0,    0.0,
2747          0.0,    0.0,   0.0,    0.0,    1.0,
2748          1.0,   -1.0,   0.0,    1.0,    0.0,
2749          1.0,    0.0,   0.0,    1.0,    1.0,
2750
2751          0.0,    0.0,   0.0,    0.0,    0.0,
2752          0.0,    1.0,   0.0,    0.0,    1.0,
2753          1.0,    0.0,   0.0,    1.0,    0.0,
2754          1.0,    1.0,   0.0,    1.0,    1.0,
2755
2756         -1.0,    0.0,   0.0,    0.0,    0.0,
2757         -1.0,    1.0,   0.0,    0.0,    1.0,
2758          0.0,    0.0,   0.0,    1.0,    0.0,
2759          0.0,    1.0,   0.0,    1.0,    1.0,
2760     };
2761
2762     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2763     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2764
2765     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2766                                         &texture, NULL);
2767     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2768     if(!texture)
2769     {
2770         skip("Failed to create test texture\n");
2771         return;
2772     }
2773
2774     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
2775     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
2776     fill_surface(surface, 0xffff0000);
2777     IDirect3DSurface9_Release(surface);
2778     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
2779     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
2780     fill_surface(surface, 0xff00ff00);
2781     IDirect3DSurface9_Release(surface);
2782     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
2783     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
2784     fill_surface(surface, 0xff0000ff);
2785     IDirect3DSurface9_Release(surface);
2786
2787     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2788     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2789     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2790     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2791
2792     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2793     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2794
2795     hr = IDirect3DDevice9_BeginScene(device);
2796     if(SUCCEEDED(hr))
2797     {
2798         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2799         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2800         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2801         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2802
2803         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2804         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2805         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2806         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2807
2808         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2809         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2810         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2811         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2812
2813         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2814         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2815         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2816         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2817         hr = IDirect3DDevice9_EndScene(device);
2818         ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
2819     }
2820
2821     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
2822     color = getPixelColor(device, 160, 360);
2823     ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
2824     color = getPixelColor(device, 160, 120);
2825     ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
2826     color = getPixelColor(device, 480, 120);
2827     ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
2828     color = getPixelColor(device, 480, 360);
2829     ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
2830     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2831     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2832
2833     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2834     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2835
2836     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2837     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2838
2839     hr = IDirect3DDevice9_BeginScene(device);
2840     if(SUCCEEDED(hr))
2841     {
2842         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2843         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2844         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2845         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2846
2847         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2848         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2849         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2850         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2851
2852         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2853         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2854         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2855         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2856
2857         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2858         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2859         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2860         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2861         hr = IDirect3DDevice9_EndScene(device);
2862         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
2863     }
2864
2865     /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2866      * samples from the highest level in the texture(level 2)
2867      */
2868     color = getPixelColor(device, 160, 360);
2869     ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
2870     color = getPixelColor(device, 160, 120);
2871     ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
2872     color = getPixelColor(device, 480, 120);
2873     ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
2874     color = getPixelColor(device, 480, 360);
2875     ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
2876     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2877     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2878
2879     hr = IDirect3DDevice9_BeginScene(device);
2880     if(SUCCEEDED(hr))
2881     {
2882         DWORD ret;
2883
2884         /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
2885         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2886         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2887         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2888         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2889         ret = IDirect3DTexture9_SetLOD(texture, 1);
2890         ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
2891         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2892         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2893
2894         /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
2895         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2896         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2897         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2898         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2899         ret = IDirect3DTexture9_SetLOD(texture, 2);
2900         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
2901         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2902         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2903
2904         /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
2905         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2906         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2907         ret = IDirect3DTexture9_SetLOD(texture, 1);
2908         ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
2909         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2910         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2911
2912         /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
2913         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2914         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2915         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2916         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2917         ret = IDirect3DTexture9_SetLOD(texture, 1);
2918         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
2919         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2920         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2921         hr = IDirect3DDevice9_EndScene(device);
2922     }
2923
2924     /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2925      * samples from the highest level in the texture(level 2)
2926      */
2927     color = getPixelColor(device, 160, 360);
2928     ok(color == 0x0000FF00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x\n", color);
2929     color = getPixelColor(device, 160, 120);
2930     ok(color == 0x0000FF00, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x\n", color);
2931     color = getPixelColor(device, 480, 120);
2932     ok(color == 0x000000FF, "MapMip 2, LOD 1, point mipfilter has color 0x%08x\n", color);
2933     color = getPixelColor(device, 480, 360);
2934     ok(color == 0x000000FF, "MapMip 2, LOD 1, none mipfilter has color 0x%08x\n", color);
2935     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2936     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2937
2938     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2939     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2940     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2941     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2942     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2943     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2944     IDirect3DTexture9_Release(texture);
2945 }
2946
2947 static void release_buffer_test(IDirect3DDevice9 *device)
2948 {
2949     IDirect3DVertexBuffer9 *vb = NULL;
2950     IDirect3DIndexBuffer9 *ib = NULL;
2951     HRESULT hr;
2952     BYTE *data;
2953     LONG ref;
2954
2955     static const struct vertex quad[] = {
2956         {-1.0,      -1.0,       0.1,        0xffff0000},
2957         {-1.0,       1.0,       0.1,        0xffff0000},
2958         { 1.0,       1.0,       0.1,        0xffff0000},
2959
2960         {-1.0,      -1.0,       0.1,        0xff00ff00},
2961         {-1.0,       1.0,       0.1,        0xff00ff00},
2962         { 1.0,       1.0,       0.1,        0xff00ff00}
2963     };
2964     short indices[] = {3, 4, 5};
2965
2966     /* Index and vertex buffers should always be creatable */
2967     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
2968                                               D3DPOOL_MANAGED, &vb, NULL);
2969     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
2970     if(!vb) {
2971         skip("Failed to create a vertex buffer\n");
2972         return;
2973     }
2974     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
2975     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
2976     if(!ib) {
2977         skip("Failed to create an index buffer\n");
2978         return;
2979     }
2980
2981     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
2982     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
2983     memcpy(data, quad, sizeof(quad));
2984     hr = IDirect3DVertexBuffer9_Unlock(vb);
2985     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
2986
2987     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
2988     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
2989     memcpy(data, indices, sizeof(indices));
2990     hr = IDirect3DIndexBuffer9_Unlock(ib);
2991     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2992
2993     hr = IDirect3DDevice9_SetIndices(device, ib);
2994     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
2995     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
2996     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
2997     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2998     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2999
3000     /* Now destroy the bound index buffer and draw again */
3001     ref = IDirect3DIndexBuffer9_Release(ib);
3002     ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3003
3004     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3005     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3006
3007     hr = IDirect3DDevice9_BeginScene(device);
3008     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3009     if(SUCCEEDED(hr))
3010     {
3011         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3012          * making assumptions about the indices or vertices
3013          */
3014         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3015         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3016         hr = IDirect3DDevice9_EndScene(device);
3017         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3018     }
3019
3020     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3021     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3022
3023     hr = IDirect3DDevice9_SetIndices(device, NULL);
3024     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3025     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3026     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3027
3028     /* Index buffer was already destroyed as part of the test */
3029     IDirect3DVertexBuffer9_Release(vb);
3030 }
3031
3032 static void float_texture_test(IDirect3DDevice9 *device)
3033 {
3034     IDirect3D9 *d3d = NULL;
3035     HRESULT hr;
3036     IDirect3DTexture9 *texture = NULL;
3037     D3DLOCKED_RECT lr;
3038     float *data;
3039     DWORD color;
3040     float quad[] = {
3041         -1.0,      -1.0,       0.1,     0.0,    0.0,
3042         -1.0,       1.0,       0.1,     0.0,    1.0,
3043          1.0,      -1.0,       0.1,     1.0,    0.0,
3044          1.0,       1.0,       0.1,     1.0,    1.0,
3045     };
3046
3047     memset(&lr, 0, sizeof(lr));
3048     IDirect3DDevice9_GetDirect3D(device, &d3d);
3049     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3050                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3051         skip("D3DFMT_R32F textures not supported\n");
3052         goto out;
3053     }
3054
3055     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3056                                         D3DPOOL_MANAGED, &texture, NULL);
3057     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3058     if(!texture) {
3059         skip("Failed to create R32F texture\n");
3060         goto out;
3061     }
3062
3063     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3064     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3065     data = lr.pBits;
3066     *data = 0.0;
3067     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3068     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3069
3070     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3071     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3072
3073     hr = IDirect3DDevice9_BeginScene(device);
3074     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3075     if(SUCCEEDED(hr))
3076     {
3077         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3078         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3079
3080         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3081         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3082
3083         hr = IDirect3DDevice9_EndScene(device);
3084         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3085     }
3086     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3087     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3088
3089     color = getPixelColor(device, 240, 320);
3090     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3091
3092     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3093     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3094
3095 out:
3096     if(texture) IDirect3DTexture9_Release(texture);
3097     IDirect3D9_Release(d3d);
3098 }
3099
3100 static void g16r16_texture_test(IDirect3DDevice9 *device)
3101 {
3102     IDirect3D9 *d3d = NULL;
3103     HRESULT hr;
3104     IDirect3DTexture9 *texture = NULL;
3105     D3DLOCKED_RECT lr;
3106     DWORD *data;
3107     DWORD color;
3108     float quad[] = {
3109        -1.0,      -1.0,       0.1,     0.0,    0.0,
3110        -1.0,       1.0,       0.1,     0.0,    1.0,
3111         1.0,      -1.0,       0.1,     1.0,    0.0,
3112         1.0,       1.0,       0.1,     1.0,    1.0,
3113     };
3114
3115     memset(&lr, 0, sizeof(lr));
3116     IDirect3DDevice9_GetDirect3D(device, &d3d);
3117     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3118        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3119            skip("D3DFMT_G16R16 textures not supported\n");
3120            goto out;
3121     }
3122
3123     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3124                                         D3DPOOL_MANAGED, &texture, NULL);
3125     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3126     if(!texture) {
3127         skip("Failed to create D3DFMT_G16R16 texture\n");
3128         goto out;
3129     }
3130
3131     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3132     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3133     data = lr.pBits;
3134     *data = 0x0f00f000;
3135     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3136     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3137
3138     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3139     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3140
3141     hr = IDirect3DDevice9_BeginScene(device);
3142     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3143     if(SUCCEEDED(hr))
3144     {
3145         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3146         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3147
3148         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3149         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3150
3151         hr = IDirect3DDevice9_EndScene(device);
3152         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3153     }
3154     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3155     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3156
3157     color = getPixelColor(device, 240, 320);
3158     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3159        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3160
3161     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3162     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3163
3164 out:
3165     if(texture) IDirect3DTexture9_Release(texture);
3166     IDirect3D9_Release(d3d);
3167 }
3168
3169 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3170 {
3171     HRESULT hr;
3172     IDirect3D9 *d3d;
3173     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3174     D3DCAPS9 caps;
3175     IDirect3DTexture9 *texture = NULL;
3176     IDirect3DVolumeTexture9 *volume = NULL;
3177     unsigned int x, y, z;
3178     D3DLOCKED_RECT lr;
3179     D3DLOCKED_BOX lb;
3180     DWORD color;
3181     UINT w, h;
3182     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3183     float identity[16] = {1.0, 0.0, 0.0, 0.0,
3184                            0.0, 1.0, 0.0, 0.0,
3185                            0.0, 0.0, 1.0, 0.0,
3186                            0.0, 0.0, 0.0, 1.0};
3187     static const D3DVERTEXELEMENT9 decl_elements[] = {
3188         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3189         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3190         D3DDECL_END()
3191     };
3192     static const D3DVERTEXELEMENT9 decl_elements2[] = {
3193         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3194         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3195         D3DDECL_END()
3196     };
3197     static const D3DVERTEXELEMENT9 decl_elements3[] = {
3198         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3199         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3200         D3DDECL_END()
3201     };
3202     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3203                                                  0x00, 0xff, 0x00, 0x00,
3204                                                  0x00, 0x00, 0x00, 0x00,
3205                                                  0x00, 0x00, 0x00, 0x00};
3206
3207     memset(&lr, 0, sizeof(lr));
3208     memset(&lb, 0, sizeof(lb));
3209     IDirect3DDevice9_GetDirect3D(device, &d3d);
3210     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3211                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3212         fmt = D3DFMT_A16B16G16R16;
3213     }
3214     IDirect3D9_Release(d3d);
3215
3216     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3217     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3218     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3219     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3220     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3221     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3222     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3223     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3224     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3225     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3226     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3227     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3228     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3229     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3230     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3231     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3232     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3233     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3234     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3235     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3236     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3237     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3238     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3239     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3240
3241     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3242     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3243     w = min(1024, caps.MaxTextureWidth);
3244     h = min(1024, caps.MaxTextureHeight);
3245     hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3246                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3247     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3248     if(!texture) {
3249         skip("Failed to create the test texture\n");
3250         return;
3251     }
3252
3253     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3254      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3255      * 1.0 in red and green for the x and y coords
3256      */
3257     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3258     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3259     for(y = 0; y < h; y++) {
3260         for(x = 0; x < w; x++) {
3261             double r_f = (double) y / (double) h;
3262             double g_f = (double) x / (double) w;
3263             if(fmt == D3DFMT_A16B16G16R16) {
3264                 unsigned short r, g;
3265                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3266                 r = (unsigned short) (r_f * 65536.0);
3267                 g = (unsigned short) (g_f * 65536.0);
3268                 dst[0] = r;
3269                 dst[1] = g;
3270                 dst[2] = 0;
3271                 dst[3] = 65535;
3272             } else {
3273                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3274                 unsigned char r = (unsigned char) (r_f * 255.0);
3275                 unsigned char g = (unsigned char) (g_f * 255.0);
3276                 dst[0] = 0;
3277                 dst[1] = g;
3278                 dst[2] = r;
3279                 dst[3] = 255;
3280             }
3281         }
3282     }
3283     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3284     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3285     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3286     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3287
3288     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3289     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3290     hr = IDirect3DDevice9_BeginScene(device);
3291     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3292     if(SUCCEEDED(hr))
3293     {
3294         float quad1[] = {
3295             -1.0,      -1.0,       0.1,     1.0,    1.0,
3296             -1.0,       0.0,       0.1,     1.0,    1.0,
3297              0.0,      -1.0,       0.1,     1.0,    1.0,
3298              0.0,       0.0,       0.1,     1.0,    1.0,
3299         };
3300         float quad2[] = {
3301             -1.0,       0.0,       0.1,     1.0,    1.0,
3302             -1.0,       1.0,       0.1,     1.0,    1.0,
3303              0.0,       0.0,       0.1,     1.0,    1.0,
3304              0.0,       1.0,       0.1,     1.0,    1.0,
3305         };
3306         float quad3[] = {
3307              0.0,       0.0,       0.1,     0.5,    0.5,
3308              0.0,       1.0,       0.1,     0.5,    0.5,
3309              1.0,       0.0,       0.1,     0.5,    0.5,
3310              1.0,       1.0,       0.1,     0.5,    0.5,
3311         };
3312         float quad4[] = {
3313              320,       480,       0.1,     1.0,    0.0,    1.0,
3314              320,       240,       0.1,     1.0,    0.0,    1.0,
3315              640,       480,       0.1,     1.0,    0.0,    1.0,
3316              640,       240,       0.1,     1.0,    0.0,    1.0,
3317         };
3318         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3319                           0.0, 0.0, 0.0, 0.0,
3320                           0.0, 0.0, 0.0, 0.0,
3321                           0.0, 0.0, 0.0, 0.0};
3322
3323         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3324         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3325         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3326         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3327         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3328
3329         /* What happens with transforms enabled? */
3330         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3331         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3332         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3333         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3334
3335         /* What happens if 4 coords are used, but only 2 given ?*/
3336         mat[8] = 1.0;
3337         mat[13] = 1.0;
3338         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3339         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3340         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3341         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3342         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3343         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3344
3345         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3346          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3347          * due to the coords in the vertices. (turns out red, indeed)
3348          */
3349         memset(mat, 0, sizeof(mat));
3350         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3351         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3352         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3353         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3354         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3355         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3356         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3357         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3358
3359         hr = IDirect3DDevice9_EndScene(device);
3360         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3361     }
3362     color = getPixelColor(device, 160, 360);
3363     ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3364     color = getPixelColor(device, 160, 120);
3365     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3366     color = getPixelColor(device, 480, 120);
3367     ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
3368     color = getPixelColor(device, 480, 360);
3369     ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
3370     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3371     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3372
3373     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3374     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3375
3376     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3377     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3378     hr = IDirect3DDevice9_BeginScene(device);
3379     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3380     if(SUCCEEDED(hr))
3381     {
3382         float quad1[] = {
3383             -1.0,      -1.0,       0.1,     0.8,    0.2,
3384             -1.0,       0.0,       0.1,     0.8,    0.2,
3385              0.0,      -1.0,       0.1,     0.8,    0.2,
3386              0.0,       0.0,       0.1,     0.8,    0.2,
3387         };
3388         float quad2[] = {
3389             -1.0,       0.0,       0.1,     0.5,    1.0,
3390             -1.0,       1.0,       0.1,     0.5,    1.0,
3391              0.0,       0.0,       0.1,     0.5,    1.0,
3392              0.0,       1.0,       0.1,     0.5,    1.0,
3393         };
3394         float quad3[] = {
3395              0.0,       0.0,       0.1,     0.5,    1.0,
3396              0.0,       1.0,       0.1,     0.5,    1.0,
3397              1.0,       0.0,       0.1,     0.5,    1.0,
3398              1.0,       1.0,       0.1,     0.5,    1.0,
3399         };
3400         float quad4[] = {
3401              0.0,      -1.0,       0.1,     0.8,    0.2,
3402              0.0,       0.0,       0.1,     0.8,    0.2,
3403              1.0,      -1.0,       0.1,     0.8,    0.2,
3404              1.0,       0.0,       0.1,     0.8,    0.2,
3405         };
3406         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3407                           0.0, 0.0, 0.0, 0.0,
3408                           0.0, 1.0, 0.0, 0.0,
3409                           0.0, 0.0, 0.0, 0.0};
3410
3411         /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3412          */
3413         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3414         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3415         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3416         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3417
3418         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3419         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3420
3421         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3422          * it behaves like COUNT2 because normal textures require 2 coords
3423          */
3424         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3425         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3426         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3427         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3428
3429         /* Just to be sure, the same as quad2 above */
3430         memset(mat, 0, sizeof(mat));
3431         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3432         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3433         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3434         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3435         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3436         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3437
3438         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3439          * used? And what happens to the first?
3440          */
3441         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3442         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3443         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3444         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3445
3446         hr = IDirect3DDevice9_EndScene(device);
3447         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3448     }
3449     color = getPixelColor(device, 160, 360);
3450     ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
3451     color = getPixelColor(device, 160, 120);
3452     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3453     color = getPixelColor(device, 480, 120);
3454     ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
3455        "quad 3 has color %08x, expected 0x00ff8000\n", color);
3456     color = getPixelColor(device, 480, 360);
3457     ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
3458        "quad 4 has color %08x, expected 0x0033cc00\n", color);
3459     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3460     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3461
3462     IDirect3DTexture9_Release(texture);
3463
3464     /* Test projected textures, without any fancy matrices */
3465     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3466     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3467     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3468     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3469     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3470     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3471     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3472     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3473
3474     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3475     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3476     for(x = 0; x < 4; x++) {
3477         memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3478     }
3479     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3480     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3481     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3482     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3483
3484     hr = IDirect3DDevice9_BeginScene(device);
3485     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3486     if(SUCCEEDED(hr))
3487     {
3488         const float proj_quads[] = {
3489            -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3490             1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3491            -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3492             1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3493            -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3494             1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3495            -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3496             1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3497         };
3498
3499         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3500         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3501         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3502         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3503
3504         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3505         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3506         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3507         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3508
3509         hr = IDirect3DDevice9_EndScene(device);
3510         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3511     }
3512
3513     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3514     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3515     IDirect3DTexture9_Release(texture);
3516
3517     color = getPixelColor(device, 158, 118);
3518     ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3519     color = getPixelColor(device, 162, 118);
3520     ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3521     color = getPixelColor(device, 158, 122);
3522     ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3523     color = getPixelColor(device, 162, 122);
3524     ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3525
3526     color = getPixelColor(device, 158, 178);
3527     ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3528     color = getPixelColor(device, 162, 178);
3529     ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3530     color = getPixelColor(device, 158, 182);
3531     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3532     color = getPixelColor(device, 162, 182);
3533     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3534
3535     color = getPixelColor(device, 318, 118);
3536     ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3537     color = getPixelColor(device, 322, 118);
3538     ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3539     color = getPixelColor(device, 318, 122);
3540     ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3541     color = getPixelColor(device, 322, 122);
3542     ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3543
3544     color = getPixelColor(device, 318, 178);
3545     ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3546     color = getPixelColor(device, 322, 178);
3547     ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3548     color = getPixelColor(device, 318, 182);
3549     ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3550     color = getPixelColor(device, 322, 182);
3551     ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3552
3553     color = getPixelColor(device, 238, 298);
3554     ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3555     color = getPixelColor(device, 242, 298);
3556     ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3557     color = getPixelColor(device, 238, 302);
3558     ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3559     color = getPixelColor(device, 242, 302);
3560     ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3561
3562     color = getPixelColor(device, 238, 388);
3563     ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3564     color = getPixelColor(device, 242, 388);
3565     ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3566     color = getPixelColor(device, 238, 392);
3567     ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3568     color = getPixelColor(device, 242, 392);
3569     ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3570
3571     color = getPixelColor(device, 478, 298);
3572     ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3573     color = getPixelColor(device, 482, 298);
3574     ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3575     color = getPixelColor(device, 478, 302);
3576     ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3577     color = getPixelColor(device, 482, 302);
3578     ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3579
3580     color = getPixelColor(device, 478, 388);
3581     ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3582     color = getPixelColor(device, 482, 388);
3583     ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3584     color = getPixelColor(device, 478, 392);
3585     ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3586     color = getPixelColor(device, 482, 392);
3587     ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3588
3589     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3590     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3591
3592     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3593     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3594     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3595      * Thus watch out if sampling from texels between 0 and 1.
3596      */
3597     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3598     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3599        "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3600     if(!volume) {
3601         skip("Failed to create a volume texture\n");
3602         goto out;
3603     }
3604
3605     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3606     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3607     for(z = 0; z < 32; z++) {
3608         for(y = 0; y < 32; y++) {
3609             for(x = 0; x < 32; x++) {
3610                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3611                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3612                 float r_f = (float) x / 31.0;
3613                 float g_f = (float) y / 31.0;
3614                 float b_f = (float) z / 31.0;
3615
3616                 if(fmt == D3DFMT_A16B16G16R16) {
3617                     unsigned short *mem_s = mem;
3618                     mem_s[0]  = r_f * 65535.0;
3619                     mem_s[1]  = g_f * 65535.0;
3620                     mem_s[2]  = b_f * 65535.0;
3621                     mem_s[3]  = 65535;
3622                 } else {
3623                     unsigned char *mem_c = mem;
3624                     mem_c[0]  = b_f * 255.0;
3625                     mem_c[1]  = g_f * 255.0;
3626                     mem_c[2]  = r_f * 255.0;
3627                     mem_c[3]  = 255;
3628                 }
3629             }
3630         }
3631     }
3632     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3633     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3634
3635     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3636     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3637
3638     hr = IDirect3DDevice9_BeginScene(device);
3639     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3640     if(SUCCEEDED(hr))
3641     {
3642         float quad1[] = {
3643             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3644             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3645              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3646              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3647         };
3648         float quad2[] = {
3649             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3650             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
3651              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3652              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
3653         };
3654         float quad3[] = {
3655              0.0,       0.0,       0.1,     0.0,    0.0,
3656              0.0,       1.0,       0.1,     0.0,    0.0,
3657              1.0,       0.0,       0.1,     0.0,    0.0,
3658              1.0,       1.0,       0.1,     0.0,    0.0
3659         };
3660         float quad4[] = {
3661              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3662              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3663              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3664              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
3665         };
3666         float mat[16] = {1.0, 0.0, 0.0, 0.0,
3667                          0.0, 0.0, 1.0, 0.0,
3668                          0.0, 1.0, 0.0, 0.0,
3669                          0.0, 0.0, 0.0, 1.0};
3670         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3671         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3672
3673         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3674          * values
3675          */
3676         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3677         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3678         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3679         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3680         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3681         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3682
3683         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3684          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3685          * otherwise the w will be missing(blue).
3686          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3687          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3688          */
3689         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3690         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3691         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3692         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3693
3694         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
3695         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3696         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3697         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3698         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3699         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3700         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3701         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3702         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3703
3704         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3705          * disable. ATI extends it up to the amount of values needed for the volume texture
3706          */
3707         memset(mat, 0, sizeof(mat));
3708         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3709         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3710         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3711         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3712         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3713         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3714         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3715         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3716
3717         hr = IDirect3DDevice9_EndScene(device);
3718         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3719     }
3720
3721     color = getPixelColor(device, 160, 360);
3722     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3723     color = getPixelColor(device, 160, 120);
3724     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3725        "quad 2 has color %08x, expected 0x00ffff00\n", color);
3726     color = getPixelColor(device, 480, 120);
3727     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3728     color = getPixelColor(device, 480, 360);
3729     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3730
3731     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3732     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3733
3734     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3735     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3736     hr = IDirect3DDevice9_BeginScene(device);
3737     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3738     if(SUCCEEDED(hr))
3739     {
3740         float quad1[] = {
3741             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3742             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3743              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3744              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3745         };
3746         float quad2[] = {
3747             -1.0,       0.0,       0.1,
3748             -1.0,       1.0,       0.1,
3749              0.0,       0.0,       0.1,
3750              0.0,       1.0,       0.1,
3751         };
3752         float quad3[] = {
3753              0.0,       0.0,       0.1,     1.0,
3754              0.0,       1.0,       0.1,     1.0,
3755              1.0,       0.0,       0.1,     1.0,
3756              1.0,       1.0,       0.1,     1.0
3757         };
3758         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
3759                            0.0, 0.0, 0.0, 0.0,
3760                            0.0, 0.0, 0.0, 0.0,
3761                            0.0, 1.0, 0.0, 0.0};
3762         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
3763                            1.0, 0.0, 0.0, 0.0,
3764                            0.0, 1.0, 0.0, 0.0,
3765                            0.0, 0.0, 1.0, 0.0};
3766         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3767         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3768
3769         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
3770          */
3771         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3772         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3773         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3774         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3775         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3776         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3777
3778         /* None passed */
3779         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3780         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3781         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3782         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3783         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3784         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3785
3786         /* 4 used, 1 passed */
3787         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
3788         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3789         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
3790         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3791         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
3792         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3793
3794         hr = IDirect3DDevice9_EndScene(device);
3795         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3796     }
3797     color = getPixelColor(device, 160, 360);
3798     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
3799     color = getPixelColor(device, 160, 120);
3800     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
3801     color = getPixelColor(device, 480, 120);
3802     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
3803     /* Quad4: unused */
3804
3805     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3806     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3807
3808     IDirect3DVolumeTexture9_Release(volume);
3809
3810     out:
3811     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3812     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3813     IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
3814     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3815     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3816     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3817     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3818     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3819     IDirect3DVertexDeclaration9_Release(decl);
3820     IDirect3DVertexDeclaration9_Release(decl2);
3821     IDirect3DVertexDeclaration9_Release(decl3);
3822 }
3823
3824 static void texdepth_test(IDirect3DDevice9 *device)
3825 {
3826     IDirect3DPixelShader9 *shader;
3827     HRESULT hr;
3828     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
3829     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
3830     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
3831     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
3832     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
3833     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
3834     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
3835     DWORD shader_code[] = {
3836         0xffff0104,                                                                 /* ps_1_4               */
3837         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
3838         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
3839         0x0000fffd,                                                                 /* phase                */
3840         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
3841         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
3842         0x0000ffff                                                                  /* end                  */
3843     };
3844     DWORD color;
3845     float vertex[] = {
3846        -1.0,   -1.0,    0.0,
3847         1.0,   -1.0,    1.0,
3848        -1.0,    1.0,    0.0,
3849         1.0,    1.0,    1.0
3850     };
3851
3852     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3853     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3854
3855     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
3856     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3857     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3858     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3859     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3860     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3861     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3862     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3863     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3864     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
3865
3866     /* Fill the depth buffer with a gradient */
3867     hr = IDirect3DDevice9_BeginScene(device);
3868     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3869     if(SUCCEEDED(hr))
3870     {
3871         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3872         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3873         hr = IDirect3DDevice9_EndScene(device);
3874         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3875     }
3876
3877     /* Now perform the actual tests. Same geometry, but with the shader */
3878     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3879     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3880     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3881     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3882     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3883     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3884
3885     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
3886     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3887     hr = IDirect3DDevice9_BeginScene(device);
3888     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3889     if(SUCCEEDED(hr))
3890     {
3891         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3892         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3893
3894         hr = IDirect3DDevice9_EndScene(device);
3895         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3896     }
3897
3898     color = getPixelColor(device, 158, 240);
3899     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3900     color = getPixelColor(device, 162, 240);
3901     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
3902
3903     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3904     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3905
3906     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3907     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
3908
3909     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
3910     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3911     hr = IDirect3DDevice9_BeginScene(device);
3912     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3913     if(SUCCEEDED(hr))
3914     {
3915         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3916         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3917
3918         hr = IDirect3DDevice9_EndScene(device);
3919         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3920     }
3921
3922     color = getPixelColor(device, 318, 240);
3923     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3924     color = getPixelColor(device, 322, 240);
3925     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3926
3927     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3928     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3929
3930     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3931     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
3932
3933     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
3934     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3935     hr = IDirect3DDevice9_BeginScene(device);
3936     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3937     if(SUCCEEDED(hr))
3938     {
3939         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3940         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3941
3942         hr = IDirect3DDevice9_EndScene(device);
3943         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3944     }
3945
3946     color = getPixelColor(device, 1, 240);
3947     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
3948
3949     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3950     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3951
3952     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3953     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
3954
3955     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
3956     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3957     hr = IDirect3DDevice9_BeginScene(device);
3958     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3959     if(SUCCEEDED(hr))
3960     {
3961         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3962         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3963
3964         hr = IDirect3DDevice9_EndScene(device);
3965         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3966     }
3967     color = getPixelColor(device, 318, 240);
3968     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3969     color = getPixelColor(device, 322, 240);
3970     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
3971
3972     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3973     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3974
3975     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3976     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
3977
3978     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
3979     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3980     hr = IDirect3DDevice9_BeginScene(device);
3981     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3982     if(SUCCEEDED(hr))
3983     {
3984         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3985         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3986
3987         hr = IDirect3DDevice9_EndScene(device);
3988         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3989     }
3990
3991     color = getPixelColor(device, 1, 240);
3992     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3993
3994     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3995     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3996
3997     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3998     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
3999
4000     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4001     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4002     hr = IDirect3DDevice9_BeginScene(device);
4003     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4004     if(SUCCEEDED(hr))
4005     {
4006         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4007         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4008
4009         hr = IDirect3DDevice9_EndScene(device);
4010         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4011     }
4012
4013     color = getPixelColor(device, 638, 240);
4014     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4015
4016     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4017     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4018
4019     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4020     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4021
4022     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4023     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4024     hr = IDirect3DDevice9_BeginScene(device);
4025     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4026     if(SUCCEEDED(hr))
4027     {
4028         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4029         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4030
4031         hr = IDirect3DDevice9_EndScene(device);
4032         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4033     }
4034
4035     color = getPixelColor(device, 638, 240);
4036     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4037
4038     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4039     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4040
4041     /* Cleanup */
4042     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4043     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4044     IDirect3DPixelShader9_Release(shader);
4045
4046     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4047     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4048     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4049     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4050 }
4051
4052 static void texkill_test(IDirect3DDevice9 *device)
4053 {
4054     IDirect3DPixelShader9 *shader;
4055     HRESULT hr;
4056     DWORD color;
4057
4058     const float vertex[] = {
4059     /*                          bottom  top    right    left */
4060         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
4061          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
4062         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
4063          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
4064     };
4065
4066     DWORD shader_code_11[] = {
4067     0xffff0101,                                                             /* ps_1_1                     */
4068     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4069     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
4070     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
4071     0x0000ffff                                                              /* end                        */
4072     };
4073     DWORD shader_code_20[] = {
4074     0xffff0200,                                                             /* ps_2_0                     */
4075     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
4076     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4077     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
4078     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
4079     0x0000ffff                                                              /* end                        */
4080     };
4081
4082     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4083     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4084     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4085     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4086
4087     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4088     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4089     hr = IDirect3DDevice9_BeginScene(device);
4090     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4091     if(SUCCEEDED(hr))
4092     {
4093         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4094         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4095         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4096         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4097         hr = IDirect3DDevice9_EndScene(device);
4098         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4099     }
4100     color = getPixelColor(device, 63, 46);
4101     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4102     color = getPixelColor(device, 66, 46);
4103     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4104     color = getPixelColor(device, 63, 49);
4105     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4106     color = getPixelColor(device, 66, 49);
4107     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4108
4109     color = getPixelColor(device, 578, 46);
4110     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4111     color = getPixelColor(device, 575, 46);
4112     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4113     color = getPixelColor(device, 578, 49);
4114     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4115     color = getPixelColor(device, 575, 49);
4116     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4117
4118     color = getPixelColor(device, 63, 430);
4119     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4120     color = getPixelColor(device, 63, 433);
4121     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4122     color = getPixelColor(device, 66, 433);
4123     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4124     color = getPixelColor(device, 66, 430);
4125     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4126
4127     color = getPixelColor(device, 578, 430);
4128     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4129     color = getPixelColor(device, 578, 433);
4130     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4131     color = getPixelColor(device, 575, 433);
4132     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4133     color = getPixelColor(device, 575, 430);
4134     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4135
4136     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4137     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4138
4139     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4140     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4141     IDirect3DPixelShader9_Release(shader);
4142
4143     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4144     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4145     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4146     if(FAILED(hr)) {
4147         skip("Failed to create 2.0 test shader, most likely not supported\n");
4148         return;
4149     }
4150
4151     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4152     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4153     hr = IDirect3DDevice9_BeginScene(device);
4154     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4155     if(SUCCEEDED(hr))
4156     {
4157         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4158         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4159         hr = IDirect3DDevice9_EndScene(device);
4160         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4161     }
4162
4163     color = getPixelColor(device, 63, 46);
4164     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4165     color = getPixelColor(device, 66, 46);
4166     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4167     color = getPixelColor(device, 63, 49);
4168     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4169     color = getPixelColor(device, 66, 49);
4170     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4171
4172     color = getPixelColor(device, 578, 46);
4173     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4174     color = getPixelColor(device, 575, 46);
4175     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4176     color = getPixelColor(device, 578, 49);
4177     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4178     color = getPixelColor(device, 575, 49);
4179     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4180
4181     color = getPixelColor(device, 63, 430);
4182     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4183     color = getPixelColor(device, 63, 433);
4184     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4185     color = getPixelColor(device, 66, 433);
4186     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4187     color = getPixelColor(device, 66, 430);
4188     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4189
4190     color = getPixelColor(device, 578, 430);
4191     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4192     color = getPixelColor(device, 578, 433);
4193     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4194     color = getPixelColor(device, 575, 433);
4195     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4196     color = getPixelColor(device, 575, 430);
4197     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4198
4199     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4200     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4201
4202     /* Cleanup */
4203     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4204     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4205     IDirect3DPixelShader9_Release(shader);
4206 }
4207
4208 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4209 {
4210     IDirect3D9 *d3d9;
4211     HRESULT hr;
4212     IDirect3DTexture9 *texture;
4213     IDirect3DPixelShader9 *shader;
4214     IDirect3DPixelShader9 *shader2;
4215     D3DLOCKED_RECT lr;
4216     DWORD color;
4217     DWORD shader_code[] = {
4218         0xffff0101,                             /* ps_1_1       */
4219         0x00000042, 0xb00f0000,                 /* tex t0       */
4220         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
4221         0x0000ffff                              /* end          */
4222     };
4223     DWORD shader_code2[] = {
4224         0xffff0101,                             /* ps_1_1       */
4225         0x00000042, 0xb00f0000,                 /* tex t0       */
4226         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
4227         0x0000ffff                              /* end          */
4228     };
4229
4230     float quad[] = {
4231        -1.0,   -1.0,   0.1,     0.5,    0.5,
4232         1.0,   -1.0,   0.1,     0.5,    0.5,
4233        -1.0,    1.0,   0.1,     0.5,    0.5,
4234         1.0,    1.0,   0.1,     0.5,    0.5,
4235     };
4236
4237     memset(&lr, 0, sizeof(lr));
4238     IDirect3DDevice9_GetDirect3D(device, &d3d9);
4239     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4240                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4241     IDirect3D9_Release(d3d9);
4242     if(FAILED(hr)) {
4243         skip("No D3DFMT_X8L8V8U8 support\n");
4244         return;
4245     };
4246
4247     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4248     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4249
4250     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4251     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4252     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4253     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4254     *((DWORD *) lr.pBits) = 0x11ca3141;
4255     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4256     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4257
4258     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4259     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4260     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4261     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4262
4263     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4264     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4265     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4266     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4267     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4268     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4269
4270     hr = IDirect3DDevice9_BeginScene(device);
4271     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4272     if(SUCCEEDED(hr))
4273     {
4274         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4275         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4276
4277         hr = IDirect3DDevice9_EndScene(device);
4278         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4279     }
4280     color = getPixelColor(device, 578, 430);
4281     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4282        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4283     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4284     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4285
4286     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4287     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4288     hr = IDirect3DDevice9_BeginScene(device);
4289     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4290     if(SUCCEEDED(hr))
4291     {
4292         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4293         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4294
4295         hr = IDirect3DDevice9_EndScene(device);
4296         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4297     }
4298     color = getPixelColor(device, 578, 430);
4299     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4300     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4301     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4302
4303     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4304     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4305     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4306     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4307     IDirect3DPixelShader9_Release(shader);
4308     IDirect3DPixelShader9_Release(shader2);
4309     IDirect3DTexture9_Release(texture);
4310 }
4311
4312 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4313 {
4314     HRESULT hr;
4315     IDirect3D9 *d3d;
4316     IDirect3DTexture9 *texture = NULL;
4317     IDirect3DSurface9 *surface;
4318     DWORD color;
4319     const RECT r1 = {256, 256, 512, 512};
4320     const RECT r2 = {512, 256, 768, 512};
4321     const RECT r3 = {256, 512, 512, 768};
4322     const RECT r4 = {512, 512, 768, 768};
4323     unsigned int x, y;
4324     D3DLOCKED_RECT lr;
4325     memset(&lr, 0, sizeof(lr));
4326
4327     IDirect3DDevice9_GetDirect3D(device, &d3d);
4328     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4329        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4330         skip("No autogenmipmap support\n");
4331         IDirect3D9_Release(d3d);
4332         return;
4333     }
4334     IDirect3D9_Release(d3d);
4335
4336     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4337     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4338
4339     /* Make the mipmap big, so that a smaller mipmap is used
4340      */
4341     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4342                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4343     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4344
4345     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4346     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4347     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4348     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4349     for(y = 0; y < 1024; y++) {
4350         for(x = 0; x < 1024; x++) {
4351             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4352             POINT pt;
4353
4354             pt.x = x;
4355             pt.y = y;
4356             if(PtInRect(&r1, pt)) {
4357                 *dst = 0xffff0000;
4358             } else if(PtInRect(&r2, pt)) {
4359                 *dst = 0xff00ff00;
4360             } else if(PtInRect(&r3, pt)) {
4361                 *dst = 0xff0000ff;
4362             } else if(PtInRect(&r4, pt)) {
4363                 *dst = 0xff000000;
4364             } else {
4365                 *dst = 0xffffffff;
4366             }
4367         }
4368     }
4369     hr = IDirect3DSurface9_UnlockRect(surface);
4370     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4371     IDirect3DSurface9_Release(surface);
4372
4373     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4374     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4375     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4376     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4377
4378     hr = IDirect3DDevice9_BeginScene(device);
4379     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4380     if(SUCCEEDED(hr)) {
4381         const float quad[] =  {
4382            -0.5,   -0.5,    0.1,    0.0,    0.0,
4383            -0.5,    0.5,    0.1,    0.0,    1.0,
4384             0.5,   -0.5,    0.1,    1.0,    0.0,
4385             0.5,    0.5,    0.1,    1.0,    1.0
4386         };
4387
4388         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4389         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4390         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4391         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4392         hr = IDirect3DDevice9_EndScene(device);
4393         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4394     }
4395     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4396     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4397     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4398     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4399     IDirect3DTexture9_Release(texture);
4400
4401     color = getPixelColor(device, 200, 200);
4402     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4403     color = getPixelColor(device, 280, 200);
4404     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4405     color = getPixelColor(device, 360, 200);
4406     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4407     color = getPixelColor(device, 440, 200);
4408     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4409     color = getPixelColor(device, 200, 270);
4410     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4411     color = getPixelColor(device, 280, 270);
4412     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4413     color = getPixelColor(device, 360, 270);
4414     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4415     color = getPixelColor(device, 440, 270);
4416     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4417     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4418     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4419 }
4420
4421 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4422 {
4423     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4424     IDirect3DVertexDeclaration9 *decl;
4425     HRESULT hr;
4426     DWORD color;
4427     DWORD shader_code_11[] =  {
4428         0xfffe0101,                                         /* vs_1_1           */
4429         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4430         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4431         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4432         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4433         0x0000ffff                                          /* end              */
4434     };
4435     DWORD shader_code_11_2[] =  {
4436         0xfffe0101,                                         /* vs_1_1           */
4437         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4438         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4439         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4440         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4441         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4442         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4443         0x0000ffff                                          /* end              */
4444     };
4445     DWORD shader_code_20[] =  {
4446         0xfffe0200,                                         /* vs_2_0           */
4447         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4448         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4449         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4450         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4451         0x0000ffff                                          /* end              */
4452     };
4453     DWORD shader_code_20_2[] =  {
4454         0xfffe0200,                                         /* vs_2_0           */
4455         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4456         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4457         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4458         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4459         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4460         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4461         0x0000ffff                                          /* end              */
4462     };
4463     static const D3DVERTEXELEMENT9 decl_elements[] = {
4464         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4465         D3DDECL_END()
4466     };
4467     float quad1[] = {
4468         -1.0,   -1.0,   0.1,
4469          0.0,   -1.0,   0.1,
4470         -1.0,    0.0,   0.1,
4471          0.0,    0.0,   0.1
4472     };
4473     float quad2[] = {
4474          0.0,   -1.0,   0.1,
4475          1.0,   -1.0,   0.1,
4476          0.0,    0.0,   0.1,
4477          1.0,    0.0,   0.1
4478     };
4479     float quad3[] = {
4480          0.0,    0.0,   0.1,
4481          1.0,    0.0,   0.1,
4482          0.0,    1.0,   0.1,
4483          1.0,    1.0,   0.1
4484     };
4485     float quad4[] = {
4486         -1.0,    0.0,   0.1,
4487          0.0,    0.0,   0.1,
4488         -1.0,    1.0,   0.1,
4489          0.0,    1.0,   0.1
4490     };
4491     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4492     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4493
4494     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4495     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4496
4497     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4498     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4499     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4500     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4501     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4502     if(FAILED(hr)) shader_20 = NULL;
4503     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4504     if(FAILED(hr)) shader_20_2 = NULL;
4505     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4506     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4507
4508     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4509     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4510     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4511     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4512     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4513     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4514
4515     hr = IDirect3DDevice9_BeginScene(device);
4516     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4517     if(SUCCEEDED(hr))
4518     {
4519         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4520         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4521         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4522         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4523
4524         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4525         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4526         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4527         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4528
4529         if(shader_20) {
4530             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4531             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4532             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4533             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4534         }
4535
4536         if(shader_20_2) {
4537             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4538             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4539             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4540             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4541         }
4542
4543         hr = IDirect3DDevice9_EndScene(device);
4544         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4545     }
4546
4547     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4548     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4549     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4550     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4551
4552     color = getPixelColor(device, 160, 360);
4553     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4554        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4555     color = getPixelColor(device, 480, 360);
4556     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4557        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4558     if(shader_20) {
4559         color = getPixelColor(device, 160, 120);
4560         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4561            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4562     }
4563     if(shader_20_2) {
4564         color = getPixelColor(device, 480, 120);
4565         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4566            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4567     }
4568     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4569     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4570
4571     IDirect3DVertexDeclaration9_Release(decl);
4572     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4573     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4574     IDirect3DVertexShader9_Release(shader_11_2);
4575     IDirect3DVertexShader9_Release(shader_11);
4576 }
4577
4578 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4579 {
4580     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4581     HRESULT hr;
4582     DWORD color;
4583     DWORD shader_code_11[] =  {
4584         0xffff0101,                                         /* ps_1_1           */
4585         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4586         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4587         0x0000ffff                                          /* end              */
4588     };
4589     DWORD shader_code_12[] =  {
4590         0xffff0102,                                         /* ps_1_2           */
4591         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4592         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4593         0x0000ffff                                          /* end              */
4594     };
4595     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4596      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4597      * During development of this test, 1.3 shaders were verified too
4598      */
4599     DWORD shader_code_14[] =  {
4600         0xffff0104,                                         /* ps_1_4           */
4601         /* Try to make one constant local. It gets clamped too, although the binary contains
4602          * the bigger numbers
4603          */
4604         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4605         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4606         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4607         0x0000ffff                                          /* end              */
4608     };
4609     DWORD shader_code_20[] =  {
4610         0xffff0200,                                         /* ps_2_0           */
4611         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4612         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4613         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
4614         0x0000ffff                                          /* end              */
4615     };
4616     float quad1[] = {
4617         -1.0,   -1.0,   0.1,
4618          0.0,   -1.0,   0.1,
4619         -1.0,    0.0,   0.1,
4620          0.0,    0.0,   0.1
4621     };
4622     float quad2[] = {
4623          0.0,   -1.0,   0.1,
4624          1.0,   -1.0,   0.1,
4625          0.0,    0.0,   0.1,
4626          1.0,    0.0,   0.1
4627     };
4628     float quad3[] = {
4629          0.0,    0.0,   0.1,
4630          1.0,    0.0,   0.1,
4631          0.0,    1.0,   0.1,
4632          1.0,    1.0,   0.1
4633     };
4634     float quad4[] = {
4635         -1.0,    0.0,   0.1,
4636          0.0,    0.0,   0.1,
4637         -1.0,    1.0,   0.1,
4638          0.0,    1.0,   0.1
4639     };
4640     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4641     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4642
4643     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4644     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4645
4646     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4647     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4648     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4649     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4650     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4651     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4652     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4653     if(FAILED(hr)) shader_20 = NULL;
4654
4655     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4656     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4657     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4658     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4659     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4660     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4661
4662     hr = IDirect3DDevice9_BeginScene(device);
4663     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4664     if(SUCCEEDED(hr))
4665     {
4666         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4667         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4668         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4669         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4670
4671         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4672         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4673         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4674         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4675
4676         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4677         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4678         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4679         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4680
4681         if(shader_20) {
4682             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4683             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4684             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4685             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4686         }
4687
4688         hr = IDirect3DDevice9_EndScene(device);
4689         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4690     }
4691     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4692     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4693
4694     color = getPixelColor(device, 160, 360);
4695     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4696        "quad 1 has color %08x, expected 0x00808000\n", color);
4697     color = getPixelColor(device, 480, 360);
4698     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4699        "quad 2 has color %08x, expected 0x00808000\n", color);
4700     color = getPixelColor(device, 480, 120);
4701     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4702        "quad 3 has color %08x, expected 0x00808000\n", color);
4703     if(shader_20) {
4704         color = getPixelColor(device, 160, 120);
4705         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4706            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4707     }
4708     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4709     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4710
4711     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4712     IDirect3DPixelShader9_Release(shader_14);
4713     IDirect3DPixelShader9_Release(shader_12);
4714     IDirect3DPixelShader9_Release(shader_11);
4715 }
4716
4717 static void dp2add_ps_test(IDirect3DDevice9 *device)
4718 {
4719     IDirect3DPixelShader9 *shader_dp2add = NULL;
4720     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4721     HRESULT hr;
4722     DWORD color;
4723
4724     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
4725      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4726      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
4727      * r0 first.
4728      * The result here for the r,g,b components should be roughly 0.5:
4729      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4730     static const DWORD shader_code_dp2add[] =  {
4731         0xffff0200,                                                             /* ps_2_0                       */
4732         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
4733
4734         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
4735         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
4736
4737         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
4738         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
4739         0x0000ffff                                                              /* end                          */
4740     };
4741
4742     /* Test the _sat modifier, too.  Result here should be:
4743      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4744      *      _SAT: ==> 1.0
4745      *   ADD: (1.0 + -0.5) = 0.5
4746      */
4747     static const DWORD shader_code_dp2add_sat[] =  {
4748         0xffff0200,                                                             /* ps_2_0                           */
4749         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
4750
4751         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
4752         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
4753         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
4754
4755         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
4756         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
4757         0x0000ffff                                                              /* end                              */
4758     };
4759
4760     const float quad[] = {
4761         -1.0,   -1.0,   0.1,
4762          1.0,   -1.0,   0.1,
4763         -1.0,    1.0,   0.1,
4764          1.0,    1.0,   0.1
4765     };
4766
4767
4768     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
4769     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4770
4771     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
4772     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4773
4774     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
4775     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4776
4777     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4778     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4779
4780     if (shader_dp2add) {
4781
4782         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
4783         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4784
4785         hr = IDirect3DDevice9_BeginScene(device);
4786         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4787         if(SUCCEEDED(hr))
4788         {
4789             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4790             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4791
4792             hr = IDirect3DDevice9_EndScene(device);
4793             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4794         }
4795
4796         color = getPixelColor(device, 360, 240);
4797         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
4798                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4799
4800         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4801         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4802
4803         IDirect3DPixelShader9_Release(shader_dp2add);
4804     } else {
4805         skip("dp2add shader creation failed\n");
4806     }
4807
4808     if (shader_dp2add_sat) {
4809
4810         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
4811         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4812
4813         hr = IDirect3DDevice9_BeginScene(device);
4814         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4815         if(SUCCEEDED(hr))
4816         {
4817             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4818             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4819
4820             hr = IDirect3DDevice9_EndScene(device);
4821             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4822         }
4823
4824         color = getPixelColor(device, 360, 240);
4825         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
4826                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4827
4828         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4829         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4830
4831         IDirect3DPixelShader9_Release(shader_dp2add_sat);
4832     } else {
4833         skip("dp2add shader creation failed\n");
4834     }
4835
4836     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4837     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4838 }
4839
4840 static void cnd_test(IDirect3DDevice9 *device)
4841 {
4842     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
4843     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
4844     HRESULT hr;
4845     DWORD color;
4846     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
4847      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
4848      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
4849      */
4850     DWORD shader_code_11[] =  {
4851         0xffff0101,                                                                 /* ps_1_1               */
4852         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4853         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4854         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
4855         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
4856         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4857         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4858         0x0000ffff                                                                  /* end                  */
4859     };
4860     DWORD shader_code_12[] =  {
4861         0xffff0102,                                                                 /* ps_1_2               */
4862         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4863         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4864         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
4865         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
4866         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4867         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4868         0x0000ffff                                                                  /* end                  */
4869     };
4870     DWORD shader_code_13[] =  {
4871         0xffff0103,                                                                 /* ps_1_3               */
4872         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4873         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4874         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
4875         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
4876         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4877         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4878         0x0000ffff                                                                  /* end                  */
4879     };
4880     DWORD shader_code_14[] =  {
4881         0xffff0104,                                                                 /* ps_1_3               */
4882         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
4883         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
4884         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
4885         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
4886         0x0000ffff                                                                  /* end                  */
4887     };
4888
4889     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
4890      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
4891      * set by the compiler, it was added manually after compilation. It isn't always allowed,
4892      * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
4893      * native CreatePixelShader returns an error.
4894      *
4895      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
4896      * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
4897      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
4898      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
4899      */
4900     DWORD shader_code_11_coissue[] =  {
4901         0xffff0101,                                                             /* ps_1_1                   */
4902         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4903         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4904         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4905         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4906         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4907         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4908         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4909         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4910         /* 0x40000000 = D3DSI_COISSUE */
4911         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4912         0x0000ffff                                                              /* end                      */
4913     };
4914     DWORD shader_code_12_coissue[] =  {
4915         0xffff0102,                                                             /* ps_1_2                   */
4916         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4917         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4918         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4919         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4920         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4921         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4922         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4923         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4924         /* 0x40000000 = D3DSI_COISSUE */
4925         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4926         0x0000ffff                                                              /* end                      */
4927     };
4928     DWORD shader_code_13_coissue[] =  {
4929         0xffff0103,                                                             /* ps_1_3                   */
4930         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4931         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4932         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4933         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4934         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4935         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4936         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4937         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4938         /* 0x40000000 = D3DSI_COISSUE */
4939         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4940         0x0000ffff                                                              /* end                      */
4941     };
4942     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
4943      * compare against 0.5
4944      */
4945     DWORD shader_code_14_coissue[] =  {
4946         0xffff0104,                                                             /* ps_1_4                   */
4947         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
4948         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
4949         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
4950         /* 0x40000000 = D3DSI_COISSUE */
4951         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
4952         0x0000ffff                                                              /* end                      */
4953     };
4954     float quad1[] = {
4955         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
4956          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
4957         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
4958          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
4959     };
4960     float quad2[] = {
4961          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
4962          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
4963          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
4964          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
4965     };
4966     float quad3[] = {
4967          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
4968          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
4969          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
4970          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
4971     };
4972     float quad4[] = {
4973         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
4974          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
4975         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
4976          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
4977     };
4978     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
4979     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
4980     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
4981     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
4982
4983     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4984     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4985
4986     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4987     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4988     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4989     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4990     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
4991     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4992     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4993     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4994     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
4995     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4996     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
4997     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4998     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
4999     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5000     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5001     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5002
5003     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5004     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5005     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5006     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5007     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5008     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5009
5010     hr = IDirect3DDevice9_BeginScene(device);
5011     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5012     if(SUCCEEDED(hr))
5013     {
5014         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5015         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5016         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5017         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5018
5019         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5020         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5021         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5022         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5023
5024         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5025         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5026         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5027         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5028
5029         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5030         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5031         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5032         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5033
5034         hr = IDirect3DDevice9_EndScene(device);
5035         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5036     }
5037
5038     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5039     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5040
5041     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5042     color = getPixelColor(device, 158, 118);
5043     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5044     color = getPixelColor(device, 162, 118);
5045     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5046     color = getPixelColor(device, 158, 122);
5047     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5048     color = getPixelColor(device, 162, 122);
5049     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5050
5051     /* 1.1 shader. All 3 components get set, based on the .w comparison */
5052     color = getPixelColor(device, 158, 358);
5053     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5054     color = getPixelColor(device, 162, 358);
5055     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5056         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5057     color = getPixelColor(device, 158, 362);
5058     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5059     color = getPixelColor(device, 162, 362);
5060     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5061         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5062
5063     /* 1.2 shader */
5064     color = getPixelColor(device, 478, 358);
5065     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5066     color = getPixelColor(device, 482, 358);
5067     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5068         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5069     color = getPixelColor(device, 478, 362);
5070     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5071     color = getPixelColor(device, 482, 362);
5072     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5073         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5074
5075     /* 1.3 shader */
5076     color = getPixelColor(device, 478, 118);
5077     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5078     color = getPixelColor(device, 482, 118);
5079     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5080         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5081     color = getPixelColor(device, 478, 122);
5082     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5083     color = getPixelColor(device, 482, 122);
5084     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5085         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5086
5087     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5088     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5089
5090     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5091     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5092     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5093     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5094     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5095     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5096
5097     hr = IDirect3DDevice9_BeginScene(device);
5098     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5099     if(SUCCEEDED(hr))
5100     {
5101         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5102         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5103         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5104         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5105
5106         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5107         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5108         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5109         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5110
5111         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5112         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5113         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5114         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5115
5116         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5117         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5118         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5119         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5120
5121         hr = IDirect3DDevice9_EndScene(device);
5122         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5123     }
5124
5125     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5126     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5127
5128     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5129      * that we swapped the values in c1 and c2 to make the other tests return some color
5130      */
5131     color = getPixelColor(device, 158, 118);
5132     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5133     color = getPixelColor(device, 162, 118);
5134     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5135     color = getPixelColor(device, 158, 122);
5136     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5137     color = getPixelColor(device, 162, 122);
5138     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5139
5140     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
5141     color = getPixelColor(device, 158, 358);
5142     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5143         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5144     color = getPixelColor(device, 162, 358);
5145     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5146         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5147     color = getPixelColor(device, 158, 362);
5148     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5149         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5150     color = getPixelColor(device, 162, 362);
5151     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5152         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5153
5154     /* 1.2 shader */
5155     color = getPixelColor(device, 478, 358);
5156     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5157         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5158     color = getPixelColor(device, 482, 358);
5159     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5160         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5161     color = getPixelColor(device, 478, 362);
5162     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5163         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5164     color = getPixelColor(device, 482, 362);
5165     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5166         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5167
5168     /* 1.3 shader */
5169     color = getPixelColor(device, 478, 118);
5170     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5171         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5172     color = getPixelColor(device, 482, 118);
5173     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5174         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5175     color = getPixelColor(device, 478, 122);
5176     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5177         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5178     color = getPixelColor(device, 482, 122);
5179     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5180         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5181
5182     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5183     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5184
5185     IDirect3DPixelShader9_Release(shader_14_coissue);
5186     IDirect3DPixelShader9_Release(shader_13_coissue);
5187     IDirect3DPixelShader9_Release(shader_12_coissue);
5188     IDirect3DPixelShader9_Release(shader_11_coissue);
5189     IDirect3DPixelShader9_Release(shader_14);
5190     IDirect3DPixelShader9_Release(shader_13);
5191     IDirect3DPixelShader9_Release(shader_12);
5192     IDirect3DPixelShader9_Release(shader_11);
5193 }
5194
5195 static void nested_loop_test(IDirect3DDevice9 *device) {
5196     const DWORD shader_code[] = {
5197         0xffff0300,                                                             /* ps_3_0               */
5198         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
5199         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5200         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
5201         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
5202         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5203         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5204         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
5205         0x0000001d,                                                             /* endloop              */
5206         0x0000001d,                                                             /* endloop              */
5207         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
5208         0x0000ffff                                                              /* end                  */
5209     };
5210     IDirect3DPixelShader9 *shader;
5211     HRESULT hr;
5212     DWORD color;
5213     const float quad[] = {
5214         -1.0,   -1.0,   0.1,
5215          1.0,   -1.0,   0.1,
5216         -1.0,    1.0,   0.1,
5217          1.0,    1.0,   0.1
5218     };
5219
5220     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5221     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5222     hr = IDirect3DDevice9_SetPixelShader(device, shader);
5223     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5224     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5225     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5226     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5227     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5228
5229     hr = IDirect3DDevice9_BeginScene(device);
5230     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5231     if(SUCCEEDED(hr))
5232     {
5233         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5234         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5235         hr = IDirect3DDevice9_EndScene(device);
5236         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5237     }
5238
5239     color = getPixelColor(device, 360, 240);
5240     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5241        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5242
5243     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5244     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5245
5246     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5247     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5248     IDirect3DPixelShader9_Release(shader);
5249 }
5250
5251 struct varying_test_struct
5252 {
5253     const DWORD             *shader_code;
5254     IDirect3DPixelShader9   *shader;
5255     DWORD                   color, color_rhw;
5256     const char              *name;
5257     BOOL                    todo, todo_rhw;
5258 };
5259
5260 struct hugeVertex
5261 {
5262     float pos_x,        pos_y,      pos_z,      rhw;
5263     float weight_1,     weight_2,   weight_3,   weight_4;
5264     float index_1,      index_2,    index_3,    index_4;
5265     float normal_1,     normal_2,   normal_3,   normal_4;
5266     float fog_1,        fog_2,      fog_3,      fog_4;
5267     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
5268     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
5269     float binormal_1,   binormal_2, binormal_3, binormal_4;
5270     float depth_1,      depth_2,    depth_3,    depth_4;
5271     DWORD diffuse, specular;
5272 };
5273
5274 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5275     /* dcl_position: fails to compile */
5276     const DWORD blendweight_code[] = {
5277         0xffff0300,                             /* ps_3_0                   */
5278         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
5279         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5280         0x0000ffff                              /* end                      */
5281     };
5282     const DWORD blendindices_code[] = {
5283         0xffff0300,                             /* ps_3_0                   */
5284         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
5285         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5286         0x0000ffff                              /* end                      */
5287     };
5288     const DWORD normal_code[] = {
5289         0xffff0300,                             /* ps_3_0                   */
5290         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
5291         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5292         0x0000ffff                              /* end                      */
5293     };
5294     /* psize: fails? */
5295     const DWORD texcoord0_code[] = {
5296         0xffff0300,                             /* ps_3_0                   */
5297         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
5298         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5299         0x0000ffff                              /* end                      */
5300     };
5301     const DWORD tangent_code[] = {
5302         0xffff0300,                             /* ps_3_0                   */
5303         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
5304         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5305         0x0000ffff                              /* end                      */
5306     };
5307     const DWORD binormal_code[] = {
5308         0xffff0300,                             /* ps_3_0                   */
5309         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
5310         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5311         0x0000ffff                              /* end                      */
5312     };
5313     /* tessfactor: fails */
5314     /* positiont: fails */
5315     const DWORD color_code[] = {
5316         0xffff0300,                             /* ps_3_0                   */
5317         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
5318         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5319         0x0000ffff                              /* end                      */
5320     };
5321     const DWORD fog_code[] = {
5322         0xffff0300,                             /* ps_3_0                   */
5323         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
5324         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5325         0x0000ffff                              /* end                      */
5326     };
5327     const DWORD depth_code[] = {
5328         0xffff0300,                             /* ps_3_0                   */
5329         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
5330         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5331         0x0000ffff                              /* end                      */
5332     };
5333     const DWORD specular_code[] = {
5334         0xffff0300,                             /* ps_3_0                   */
5335         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
5336         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5337         0x0000ffff                              /* end                      */
5338     };
5339     /* sample: fails */
5340
5341     struct varying_test_struct tests[] = {
5342        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
5343        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
5344        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
5345        /* Why does dx not forward the texcoord? */
5346        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
5347        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
5348        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
5349        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
5350        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
5351        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
5352        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
5353     };
5354     /* Declare a monster vertex type :-) */
5355     static const D3DVERTEXELEMENT9 decl_elements[] = {
5356         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5357         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5358         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5359         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5360         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5361         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5362         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5363         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5364         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5365         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5366         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5367         D3DDECL_END()
5368     };
5369     static const D3DVERTEXELEMENT9 decl_elements2[] = {
5370         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
5371         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5372         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5373         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5374         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5375         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5376         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5377         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5378         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5379         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5380         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5381         D3DDECL_END()
5382     };
5383     struct hugeVertex data[4] = {
5384         {
5385             -1.0,   -1.0,   0.1,    1.0,
5386              0.1,    0.1,   0.1,    0.1,
5387              0.2,    0.2,   0.2,    0.2,
5388              0.3,    0.3,   0.3,    0.3,
5389              0.4,    0.4,   0.4,    0.4,
5390              0.50,   0.55,  0.55,   0.55,
5391              0.6,    0.6,   0.6,    0.7,
5392              0.7,    0.7,   0.7,    0.6,
5393              0.8,    0.8,   0.8,    0.8,
5394              0xe6e6e6e6, /* 0.9 * 256 */
5395              0x224488ff  /* Nothing special */
5396         },
5397         {
5398              1.0,   -1.0,   0.1,    1.0,
5399              0.1,    0.1,   0.1,    0.1,
5400              0.2,    0.2,   0.2,    0.2,
5401              0.3,    0.3,   0.3,    0.3,
5402              0.4,    0.4,   0.4,    0.4,
5403              0.50,   0.55,  0.55,   0.55,
5404              0.6,    0.6,   0.6,    0.7,
5405              0.7,    0.7,   0.7,    0.6,
5406              0.8,    0.8,   0.8,    0.8,
5407              0xe6e6e6e6, /* 0.9 * 256 */
5408              0x224488ff /* Nothing special */
5409         },
5410         {
5411             -1.0,    1.0,   0.1,    1.0,
5412              0.1,    0.1,   0.1,    0.1,
5413              0.2,    0.2,   0.2,    0.2,
5414              0.3,    0.3,   0.3,    0.3,
5415              0.4,    0.4,   0.4,    0.4,
5416              0.50,   0.55,  0.55,   0.55,
5417              0.6,    0.6,   0.6,    0.7,
5418              0.7,    0.7,   0.7,    0.6,
5419              0.8,    0.8,   0.8,    0.8,
5420              0xe6e6e6e6, /* 0.9 * 256 */
5421              0x224488ff /* Nothing special */
5422         },
5423         {
5424              1.0,    1.0,   0.1,    1.0,
5425              0.1,    0.1,   0.1,    0.1,
5426              0.2,    0.2,   0.2,    0.2,
5427              0.3,    0.3,   0.3,    0.3,
5428              0.4,    0.4,   0.4,    0.4,
5429              0.50,   0.55,  0.55,   0.55,
5430              0.6,    0.6,   0.6,    0.7,
5431              0.7,    0.7,   0.7,    0.6,
5432              0.8,    0.8,   0.8,    0.8,
5433              0xe6e6e6e6, /* 0.9 * 256 */
5434              0x224488ff /* Nothing special */
5435         },
5436     };
5437     struct hugeVertex data2[4];
5438     IDirect3DVertexDeclaration9 *decl;
5439     IDirect3DVertexDeclaration9 *decl2;
5440     HRESULT hr;
5441     unsigned int i;
5442     DWORD color, r, g, b, r_e, g_e, b_e;
5443     BOOL drawok;
5444
5445     memcpy(data2, data, sizeof(data2));
5446     data2[0].pos_x = 0;     data2[0].pos_y = 0;
5447     data2[1].pos_x = 640;   data2[1].pos_y = 0;
5448     data2[2].pos_x = 0;     data2[2].pos_y = 480;
5449     data2[3].pos_x = 640;   data2[3].pos_y = 480;
5450
5451     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5452     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5453     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5454     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5455     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5456     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5457
5458     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5459     {
5460         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5461         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5462            tests[i].name, hr);
5463     }
5464
5465     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5466     {
5467         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5468         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5469
5470         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5471         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5472
5473         hr = IDirect3DDevice9_BeginScene(device);
5474         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5475         drawok = FALSE;
5476         if(SUCCEEDED(hr))
5477         {
5478             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5479             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5480             drawok = SUCCEEDED(hr);
5481             hr = IDirect3DDevice9_EndScene(device);
5482             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5483         }
5484
5485         /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5486          * the failure and do not check the color if it failed
5487          */
5488         if(!drawok) {
5489             continue;
5490         }
5491
5492         color = getPixelColor(device, 360, 240);
5493         r = color & 0x00ff0000 >> 16;
5494         g = color & 0x0000ff00 >>  8;
5495         b = color & 0x000000ff;
5496         r_e = tests[i].color & 0x00ff0000 >> 16;
5497         g_e = tests[i].color & 0x0000ff00 >>  8;
5498         b_e = tests[i].color & 0x000000ff;
5499
5500         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5501         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5502
5503         if(tests[i].todo) {
5504             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5505                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5506                          tests[i].name, color, tests[i].color);
5507         } else {
5508             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5509                "Test %s returned color 0x%08x, expected 0x%08x\n",
5510                tests[i].name, color, tests[i].color);
5511         }
5512     }
5513
5514     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5515     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5516     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5517     {
5518         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5519         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5520
5521         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5522         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5523
5524         hr = IDirect3DDevice9_BeginScene(device);
5525         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5526         if(SUCCEEDED(hr))
5527         {
5528             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5529             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5530             hr = IDirect3DDevice9_EndScene(device);
5531             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5532         }
5533
5534         color = getPixelColor(device, 360, 240);
5535         r = color & 0x00ff0000 >> 16;
5536         g = color & 0x0000ff00 >>  8;
5537         b = color & 0x000000ff;
5538         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5539         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
5540         b_e = tests[i].color_rhw & 0x000000ff;
5541
5542         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5543         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5544
5545         if(tests[i].todo_rhw) {
5546             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5547              * pipeline
5548              */
5549             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5550                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5551                          tests[i].name, color, tests[i].color_rhw);
5552         } else {
5553             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5554                "Test %s returned color 0x%08x, expected 0x%08x\n",
5555                tests[i].name, color, tests[i].color_rhw);
5556         }
5557     }
5558
5559     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5560     {
5561         IDirect3DPixelShader9_Release(tests[i].shader);
5562     }
5563
5564     IDirect3DVertexDeclaration9_Release(decl2);
5565     IDirect3DVertexDeclaration9_Release(decl);
5566 }
5567
5568 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5569     static const DWORD ps_code[] = {
5570     0xffff0300,                                                             /* ps_3_0                       */
5571     0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0          */
5572     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5573     0x0200001f, 0x8001000a, 0x900f0003,                                     /* dcl_color1 v3                */
5574     0x0200001f, 0x8000000b, 0x900f0004,                                     /* dcl_fog v4                   */
5575     0x0200001f, 0x80030005, 0x900f0005,                                     /* dcl_texcoord3 v5             */
5576     0x0200001f, 0x80000003, 0x900f0006,                                     /* dcl_normal v6                */
5577     0x0200001f, 0x80000006, 0x900f0007,                                     /* dcl_tangent v7               */
5578     0x0200001f, 0x80000001, 0x900f0008,                                     /* dcl_blendweight v8           */
5579     0x0200001f, 0x8000000c, 0x900f0009,                                     /* dcl_depth v9                 */
5580
5581     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5582     0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0                  */
5583     0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800,             /* add r0, r0, v0[aL]           */
5584     0x0000001d,                                                             /* endloop                      */
5585     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5586     0x0000ffff                                                              /* end                          */
5587     };
5588     static const DWORD vs_1_code[] = {
5589     0xfffe0101,                                                             /* vs_1_1                       */
5590     0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5591     0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5592     0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5593     0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5594     0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5595     0x00000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5596     0x00000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5597     0x00000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5598     0x00000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5599     0x00000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5600     0x00000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5601     0x00000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5602     0x00000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5603     0x00000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5604     0x00000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5605     0x00000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5606     0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5607     0x0000ffff
5608     };
5609     DWORD vs_2_code[] = {
5610     0xfffe0200,                                                             /* vs_2_0                       */
5611     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5612     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5613     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5614     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5615     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5616     0x02000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5617     0x02000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5618     0x02000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5619     0x02000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5620     0x02000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5621     0x02000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5622     0x02000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5623     0x02000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5624     0x02000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5625     0x02000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5626     0x02000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5627     0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5628     0x0000ffff                                                              /* end                          */
5629     };
5630     /* TODO: Define normal, tangent, blendweight and depth here */
5631     static const DWORD vs_3_code[] = {
5632     0xfffe0300,                                                             /* vs_3_0                       */
5633     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5634     0x0200001f, 0x8001000a, 0xe00f0009,                                     /* dcl_color1 o9                */
5635     0x0200001f, 0x8000000b, 0xe00f0002,                                     /* dcl_fog o2                   */
5636     0x0200001f, 0x80030005, 0xe00f0005,                                     /* dcl_texcoord3 o5             */
5637     0x0200001f, 0x80000000, 0xe00f000b,                                     /* dcl_position o11             */
5638     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5639     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5640     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5641     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5642     0x02000001, 0xe00f0009, 0xa0e40000,                                     /* mov o9, c0                   */
5643     0x02000001, 0xe00f0002, 0xa0e40001,                                     /* mov o2, c1                   */
5644     0x02000001, 0xe00f0005, 0xa0e40002,                                     /* mov o5, c2                   */
5645     0x02000001, 0xe00f000b, 0x90e40000,                                     /* mov o11, v0                  */
5646     0x0000ffff                                                              /* end                          */
5647     };
5648     float quad1[] =  {
5649         -1.0,   -1.0,   0.1,
5650          0.0,   -1.0,   0.1,
5651         -1.0,    0.0,   0.1,
5652          0.0,    0.0,   0.1
5653     };
5654     float quad2[] =  {
5655          0.0,   -1.0,   0.1,
5656          1.0,   -1.0,   0.1,
5657          0.0,    0.0,   0.1,
5658          1.0,    0.0,   0.1
5659     };
5660     float quad3[] =  {
5661         -1.0,    0.0,   0.1,
5662          0.0,    0.0,   0.1,
5663         -1.0,    1.0,   0.1,
5664          0.0,    1.0,   0.1
5665     };
5666
5667     HRESULT hr;
5668     DWORD color;
5669     IDirect3DPixelShader9 *pixelshader = NULL;
5670     IDirect3DVertexShader9 *vs_1_shader = NULL;
5671     IDirect3DVertexShader9 *vs_2_shader = NULL;
5672     IDirect3DVertexShader9 *vs_3_shader = NULL;
5673
5674     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5675     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5676
5677     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5678     ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %08x\n", hr);
5679     hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5680     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5681     hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5682     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5683     hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5684     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5685     hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5686     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5687     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5688
5689     hr = IDirect3DDevice9_BeginScene(device);
5690     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5691     if(SUCCEEDED(hr))
5692     {
5693         hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5694         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5695         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5696         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5697
5698         hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5699         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5700         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5701         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5702
5703         hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5704         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5705         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5706         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5707
5708         hr = IDirect3DDevice9_EndScene(device);
5709         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5710     }
5711
5712     color = getPixelColor(device, 160, 120);
5713     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x1a, 0x34, 0x67), 1),
5714        "vs_3_0 returned color 0x%08x, expected 0x00193366\n", color);
5715     /* Accept two ways of oFog handling:
5716      *
5717      * oFog is supposed to be a scalar. The pixel shader declares a vec4 oFog input and reads all components.
5718      * The vertex shader writes oFog without a writemask. There are two ways windows drivers deal with this:
5719      *
5720      * 1) Keep oFog a scalar, and assign v4 = {oFog, 0, 0, 0}. oFog = 0x33, so the result color is 004d0067.
5721      *    This happens with software vertex processing and on Intel cards
5722      *
5723      * 2) Make oFog a vec4, and assign v4 = {oFog.x, oFog.y, oFog.z, oFog.w}. This way the result color is
5724      *    0x004d339a. This happens on Nvidia Geforce 6+ cards
5725      */
5726     color = getPixelColor(device, 160, 360);
5727     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5728        color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5729        "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5730     color = getPixelColor(device, 480, 360);
5731     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5732        color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5733        "vs_2_0 returned color 0x%08x, expected 0x004d0067 or 0x004d33a0\n", color);
5734
5735     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5736     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5737
5738     /* cleanup */
5739     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5740     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5741     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5742     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5743     if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5744     if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5745     if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5746     if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5747 }
5748
5749 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5750     static const DWORD vs_code[] = {
5751     0xfffe0300,                                                             /* vs_3_0                       */
5752     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5753     0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0              */
5754     0x0200001f, 0x8000000a, 0xe00f0001,                                     /* dcl_color0 o1                */
5755     0x0200001f, 0x80000005, 0xe00f0002,                                     /* dcl_texcoord0 o2             */
5756     0x0200001f, 0x8000000b, 0xe00f0003,                                     /* dcl_fog o3                   */
5757     0x0200001f, 0x80000003, 0xe00f0004,                                     /* dcl_normal o4                */
5758     0x0200001f, 0x8000000c, 0xe00f0005,                                     /* dcl_depth o5                 */
5759     0x0200001f, 0x80000006, 0xe00f0006,                                     /* dcl_tangent o6               */
5760     0x0200001f, 0x80000001, 0xe00f0007,                                     /* dcl_blendweight o7           */
5761     0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0   */
5762     0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0   */
5763     0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0   */
5764     0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0   */
5765
5766     0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                   */
5767     0x02000001, 0xe00f0001, 0xa0e40001,                                     /* mov o1, c1                   */
5768     0x02000001, 0xe00f0002, 0xa0e40002,                                     /* mov o2, c2                   */
5769     0x02000001, 0xe00f0003, 0xa0e40003,                                     /* mov o3, c3                   */
5770     0x02000001, 0xe00f0004, 0xa0e40000,                                     /* mov o4, c0                   */
5771     0x02000001, 0xe00f0005, 0xa0e40000,                                     /* mov o5, c0                   */
5772     0x02000001, 0xe00f0006, 0xa0e40000,                                     /* mov o6, c0                   */
5773     0x02000001, 0xe00f0007, 0xa0e40000,                                     /* mov o7, c0                   */
5774     0x0000ffff                                                              /* end                          */
5775     };
5776     static const DWORD ps_1_code[] = {
5777     0xffff0104,                                                             /* ps_1_4                       */
5778     0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5779     0x00000040, 0x80070001, 0xb0e40000,                                     /* texcrd r1.xyz, t0            */
5780     0x00000001, 0x80080001, 0xa0ff0000,                                     /* mov r1.a, c0.a               */
5781     0x00000002, 0x800f0000, 0x90e40000, 0x80e40001,                         /* add r0, v0, r1               */
5782     0x0000ffff                                                              /* end                          */
5783     };
5784     static const DWORD ps_2_code[] = {
5785     0xffff0200,                                                             /* ps_2_0                       */
5786     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
5787     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl v0                       */
5788     0x0200001f, 0x80000000, 0x900f0001,                                     /* dcl v1                       */
5789
5790     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
5791     0x03000002, 0x800f0000, 0x80e40000,0xb0e40000,                          /* add r0, r0, t0               */
5792     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5793     0x0000ffff                                                              /* end                          */
5794     };
5795     static const DWORD ps_3_code[] = {
5796     0xffff0300,                                                             /* ps_3_0                       */
5797     0x0200001f, 0x80000005, 0x900f0000,                                     /* dcl_texcoord0 v0             */
5798     0x0200001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
5799     0x0200001f, 0x8000000b, 0x900f0002,                                     /* dcl_fog v2                   */
5800
5801     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
5802     0x03000002, 0x800f0000, 0x80e40000, 0x90e40001,                         /* add r0, r0, v1               */
5803     0x03000002, 0x800f0000, 0x80e40000, 0x90e40002,                         /* mov r0, r0, v2               */
5804     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5805     0x0000ffff                                                              /* end                          */
5806     };
5807
5808     float quad1[] =  {
5809         -1.0,   -1.0,   0.1,
5810          0.0,   -1.0,   0.1,
5811         -1.0,    0.0,   0.1,
5812          0.0,    0.0,   0.1
5813     };
5814     float quad2[] =  {
5815          0.0,   -1.0,   0.1,
5816          1.0,   -1.0,   0.1,
5817          0.0,    0.0,   0.1,
5818          1.0,    0.0,   0.1
5819     };
5820     float quad3[] =  {
5821         -1.0,    0.0,   0.1,
5822          0.0,    0.0,   0.1,
5823         -1.0,    1.0,   0.1,
5824          0.0,    1.0,   0.1
5825     };
5826     float quad4[] =  {
5827          0.0,    0.0,   0.1,
5828          1.0,    0.0,   0.1,
5829          0.0,    1.0,   0.1,
5830          1.0,    1.0,   0.1
5831     };
5832
5833     HRESULT hr;
5834     DWORD color;
5835     IDirect3DVertexShader9 *vertexshader = NULL;
5836     IDirect3DPixelShader9 *ps_1_shader = NULL;
5837     IDirect3DPixelShader9 *ps_2_shader = NULL;
5838     IDirect3DPixelShader9 *ps_3_shader = NULL;
5839     IDirect3DTexture9 *texture = NULL;
5840     D3DLOCKED_RECT lr;
5841     unsigned int x, y;
5842
5843     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5844     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5845
5846     hr = IDirect3DDevice9_CreateTexture(device, 512,  512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
5847     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5848     if(FAILED(hr)) {
5849         skip("D3DFMT_A16B16G16R16 textures not supported\n");
5850         return;
5851     }
5852     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5853     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
5854     for(y = 0; y < 512; y++) {
5855         for(x = 0; x < 512; x++) {
5856             double r_f = (double) x / (double) 512;
5857             double g_f = (double) y / (double) 512;
5858             unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
5859             unsigned short r = (unsigned short) (r_f * 65535.0);
5860             unsigned short g = (unsigned short) (g_f * 65535.0);
5861             dst[0] = r;
5862             dst[1] = g;
5863             dst[2] = 0;
5864             dst[3] = 65535;
5865         }
5866     }
5867     hr = IDirect3DTexture9_UnlockRect(texture, 0);
5868     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
5869
5870     hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
5871     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5872     hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
5873     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5874     hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
5875     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5876     hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
5877     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5878     hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
5879     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5880     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5881
5882     hr = IDirect3DDevice9_BeginScene(device);
5883     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5884     if(SUCCEEDED(hr))
5885     {
5886         hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
5887         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5888         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5889         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5890
5891         hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
5892         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5893         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5894         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5895
5896         hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
5897         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5898         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5899         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5900
5901         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5902         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5903         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5904         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5905         hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5906         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
5907         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
5908         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
5909         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5910         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
5911         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
5912         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
5913         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5914         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5915
5916         hr = IDirect3DDevice9_EndScene(device);
5917         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5918     }
5919
5920     color = getPixelColor(device, 160, 120);
5921     ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
5922        (color & 0x0000ff00) == 0x0000ff00 &&
5923        (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
5924        "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
5925     color = getPixelColor(device, 160, 360);
5926     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5927        (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
5928        (color & 0x000000ff) == 0x00000000,
5929        "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
5930     color = getPixelColor(device, 480, 360);
5931     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5932        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5933        (color & 0x000000ff) == 0x00000000,
5934        "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
5935     color = getPixelColor(device, 480, 160);
5936     ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
5937        (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5938        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5939        (color & 0x000000ff) == 0x00000000),
5940        "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
5941
5942     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5943     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5944
5945     /* cleanup */
5946     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5947     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5948     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5949     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5950     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5951     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5952     if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
5953     if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
5954     if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
5955     if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
5956     if(texture) IDirect3DTexture9_Release(texture);
5957 }
5958
5959 static void test_compare_instructions(IDirect3DDevice9 *device)
5960 {
5961     DWORD shader_sge_vec_code[] = {
5962         0xfffe0101,                                         /* vs_1_1                   */
5963         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5964         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5965         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5966         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
5967         0x0000ffff                                          /* end                      */
5968     };
5969     DWORD shader_slt_vec_code[] = {
5970         0xfffe0101,                                         /* vs_1_1                   */
5971         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5972         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5973         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5974         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
5975         0x0000ffff                                          /* end                      */
5976     };
5977     DWORD shader_sge_scalar_code[] = {
5978         0xfffe0101,                                         /* vs_1_1                   */
5979         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5980         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5981         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5982         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
5983         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
5984         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
5985         0x0000ffff                                          /* end                      */
5986     };
5987     DWORD shader_slt_scalar_code[] = {
5988         0xfffe0101,                                         /* vs_1_1                   */
5989         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5990         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5991         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5992         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
5993         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
5994         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
5995         0x0000ffff                                          /* end                      */
5996     };
5997     IDirect3DVertexShader9 *shader_sge_vec;
5998     IDirect3DVertexShader9 *shader_slt_vec;
5999     IDirect3DVertexShader9 *shader_sge_scalar;
6000     IDirect3DVertexShader9 *shader_slt_scalar;
6001     HRESULT hr, color;
6002     float quad1[] =  {
6003         -1.0,   -1.0,   0.1,
6004          0.0,   -1.0,   0.1,
6005         -1.0,    0.0,   0.1,
6006          0.0,    0.0,   0.1
6007     };
6008     float quad2[] =  {
6009          0.0,   -1.0,   0.1,
6010          1.0,   -1.0,   0.1,
6011          0.0,    0.0,   0.1,
6012          1.0,    0.0,   0.1
6013     };
6014     float quad3[] =  {
6015         -1.0,    0.0,   0.1,
6016          0.0,    0.0,   0.1,
6017         -1.0,    1.0,   0.1,
6018          0.0,    1.0,   0.1
6019     };
6020     float quad4[] =  {
6021          0.0,    0.0,   0.1,
6022          1.0,    0.0,   0.1,
6023          0.0,    1.0,   0.1,
6024          1.0,    1.0,   0.1
6025     };
6026     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
6027     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
6028
6029     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6030     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6031
6032     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
6033     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6034     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
6035     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6036     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
6037     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6038     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
6039     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6040     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6041     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6042     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
6043     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6044     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6045     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
6046
6047     hr = IDirect3DDevice9_BeginScene(device);
6048     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6049     if(SUCCEEDED(hr))
6050     {
6051         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
6052         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6053         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6054         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6055
6056         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
6057         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6058         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
6059         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6060
6061         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
6062         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6063         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6064         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6065
6066         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6067         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6068
6069         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
6070         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6071         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6072         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6073
6074         hr = IDirect3DDevice9_EndScene(device);
6075         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6076     }
6077
6078     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6079     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6080
6081     color = getPixelColor(device, 160, 360);
6082     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
6083     color = getPixelColor(device, 480, 360);
6084     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
6085     color = getPixelColor(device, 160, 120);
6086     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
6087     color = getPixelColor(device, 480, 160);
6088     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
6089
6090     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6091     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6092
6093     IDirect3DVertexShader9_Release(shader_sge_vec);
6094     IDirect3DVertexShader9_Release(shader_slt_vec);
6095     IDirect3DVertexShader9_Release(shader_sge_scalar);
6096     IDirect3DVertexShader9_Release(shader_slt_scalar);
6097 }
6098
6099 static void test_vshader_input(IDirect3DDevice9 *device)
6100 {
6101     DWORD swapped_shader_code_3[] = {
6102         0xfffe0300,                                         /* vs_3_0               */
6103         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6104         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6105         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6106         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6107         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6108         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6109         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6110         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6111         0x0000ffff                                          /* end                  */
6112     };
6113     DWORD swapped_shader_code_1[] = {
6114         0xfffe0101,                                         /* vs_1_1               */
6115         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6116         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6117         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6118         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6119         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6120         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6121         0x0000ffff                                          /* end                  */
6122     };
6123     DWORD swapped_shader_code_2[] = {
6124         0xfffe0200,                                         /* vs_2_0               */
6125         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6126         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6127         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6128         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6129         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6130         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6131         0x0000ffff                                          /* end                  */
6132     };
6133     DWORD texcoord_color_shader_code_3[] = {
6134         0xfffe0300,                                         /* vs_3_0               */
6135         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6136         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6137         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6138         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6139         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6140         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
6141         0x0000ffff                                          /* end                  */
6142     };
6143     DWORD texcoord_color_shader_code_2[] = {
6144         0xfffe0200,                                         /* vs_2_0               */
6145         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6146         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6147         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6148         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6149         0x0000ffff                                          /* end                  */
6150     };
6151     DWORD texcoord_color_shader_code_1[] = {
6152         0xfffe0101,                                         /* vs_1_1               */
6153         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6154         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6155         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6156         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6157         0x0000ffff                                          /* end                  */
6158     };
6159     DWORD color_color_shader_code_3[] = {
6160         0xfffe0300,                                         /* vs_3_0               */
6161         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6162         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6163         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6164         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6165         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6166         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
6167         0x0000ffff                                          /* end                  */
6168     };
6169     DWORD color_color_shader_code_2[] = {
6170         0xfffe0200,                                         /* vs_2_0               */
6171         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6172         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6173         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6174         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6175         0x0000ffff                                          /* end                  */
6176     };
6177     DWORD color_color_shader_code_1[] = {
6178         0xfffe0101,                                         /* vs_1_1               */
6179         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6180         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6181         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6182         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6183         0x0000ffff                                          /* end                  */
6184     };
6185     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6186     HRESULT hr;
6187     DWORD color;
6188     float quad1[] =  {
6189         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6190          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6191         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6192          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6193     };
6194     float quad2[] =  {
6195          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6196          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6197          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6198          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6199     };
6200     float quad3[] =  {
6201         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
6202          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
6203         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
6204          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6205     };
6206     float quad4[] =  {
6207          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6208          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6209          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6210          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6211     };
6212     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6213         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6214         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6215         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6216         D3DDECL_END()
6217     };
6218     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6219         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6220         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6221         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6222         D3DDECL_END()
6223     };
6224     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6225         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6226         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6227         D3DDECL_END()
6228     };
6229     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6230         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6231         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6232         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
6233         D3DDECL_END()
6234     };
6235     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6236         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6237         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6238         D3DDECL_END()
6239     };
6240     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6241         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6242         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6243         D3DDECL_END()
6244     };
6245     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6246         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6247         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6248         D3DDECL_END()
6249     };
6250     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6251         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6252         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6253         D3DDECL_END()
6254     };
6255     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6256     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6257     unsigned int i;
6258     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6259     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6260
6261     struct vertex quad1_color[] =  {
6262        {-1.0,   -1.0,   0.1,    0x00ff8040},
6263        { 0.0,   -1.0,   0.1,    0x00ff8040},
6264        {-1.0,    0.0,   0.1,    0x00ff8040},
6265        { 0.0,    0.0,   0.1,    0x00ff8040}
6266     };
6267     struct vertex quad2_color[] =  {
6268        { 0.0,   -1.0,   0.1,    0x00ff8040},
6269        { 1.0,   -1.0,   0.1,    0x00ff8040},
6270        { 0.0,    0.0,   0.1,    0x00ff8040},
6271        { 1.0,    0.0,   0.1,    0x00ff8040}
6272     };
6273     struct vertex quad3_color[] =  {
6274        {-1.0,    0.0,   0.1,    0x00ff8040},
6275        { 0.0,    0.0,   0.1,    0x00ff8040},
6276        {-1.0,    1.0,   0.1,    0x00ff8040},
6277        { 0.0,    1.0,   0.1,    0x00ff8040}
6278     };
6279     float quad4_color[] =  {
6280          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6281          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6282          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6283          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6284     };
6285
6286     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6287     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6288     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6289     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6290     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6291     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6292     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6293     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6294
6295     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6296     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6297     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6298     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6299     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6300     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6301     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6302     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6303
6304     for(i = 1; i <= 3; i++) {
6305         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6306         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6307         if(i == 3) {
6308             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6309             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6310         } else if(i == 2){
6311             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6312             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6313         } else if(i == 1) {
6314             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6315             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6316         }
6317
6318         hr = IDirect3DDevice9_BeginScene(device);
6319         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6320         if(SUCCEEDED(hr))
6321         {
6322             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6323             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6324
6325             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6326             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6327             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6328             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6329
6330             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6331             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6332             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6333             if(i == 3 || i == 2) {
6334                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6335             } else if(i == 1) {
6336                 /* Succeeds or fails, depending on SW or HW vertex processing */
6337                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6338             }
6339
6340             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6341             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6342             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6343             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6344
6345             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6346             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6347             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6348             if(i == 3 || i == 2) {
6349                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6350             } else if(i == 1) {
6351                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6352             }
6353
6354             hr = IDirect3DDevice9_EndScene(device);
6355             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6356         }
6357
6358         if(i == 3 || i == 2) {
6359             color = getPixelColor(device, 160, 360);
6360             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6361                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6362
6363             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6364             color = getPixelColor(device, 480, 360);
6365             ok(color == 0x00FFFF00 || color ==0x00FF0000,
6366                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6367             color = getPixelColor(device, 160, 120);
6368             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6369             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6370                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6371
6372             color = getPixelColor(device, 480, 160);
6373             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6374         } else if(i == 1) {
6375             color = getPixelColor(device, 160, 360);
6376             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6377                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6378             color = getPixelColor(device, 480, 360);
6379             /* Accept the clear color as well in this case, since SW VP returns an error */
6380             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6381             color = getPixelColor(device, 160, 120);
6382             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6383                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6384             color = getPixelColor(device, 480, 160);
6385             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6386         }
6387
6388         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6389         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6390
6391         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6392         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6393
6394         /* Now find out if the whole streams are re-read, or just the last active value for the
6395          * vertices is used.
6396          */
6397         hr = IDirect3DDevice9_BeginScene(device);
6398         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6399         if(SUCCEEDED(hr))
6400         {
6401             float quad1_modified[] =  {
6402                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6403                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6404                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6405                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6406             };
6407             float quad2_modified[] =  {
6408                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6409                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6410                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6411                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6412             };
6413
6414             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6415             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6416
6417             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6418             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6419             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6420             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6421
6422             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6423             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6424             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6425             if(i == 3 || i == 2) {
6426                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6427             } else if(i == 1) {
6428                 /* Succeeds or fails, depending on SW or HW vertex processing */
6429                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6430             }
6431
6432             hr = IDirect3DDevice9_EndScene(device);
6433             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6434         }
6435
6436         color = getPixelColor(device, 480, 350);
6437         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6438          * as well.
6439          *
6440          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6441          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6442          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6443          * refrast's result.
6444          *
6445          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6446          */
6447         ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6448            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6449
6450         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6451         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6452
6453         IDirect3DDevice9_SetVertexShader(device, NULL);
6454         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6455
6456         IDirect3DVertexShader9_Release(swapped_shader);
6457     }
6458
6459     for(i = 1; i <= 3; i++) {
6460         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6461         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6462         if(i == 3) {
6463             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6464             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6465             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6466             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6467         } else if(i == 2){
6468             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6469             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6470             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6471             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6472         } else if(i == 1) {
6473             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6474             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6475             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6476             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6477         }
6478
6479         hr = IDirect3DDevice9_BeginScene(device);
6480         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6481         if(SUCCEEDED(hr))
6482         {
6483             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6484             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6485             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6486             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6487             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6488             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6489
6490             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6491             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6492
6493             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6494             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6495             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6496             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6497             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6498             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6499
6500             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6501             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6502             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6503             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6504             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6505             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6506
6507             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6508             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6509             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6510             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6511
6512             hr = IDirect3DDevice9_EndScene(device);
6513             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6514         }
6515         IDirect3DDevice9_SetVertexShader(device, NULL);
6516         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6517
6518         color = getPixelColor(device, 160, 360);
6519         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6520            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6521         color = getPixelColor(device, 480, 360);
6522         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6523            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6524         color = getPixelColor(device, 160, 120);
6525         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6526            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6527         color = getPixelColor(device, 480, 160);
6528         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6529            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6530
6531         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6532         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6533
6534         IDirect3DVertexShader9_Release(texcoord_color_shader);
6535         IDirect3DVertexShader9_Release(color_color_shader);
6536     }
6537
6538     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6539     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6540     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6541     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6542
6543     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6544     IDirect3DVertexDeclaration9_Release(decl_color_color);
6545     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6546     IDirect3DVertexDeclaration9_Release(decl_color_float);
6547 }
6548
6549 static void srgbtexture_test(IDirect3DDevice9 *device)
6550 {
6551     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6552      * texture stage state to render a quad using that texture.  The resulting
6553      * color components should be 0x36 (~ 0.21), per this formula:
6554      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6555      * This is true where srgb_color > 0.04045.
6556      */
6557     IDirect3D9 *d3d = NULL;
6558     HRESULT hr;
6559     LPDIRECT3DTEXTURE9 texture = NULL;
6560     LPDIRECT3DSURFACE9 surface = NULL;
6561     D3DLOCKED_RECT lr;
6562     DWORD color;
6563     float quad[] = {
6564         -1.0,       1.0,       0.0,     0.0,    0.0,
6565          1.0,       1.0,       0.0,     1.0,    0.0,
6566         -1.0,      -1.0,       0.0,     0.0,    1.0,
6567          1.0,      -1.0,       0.0,     1.0,    1.0,
6568     };
6569
6570
6571     memset(&lr, 0, sizeof(lr));
6572     IDirect3DDevice9_GetDirect3D(device, &d3d);
6573     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6574                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6575                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6576         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6577         goto out;
6578     }
6579
6580     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6581                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6582                                         &texture, NULL);
6583     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6584     if(!texture) {
6585         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6586         goto out;
6587     }
6588     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6589     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6590
6591     fill_surface(surface, 0xff7f7f7f);
6592     IDirect3DSurface9_Release(surface);
6593
6594     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6595     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6596     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6597     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6598
6599     hr = IDirect3DDevice9_BeginScene(device);
6600     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6601     if(SUCCEEDED(hr))
6602     {
6603         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6604         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6605
6606         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6607         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6608
6609
6610         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6611         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6612
6613         hr = IDirect3DDevice9_EndScene(device);
6614         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6615     }
6616
6617     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6618     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6619     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6620     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6621
6622     color = getPixelColor(device, 320, 240);
6623     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6624
6625     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6626     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6627
6628 out:
6629     if(texture) IDirect3DTexture9_Release(texture);
6630     IDirect3D9_Release(d3d);
6631 }
6632
6633 static void shademode_test(IDirect3DDevice9 *device)
6634 {
6635     /* Render a quad and try all of the different fixed function shading models. */
6636     HRESULT hr;
6637     DWORD color0, color1;
6638     DWORD color0_gouraud = 0, color1_gouraud = 0;
6639     DWORD shademode = D3DSHADE_FLAT;
6640     DWORD primtype = D3DPT_TRIANGLESTRIP;
6641     LPVOID data = NULL;
6642     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6643     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6644     UINT i, j;
6645     struct vertex quad_strip[] =
6646     {
6647         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6648         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6649         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6650         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6651     };
6652     struct vertex quad_list[] =
6653     {
6654         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6655         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6656         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6657
6658         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6659         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6660         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6661     };
6662
6663     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6664                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6665     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6666     if (FAILED(hr)) goto bail;
6667
6668     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6669                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6670     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6671     if (FAILED(hr)) goto bail;
6672
6673     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6674     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6675
6676     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6677     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6678
6679     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6680     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6681     memcpy(data, quad_strip, sizeof(quad_strip));
6682     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6683     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6684
6685     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6686     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6687     memcpy(data, quad_list, sizeof(quad_list));
6688     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6689     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6690
6691     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
6692      * the color fixups we have to do for FLAT shading will be dependent on that. */
6693     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6694     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6695
6696     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6697     for (j=0; j<2; j++) {
6698
6699         /* Inner loop just changes the D3DRS_SHADEMODE */
6700         for (i=0; i<3; i++) {
6701             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6702             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6703
6704             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6705             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6706
6707             hr = IDirect3DDevice9_BeginScene(device);
6708             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6709             if(SUCCEEDED(hr))
6710             {
6711                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6712                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6713
6714                 hr = IDirect3DDevice9_EndScene(device);
6715                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6716             }
6717
6718             /* Sample two spots from the output */
6719             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6720             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6721             switch(shademode) {
6722                 case D3DSHADE_FLAT:
6723                     /* Should take the color of the first vertex of each triangle */
6724                     if (0)
6725                     {
6726                         /* This test depends on EXT_provoking_vertex being
6727                          * available. This extension is currently (20090810)
6728                          * not common enough to let the test fail if it isn't
6729                          * present. */
6730                         ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
6731                         ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
6732                     }
6733                     shademode = D3DSHADE_GOURAUD;
6734                     break;
6735                 case D3DSHADE_GOURAUD:
6736                     /* Should be an interpolated blend */
6737
6738                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6739                        "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6740                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6741                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6742
6743                     color0_gouraud = color0;
6744                     color1_gouraud = color1;
6745
6746                     shademode = D3DSHADE_PHONG;
6747                     break;
6748                 case D3DSHADE_PHONG:
6749                     /* Should be the same as GOURAUD, since no hardware implements this */
6750                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6751                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6752                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6753                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6754
6755                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6756                             color0_gouraud, color0);
6757                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6758                             color1_gouraud, color1);
6759                     break;
6760             }
6761         }
6762
6763         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6764         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6765
6766         /* Now, do it all over again with a TRIANGLELIST */
6767         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6768         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6769         primtype = D3DPT_TRIANGLELIST;
6770         shademode = D3DSHADE_FLAT;
6771     }
6772
6773 bail:
6774     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6775     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6776     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6777     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6778
6779     if (vb_strip)
6780         IDirect3DVertexBuffer9_Release(vb_strip);
6781     if (vb_list)
6782         IDirect3DVertexBuffer9_Release(vb_list);
6783 }
6784
6785
6786 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
6787 {
6788     /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
6789      * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
6790      * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
6791      * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
6792      * 0.73
6793      *
6794      * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
6795      * so use shaders for this task
6796      */
6797     IDirect3DPixelShader9 *pshader;
6798     IDirect3DVertexShader9 *vshader;
6799     IDirect3D9 *d3d;
6800     DWORD vshader_code[] = {
6801         0xfffe0101,                                                             /* vs_1_1                       */
6802         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
6803         0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0   */
6804         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
6805         0x00000001, 0xc00f0001, 0xa0000000,                                     /* mov oFog, c0.x               */
6806         0x0000ffff                                                              /* end                          */
6807     };
6808     DWORD pshader_code[] = {
6809         0xffff0101,                                                             /* ps_1_1                       */
6810         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
6811         0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
6812         0x0000ffff                                                              /* end                          */
6813     };
6814     const float quad[] = {
6815        -1.0,   -1.0,    0.1,
6816         1.0,   -1.0,    0.1,
6817        -1.0,    1.0,    0.1,
6818         1.0,    1.0,    0.1
6819     };
6820     HRESULT hr;
6821     D3DCOLOR color;
6822
6823     IDirect3DDevice9_GetDirect3D(device, &d3d);
6824     /* Ask for srgb writing on D3DRTYPE_TEXTURE. Some Windows drivers do not report it on surfaces.
6825      * For some not entirely understood reasons D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE
6826      * passes on surfaces, while asking for SRGBWRITE alone fails. Textures advertize srgb writing
6827      * alone as well, so use that since it is not the point of this test to show how CheckDeviceFormat
6828      * works
6829      */
6830     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6831                                     D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
6832                                     D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK) {
6833         skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
6834         IDirect3D9_Release(d3d);
6835         return;
6836     }
6837     IDirect3D9_Release(d3d);
6838
6839     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6840     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6841
6842     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6843     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6844     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
6845     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6846     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
6847     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6848     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
6849     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6850     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
6851     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6852
6853     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6854     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6855     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
6856     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6857     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6858     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6859     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6860     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6861     hr = IDirect3DDevice9_SetPixelShader(device, pshader);
6862     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6863
6864     hr = IDirect3DDevice9_BeginScene(device);
6865     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6866     if(SUCCEEDED(hr)) {
6867         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
6868         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6869
6870         hr = IDirect3DDevice9_EndScene(device);
6871         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6872     }
6873
6874     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6875     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6876     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6877     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6878     IDirect3DPixelShader9_Release(pshader);
6879     IDirect3DVertexShader9_Release(vshader);
6880
6881     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
6882     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6883     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
6884     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6885
6886     color = getPixelColor(device, 160, 360);
6887     ok(color_match(color, 0x00808080, 1),
6888             "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
6889     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6890     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6891 }
6892
6893 static void alpha_test(IDirect3DDevice9 *device)
6894 {
6895     HRESULT hr;
6896     IDirect3DTexture9 *offscreenTexture;
6897     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6898     DWORD color;
6899
6900     struct vertex quad1[] =
6901     {
6902         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
6903         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
6904         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
6905         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
6906     };
6907     struct vertex quad2[] =
6908     {
6909         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
6910         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
6911         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
6912         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
6913     };
6914     static const float composite_quad[][5] = {
6915         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6916         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
6917         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6918         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
6919     };
6920
6921     /* Clear the render target with alpha = 0.5 */
6922     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6923     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6924
6925     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6926     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6927
6928     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6929     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6930     if(!backbuffer) {
6931         goto out;
6932     }
6933
6934     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6935     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6936     if(!offscreen) {
6937         goto out;
6938     }
6939
6940     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6941     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6942
6943     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6944     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6945     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6946     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6947     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6948     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6949     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6950     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6951     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6952     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6953
6954     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6955     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6956     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6957
6958         /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6959         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6960         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6961         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6962         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6963         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6964         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6965
6966         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6967         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6968         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6969         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6970         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6971         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6972
6973         /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6974          * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6975          * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6976         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6977         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6978         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6979         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6980
6981         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6982         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6983         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6984         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6985         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6986         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6987
6988         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6989         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6990         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6991         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6992         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6993         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6994
6995         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6996         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6997
6998         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6999          * Disable alpha blending for the final composition
7000          */
7001         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
7002         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7003         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7004         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7005
7006         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
7007         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7008         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
7009         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7010         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7011         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7012
7013         hr = IDirect3DDevice9_EndScene(device);
7014         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
7015     }
7016
7017     color = getPixelColor(device, 160, 360);
7018     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7019        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
7020
7021     color = getPixelColor(device, 160, 120);
7022     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
7023        "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
7024
7025     color = getPixelColor(device, 480, 360);
7026     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7027        "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
7028
7029     color = getPixelColor(device, 480, 120);
7030     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
7031        "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
7032
7033     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7034
7035     out:
7036     /* restore things */
7037     if(backbuffer) {
7038         IDirect3DSurface9_Release(backbuffer);
7039     }
7040     if(offscreenTexture) {
7041         IDirect3DTexture9_Release(offscreenTexture);
7042     }
7043     if(offscreen) {
7044         IDirect3DSurface9_Release(offscreen);
7045     }
7046 }
7047
7048 struct vertex_shortcolor {
7049     float x, y, z;
7050     unsigned short r, g, b, a;
7051 };
7052 struct vertex_floatcolor {
7053     float x, y, z;
7054     float r, g, b, a;
7055 };
7056
7057 static void fixed_function_decl_test(IDirect3DDevice9 *device)
7058 {
7059     HRESULT hr;
7060     BOOL s_ok, ub_ok, f_ok;
7061     DWORD color, size, i;
7062     void *data;
7063     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
7064         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7065         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7066         D3DDECL_END()
7067     };
7068     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
7069         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7070         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7071         D3DDECL_END()
7072     };
7073     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
7074         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7075         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7076         D3DDECL_END()
7077     };
7078     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
7079         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7080         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7081         D3DDECL_END()
7082     };
7083     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
7084         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7085         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7086         D3DDECL_END()
7087     };
7088     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
7089         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7090         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7091         D3DDECL_END()
7092     };
7093     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
7094         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
7095         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7096         D3DDECL_END()
7097     };
7098     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
7099     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
7100     IDirect3DVertexBuffer9 *vb, *vb2;
7101     struct vertex quad1[] =                             /* D3DCOLOR */
7102     {
7103         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
7104         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7105         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
7106         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7107     };
7108     struct vertex quad2[] =                             /* UBYTE4N */
7109     {
7110         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7111         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
7112         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7113         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
7114     };
7115     struct vertex_shortcolor quad3[] =                  /* short */
7116     {
7117         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7118         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7119         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7120         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7121     };
7122     struct vertex_floatcolor quad4[] =
7123     {
7124         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7125         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7126         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7127         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7128     };
7129     DWORD colors[] = {
7130         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7131         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7132         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7133         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7134         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7135         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7136         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7137         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7138         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7139         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7140         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7141         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7142         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7143         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7144         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7145         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7146     };
7147     float quads[] = {
7148         -1.0,   -1.0,     0.1,
7149         -1.0,    0.0,     0.1,
7150          0.0,   -1.0,     0.1,
7151          0.0,    0.0,     0.1,
7152
7153          0.0,   -1.0,     0.1,
7154          0.0,    0.0,     0.1,
7155          1.0,   -1.0,     0.1,
7156          1.0,    0.0,     0.1,
7157
7158          0.0,    0.0,     0.1,
7159          0.0,    1.0,     0.1,
7160          1.0,    0.0,     0.1,
7161          1.0,    1.0,     0.1,
7162
7163         -1.0,    0.0,     0.1,
7164         -1.0,    1.0,     0.1,
7165          0.0,    0.0,     0.1,
7166          0.0,    1.0,     0.1
7167     };
7168     struct tvertex quad_transformed[] = {
7169        {  90,    110,     0.1,      2.0,        0x00ffff00},
7170        { 570,    110,     0.1,      2.0,        0x00ffff00},
7171        {  90,    300,     0.1,      2.0,        0x00ffff00},
7172        { 570,    300,     0.1,      2.0,        0x00ffff00}
7173     };
7174     D3DCAPS9 caps;
7175
7176     memset(&caps, 0, sizeof(caps));
7177     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7178     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7179
7180     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7181     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7182
7183     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7184     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7185     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7186     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7187     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7188     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7189     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7190         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7191         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7192         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7193         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7194     } else {
7195         trace("D3DDTCAPS_UBYTE4N not supported\n");
7196         dcl_ubyte_2 = NULL;
7197         dcl_ubyte = NULL;
7198     }
7199     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7200     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7201     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7202     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7203
7204     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7205     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7206                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
7207     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7208
7209     hr = IDirect3DDevice9_BeginScene(device);
7210     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7211     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7212     if(SUCCEEDED(hr)) {
7213         if(dcl_color) {
7214             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7215             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7216             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7217             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7218         }
7219
7220         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7221          * accepts them, the nvidia driver accepts them all. All those differences even though we're
7222          * using software vertex processing. Doh!
7223          */
7224         if(dcl_ubyte) {
7225             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7226             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7227             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7228             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7229             ub_ok = SUCCEEDED(hr);
7230         }
7231
7232         if(dcl_short) {
7233             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7234             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7235             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7236             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7237             s_ok = SUCCEEDED(hr);
7238         }
7239
7240         if(dcl_float) {
7241             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7242             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7243             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7244             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7245             f_ok = SUCCEEDED(hr);
7246         }
7247
7248         hr = IDirect3DDevice9_EndScene(device);
7249         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7250     }
7251
7252     if(dcl_short) {
7253         color = getPixelColor(device, 480, 360);
7254         ok(color == 0x000000ff || !s_ok,
7255            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7256     }
7257     if(dcl_ubyte) {
7258         color = getPixelColor(device, 160, 120);
7259         ok(color == 0x0000ffff || !ub_ok,
7260            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7261     }
7262     if(dcl_color) {
7263         color = getPixelColor(device, 160, 360);
7264         ok(color == 0x00ffff00,
7265            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7266     }
7267     if(dcl_float) {
7268         color = getPixelColor(device, 480, 120);
7269         ok(color == 0x00ff0000 || !f_ok,
7270            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7271     }
7272     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7273
7274     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7275      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7276      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7277      * whether the immediate mode code works
7278      */
7279     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7280     hr = IDirect3DDevice9_BeginScene(device);
7281     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7282     if(SUCCEEDED(hr)) {
7283         if(dcl_color) {
7284             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7285             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7286             memcpy(data, quad1, sizeof(quad1));
7287             hr = IDirect3DVertexBuffer9_Unlock(vb);
7288             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7289             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7290             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7291             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7292             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7293             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7294             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7295         }
7296
7297         if(dcl_ubyte) {
7298             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7299             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7300             memcpy(data, quad2, sizeof(quad2));
7301             hr = IDirect3DVertexBuffer9_Unlock(vb);
7302             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7303             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7304             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7305             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7306             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7307             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7308             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7309                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7310             ub_ok = SUCCEEDED(hr);
7311         }
7312
7313         if(dcl_short) {
7314             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7315             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7316             memcpy(data, quad3, sizeof(quad3));
7317             hr = IDirect3DVertexBuffer9_Unlock(vb);
7318             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7319             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7320             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7321             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7322             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7323             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7324             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7325                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7326             s_ok = SUCCEEDED(hr);
7327         }
7328
7329         if(dcl_float) {
7330             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7331             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7332             memcpy(data, quad4, sizeof(quad4));
7333             hr = IDirect3DVertexBuffer9_Unlock(vb);
7334             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7335             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7336             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7337             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7338             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7339             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7340             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7341                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7342             f_ok = SUCCEEDED(hr);
7343         }
7344
7345         hr = IDirect3DDevice9_EndScene(device);
7346         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7347     }
7348
7349     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7350     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7351     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7352     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7353
7354     if(dcl_short) {
7355         color = getPixelColor(device, 480, 360);
7356         ok(color == 0x000000ff || !s_ok,
7357            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7358     }
7359     if(dcl_ubyte) {
7360         color = getPixelColor(device, 160, 120);
7361         ok(color == 0x0000ffff || !ub_ok,
7362            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7363     }
7364     if(dcl_color) {
7365         color = getPixelColor(device, 160, 360);
7366         ok(color == 0x00ffff00,
7367            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7368     }
7369     if(dcl_float) {
7370         color = getPixelColor(device, 480, 120);
7371         ok(color == 0x00ff0000 || !f_ok,
7372            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7373     }
7374     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7375
7376     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7377     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7378
7379     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7380     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7381     memcpy(data, quad_transformed, sizeof(quad_transformed));
7382     hr = IDirect3DVertexBuffer9_Unlock(vb);
7383     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7384
7385     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7386     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7387
7388     hr = IDirect3DDevice9_BeginScene(device);
7389     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7390     if(SUCCEEDED(hr)) {
7391         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7392         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7393         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7394         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7395
7396         hr = IDirect3DDevice9_EndScene(device);
7397         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7398     }
7399
7400     color = getPixelColor(device, 88, 108);
7401     ok(color == 0x000000ff,
7402        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7403     color = getPixelColor(device, 92, 108);
7404     ok(color == 0x000000ff,
7405        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7406     color = getPixelColor(device, 88, 112);
7407     ok(color == 0x000000ff,
7408        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7409     color = getPixelColor(device, 92, 112);
7410     ok(color == 0x00ffff00,
7411        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7412
7413     color = getPixelColor(device, 568, 108);
7414     ok(color == 0x000000ff,
7415        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7416     color = getPixelColor(device, 572, 108);
7417     ok(color == 0x000000ff,
7418        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7419     color = getPixelColor(device, 568, 112);
7420     ok(color == 0x00ffff00,
7421        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7422     color = getPixelColor(device, 572, 112);
7423     ok(color == 0x000000ff,
7424        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7425
7426     color = getPixelColor(device, 88, 298);
7427     ok(color == 0x000000ff,
7428        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7429     color = getPixelColor(device, 92, 298);
7430     ok(color == 0x00ffff00,
7431        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7432     color = getPixelColor(device, 88, 302);
7433     ok(color == 0x000000ff,
7434        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7435     color = getPixelColor(device, 92, 302);
7436     ok(color == 0x000000ff,
7437        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7438
7439     color = getPixelColor(device, 568, 298);
7440     ok(color == 0x00ffff00,
7441        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7442     color = getPixelColor(device, 572, 298);
7443     ok(color == 0x000000ff,
7444        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7445     color = getPixelColor(device, 568, 302);
7446     ok(color == 0x000000ff,
7447        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7448     color = getPixelColor(device, 572, 302);
7449     ok(color == 0x000000ff,
7450        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7451
7452     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7453
7454     /* This test is pointless without those two declarations: */
7455     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7456         skip("color-ubyte switching test declarations aren't supported\n");
7457         goto out;
7458     }
7459
7460     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7461     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7462     memcpy(data, quads, sizeof(quads));
7463     hr = IDirect3DVertexBuffer9_Unlock(vb);
7464     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7465     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7466                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7467     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7468     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7469     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7470     memcpy(data, colors, sizeof(colors));
7471     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7472     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7473
7474     for(i = 0; i < 2; i++) {
7475         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7476         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7477
7478         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7479         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7480         if(i == 0) {
7481             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7482         } else {
7483             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7484         }
7485         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7486
7487         hr = IDirect3DDevice9_BeginScene(device);
7488         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7489         ub_ok = FALSE;
7490         if(SUCCEEDED(hr)) {
7491             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7492             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7493             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7494             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7495                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7496             ub_ok = SUCCEEDED(hr);
7497
7498             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7499             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7500             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7501             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7502
7503             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7504             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7505             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7506             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7507                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7508             ub_ok = (SUCCEEDED(hr) && ub_ok);
7509
7510             hr = IDirect3DDevice9_EndScene(device);
7511             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7512         }
7513
7514         if(i == 0) {
7515             color = getPixelColor(device, 480, 360);
7516             ok(color == 0x00ff0000,
7517                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7518             color = getPixelColor(device, 160, 120);
7519             ok(color == 0x00ffffff,
7520                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7521             color = getPixelColor(device, 160, 360);
7522             ok(color == 0x000000ff || !ub_ok,
7523                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7524             color = getPixelColor(device, 480, 120);
7525             ok(color == 0x000000ff || !ub_ok,
7526                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7527         } else {
7528             color = getPixelColor(device, 480, 360);
7529             ok(color == 0x000000ff,
7530                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7531             color = getPixelColor(device, 160, 120);
7532             ok(color == 0x00ffffff,
7533                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7534             color = getPixelColor(device, 160, 360);
7535             ok(color == 0x00ff0000 || !ub_ok,
7536                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7537             color = getPixelColor(device, 480, 120);
7538             ok(color == 0x00ff0000 || !ub_ok,
7539                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7540         }
7541         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7542     }
7543
7544     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7545     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7546     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7547     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7548     IDirect3DVertexBuffer9_Release(vb2);
7549
7550     out:
7551     IDirect3DVertexBuffer9_Release(vb);
7552     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7553     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7554     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7555     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7556     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7557     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7558     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7559 }
7560
7561 struct vertex_float16color {
7562     float x, y, z;
7563     DWORD c1, c2;
7564 };
7565
7566 static void test_vshader_float16(IDirect3DDevice9 *device)
7567 {
7568     HRESULT hr;
7569     DWORD color;
7570     void *data;
7571     static const D3DVERTEXELEMENT9 decl_elements[] = {
7572         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7573         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7574         D3DDECL_END()
7575     };
7576     IDirect3DVertexDeclaration9 *vdecl = NULL;
7577     IDirect3DVertexBuffer9 *buffer = NULL;
7578     IDirect3DVertexShader9 *shader;
7579     DWORD shader_code[] = {
7580         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7581         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7582         0x90e40001, 0x0000ffff
7583     };
7584     struct vertex_float16color quad[] = {
7585         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7586         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7587         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7588         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7589
7590         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7591         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7592         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7593         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7594
7595         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7596         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7597         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7598         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7599
7600         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7601         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7602         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7603         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7604     };
7605
7606     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7607     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7608
7609     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7610     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7611     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7612     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7613     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7614     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7615
7616     hr = IDirect3DDevice9_BeginScene(device);
7617     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7618     if(SUCCEEDED(hr)) {
7619         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7620         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7621         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7622         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7623         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7624         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7625         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7626         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7627         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7628         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7629
7630         hr = IDirect3DDevice9_EndScene(device);
7631         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7632     }
7633     color = getPixelColor(device, 480, 360);
7634     ok(color == 0x00ff0000,
7635        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7636     color = getPixelColor(device, 160, 120);
7637     ok(color == 0x00000000,
7638        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7639     color = getPixelColor(device, 160, 360);
7640     ok(color == 0x0000ff00,
7641        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7642     color = getPixelColor(device, 480, 120);
7643     ok(color == 0x000000ff,
7644        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7645     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7646
7647     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7648     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7649
7650     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7651                                              D3DPOOL_MANAGED, &buffer, NULL);
7652     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7653     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7654     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7655     memcpy(data, quad, sizeof(quad));
7656     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7657     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7658     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7659     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7660
7661     hr = IDirect3DDevice9_BeginScene(device);
7662     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7663     if(SUCCEEDED(hr)) {
7664             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7665             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7666             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7667             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7668             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7669             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7670             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7671             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7672
7673             hr = IDirect3DDevice9_EndScene(device);
7674             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7675     }
7676
7677     color = getPixelColor(device, 480, 360);
7678     ok(color == 0x00ff0000,
7679        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7680     color = getPixelColor(device, 160, 120);
7681     ok(color == 0x00000000,
7682        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7683     color = getPixelColor(device, 160, 360);
7684     ok(color == 0x0000ff00,
7685        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7686     color = getPixelColor(device, 480, 120);
7687     ok(color == 0x000000ff,
7688        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7689     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7690
7691     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7692     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7693     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7694     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7695     IDirect3DDevice9_SetVertexShader(device, NULL);
7696     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7697
7698     IDirect3DVertexDeclaration9_Release(vdecl);
7699     IDirect3DVertexShader9_Release(shader);
7700     IDirect3DVertexBuffer9_Release(buffer);
7701 }
7702
7703 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7704 {
7705     D3DCAPS9 caps;
7706     IDirect3DTexture9 *texture;
7707     HRESULT hr;
7708     D3DLOCKED_RECT rect;
7709     unsigned int x, y;
7710     DWORD *dst, color;
7711     const float quad[] = {
7712         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
7713          1.0,   -1.0,   0.1,    1.2,   -0.2,
7714         -1.0,    1.0,   0.1,   -0.2,    1.2,
7715          1.0,    1.0,   0.1,    1.2,    1.2
7716     };
7717     memset(&caps, 0, sizeof(caps));
7718
7719     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7720     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7721     if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7722         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7723         ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7724            "Card has conditional NP2 support without power of two restriction set\n");
7725         skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7726         return;
7727     } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7728         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7729         return;
7730     }
7731
7732     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7733     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7734
7735     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7736     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7737
7738     memset(&rect, 0, sizeof(rect));
7739     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7740     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7741     for(y = 0; y < 10; y++) {
7742         for(x = 0; x < 10; x++) {
7743             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7744             if(x == 0 || x == 9 || y == 0 || y == 9) {
7745                 *dst = 0x00ff0000;
7746             } else {
7747                 *dst = 0x000000ff;
7748             }
7749         }
7750     }
7751     hr = IDirect3DTexture9_UnlockRect(texture, 0);
7752     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7753
7754     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7755     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7756     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7757     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7758     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7759     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7760     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7761     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7762
7763     hr = IDirect3DDevice9_BeginScene(device);
7764     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7765     if(SUCCEEDED(hr)) {
7766         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7767         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7768
7769         hr = IDirect3DDevice9_EndScene(device);
7770         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7771     }
7772
7773     color = getPixelColor(device,    1,  1);
7774     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
7775     color = getPixelColor(device, 639, 479);
7776     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7777
7778     color = getPixelColor(device, 135, 101);
7779     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7780     color = getPixelColor(device, 140, 101);
7781     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7782     color = getPixelColor(device, 135, 105);
7783     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7784     color = getPixelColor(device, 140, 105);
7785     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7786
7787     color = getPixelColor(device, 135, 376);
7788     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7789     color = getPixelColor(device, 140, 376);
7790     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7791     color = getPixelColor(device, 135, 379);
7792     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7793     color = getPixelColor(device, 140, 379);
7794     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7795
7796     color = getPixelColor(device, 500, 101);
7797     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7798     color = getPixelColor(device, 504, 101);
7799     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7800     color = getPixelColor(device, 500, 105);
7801     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7802     color = getPixelColor(device, 504, 105);
7803     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7804
7805     color = getPixelColor(device, 500, 376);
7806     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7807     color = getPixelColor(device, 504, 376);
7808     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7809     color = getPixelColor(device, 500, 380);
7810     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7811     color = getPixelColor(device, 504, 380);
7812     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7813
7814     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7815
7816     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7817     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7818     IDirect3DTexture9_Release(texture);
7819 }
7820
7821 static void vFace_register_test(IDirect3DDevice9 *device)
7822 {
7823     HRESULT hr;
7824     DWORD color;
7825     const DWORD shader_code[] = {
7826         0xffff0300,                                                             /* ps_3_0                     */
7827         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7828         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7829         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
7830         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
7831         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
7832         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
7833         0x0000ffff                                                              /* END                        */
7834     };
7835     IDirect3DPixelShader9 *shader;
7836     IDirect3DTexture9 *texture;
7837     IDirect3DSurface9 *surface, *backbuffer;
7838     const float quad[] = {
7839         -1.0,   -1.0,   0.1,
7840          1.0,   -1.0,   0.1,
7841         -1.0,    0.0,   0.1,
7842
7843          1.0,   -1.0,   0.1,
7844          1.0,    0.0,   0.1,
7845         -1.0,    0.0,   0.1,
7846
7847         -1.0,    0.0,   0.1,
7848         -1.0,    1.0,   0.1,
7849          1.0,    0.0,   0.1,
7850
7851          1.0,    0.0,   0.1,
7852         -1.0,    1.0,   0.1,
7853          1.0,    1.0,   0.1,
7854     };
7855     const float blit[] = {
7856          0.0,   -1.0,   0.1,    0.0,    0.0,
7857          1.0,   -1.0,   0.1,    1.0,    0.0,
7858          0.0,    1.0,   0.1,    0.0,    1.0,
7859          1.0,    1.0,   0.1,    1.0,    1.0,
7860     };
7861
7862     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7863     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7864     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7865     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7866     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7867     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7868     hr = IDirect3DDevice9_SetPixelShader(device, shader);
7869     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7870     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7871     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7872     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7873     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7874
7875     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7876     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7877
7878     hr = IDirect3DDevice9_BeginScene(device);
7879     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7880     if(SUCCEEDED(hr)) {
7881         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7882         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7883         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7884         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7885         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7886         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7887         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7888         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7889         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7890         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7891         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7892
7893         /* Blit the texture onto the back buffer to make it visible */
7894         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7895         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7896         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7897         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7898         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7899         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7900         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7901         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7902         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7903         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7904
7905         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7906         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7907
7908         hr = IDirect3DDevice9_EndScene(device);
7909         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7910     }
7911
7912     color = getPixelColor(device, 160, 360);
7913     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7914     color = getPixelColor(device, 160, 120);
7915     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7916     color = getPixelColor(device, 480, 360);
7917     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7918     color = getPixelColor(device, 480, 120);
7919     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7920     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7921
7922     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7923     IDirect3DDevice9_SetTexture(device, 0, NULL);
7924     IDirect3DPixelShader9_Release(shader);
7925     IDirect3DSurface9_Release(surface);
7926     IDirect3DSurface9_Release(backbuffer);
7927     IDirect3DTexture9_Release(texture);
7928 }
7929
7930 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7931 {
7932     HRESULT hr;
7933     DWORD color;
7934     int i;
7935     D3DCAPS9 caps;
7936     BOOL L6V5U5_supported = FALSE;
7937     IDirect3DTexture9 *tex1, *tex2;
7938     D3DLOCKED_RECT locked_rect;
7939
7940     static const float quad[][7] = {
7941         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7942         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7943         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7944         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7945     };
7946
7947     static const D3DVERTEXELEMENT9 decl_elements[] = {
7948         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7949         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7950         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7951         D3DDECL_END()
7952     };
7953
7954     /* use asymmetric matrix to test loading */
7955     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7956     float scale, offset;
7957
7958     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7959     IDirect3DTexture9           *texture            = NULL;
7960
7961     memset(&caps, 0, sizeof(caps));
7962     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7963     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7964     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7965         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7966         return;
7967     } else {
7968         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7969          * They report that it is not supported, but after that bump mapping works properly. So just test
7970          * if the format is generally supported, and check the BUMPENVMAP flag
7971          */
7972         IDirect3D9 *d3d9;
7973
7974         IDirect3DDevice9_GetDirect3D(device, &d3d9);
7975         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7976                                           D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
7977         L6V5U5_supported = SUCCEEDED(hr);
7978         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7979                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7980         IDirect3D9_Release(d3d9);
7981         if(FAILED(hr)) {
7982             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7983             return;
7984         }
7985     }
7986
7987     /* Generate the textures */
7988     generate_bumpmap_textures(device);
7989
7990     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7991     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7992     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7993     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7994     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7995     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7996     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7997     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7998
7999     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
8000     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8001     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
8002     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8003     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
8004     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8005
8006     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8007     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8008     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8009     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8010     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8011     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8012
8013     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8014     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8015
8016     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8017     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
8018
8019     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
8020     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
8021
8022
8023     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
8024     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
8025     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
8026     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
8027
8028     hr = IDirect3DDevice9_BeginScene(device);
8029     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8030
8031     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8032     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8033
8034     hr = IDirect3DDevice9_EndScene(device);
8035     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8036
8037     /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
8038      * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
8039      * But since testing the color match is not the purpose of the test don't be too picky
8040      */
8041     color = getPixelColor(device, 320-32, 240);
8042     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8043     color = getPixelColor(device, 320+32, 240);
8044     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8045     color = getPixelColor(device, 320, 240-32);
8046     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8047     color = getPixelColor(device, 320, 240+32);
8048     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8049     color = getPixelColor(device, 320, 240);
8050     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8051     color = getPixelColor(device, 320+32, 240+32);
8052     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8053     color = getPixelColor(device, 320-32, 240+32);
8054     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8055     color = getPixelColor(device, 320+32, 240-32);
8056     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8057     color = getPixelColor(device, 320-32, 240-32);
8058     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8059     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8060     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8061
8062     for(i = 0; i < 2; i++) {
8063         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
8064         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
8065         IDirect3DTexture9_Release(texture); /* For the GetTexture */
8066         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
8067         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
8068         IDirect3DTexture9_Release(texture); /* To destroy it */
8069     }
8070
8071     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
8072         skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
8073         goto cleanup;
8074     }
8075     if(L6V5U5_supported == FALSE) {
8076         skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
8077         goto cleanup;
8078     }
8079
8080     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
8081     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8082     /* This test only tests the luminance part. The bumpmapping part was already tested above and
8083      * would only make this test more complicated
8084      */
8085     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
8086     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8087     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8088     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8089
8090     memset(&locked_rect, 0, sizeof(locked_rect));
8091     hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
8092     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8093     *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
8094     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8095     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8096
8097     memset(&locked_rect, 0, sizeof(locked_rect));
8098     hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
8099     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8100     *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
8101     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8102     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8103
8104     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8105     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8106     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8107     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8108
8109     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
8110     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8111     scale = 2.0;
8112     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8113     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8114     offset = 0.1;
8115     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8116     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8117
8118     hr = IDirect3DDevice9_BeginScene(device);
8119     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8120     if(SUCCEEDED(hr)) {
8121         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8122         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8123         hr = IDirect3DDevice9_EndScene(device);
8124         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8125     }
8126
8127     color = getPixelColor(device, 320, 240);
8128     /* red:   1.0  * (0.25 * 2.0 + 0.1) = 1.0  * 0.6 = 0.6  = 0x99
8129      * green: 0.5  * (0.25 * 2.0 + 0.1) = 0.5  * 0.6 = 0.3  = 0x4c
8130      * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
8131      */
8132     ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
8133     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8134     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8135
8136     /* Check a result scale factor > 1.0 */
8137     scale = 10;
8138     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8139     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8140     offset = 10;
8141     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8142     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8143
8144     hr = IDirect3DDevice9_BeginScene(device);
8145     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8146     if(SUCCEEDED(hr)) {
8147         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8148         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8149         hr = IDirect3DDevice9_EndScene(device);
8150         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8151     }
8152     color = getPixelColor(device, 320, 240);
8153     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8154     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8155     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8156
8157     /* Check clamping in the scale factor calculation */
8158     scale = 1000;
8159     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8160     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8161     offset = -1;
8162     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8163     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8164
8165     hr = IDirect3DDevice9_BeginScene(device);
8166     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8167     if(SUCCEEDED(hr)) {
8168         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8169         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8170         hr = IDirect3DDevice9_EndScene(device);
8171         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8172     }
8173     color = getPixelColor(device, 320, 240);
8174     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8175     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8176     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8177
8178     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8179     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8180     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8181     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8182
8183     IDirect3DTexture9_Release(tex1);
8184     IDirect3DTexture9_Release(tex2);
8185
8186 cleanup:
8187     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8188     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8189     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8190     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8191
8192     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8193     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8194     IDirect3DVertexDeclaration9_Release(vertex_declaration);
8195 }
8196
8197 static void stencil_cull_test(IDirect3DDevice9 *device) {
8198     HRESULT hr;
8199     IDirect3DSurface9 *depthstencil = NULL;
8200     D3DSURFACE_DESC desc;
8201     float quad1[] = {
8202         -1.0,   -1.0,   0.1,
8203          0.0,   -1.0,   0.1,
8204         -1.0,    0.0,   0.1,
8205          0.0,    0.0,   0.1,
8206     };
8207     float quad2[] = {
8208          0.0,   -1.0,   0.1,
8209          1.0,   -1.0,   0.1,
8210          0.0,    0.0,   0.1,
8211          1.0,    0.0,   0.1,
8212     };
8213     float quad3[] = {
8214         0.0,    0.0,   0.1,
8215         1.0,    0.0,   0.1,
8216         0.0,    1.0,   0.1,
8217         1.0,    1.0,   0.1,
8218     };
8219     float quad4[] = {
8220         -1.0,    0.0,   0.1,
8221          0.0,    0.0,   0.1,
8222         -1.0,    1.0,   0.1,
8223          0.0,    1.0,   0.1,
8224     };
8225     struct vertex painter[] = {
8226        {-1.0,   -1.0,   0.0,    0x00000000},
8227        { 1.0,   -1.0,   0.0,    0x00000000},
8228        {-1.0,    1.0,   0.0,    0x00000000},
8229        { 1.0,    1.0,   0.0,    0x00000000},
8230     };
8231     WORD indices_cw[]  = {0, 1, 3};
8232     WORD indices_ccw[] = {0, 2, 3};
8233     unsigned int i;
8234     DWORD color;
8235
8236     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8237     if(depthstencil == NULL) {
8238         skip("No depth stencil buffer\n");
8239         return;
8240     }
8241     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8242     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8243     IDirect3DSurface9_Release(depthstencil);
8244     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8245         skip("No 4 or 8 bit stencil surface\n");
8246         return;
8247     }
8248
8249     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8250     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8251     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8252
8253     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8254     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8255     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8256     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8257     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8258     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8259     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8260     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8261
8262     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8263     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8264     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8265     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8266     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8267     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8268
8269     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8270     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8271     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8272     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8273
8274     /* First pass: Fill the stencil buffer with some values... */
8275     hr = IDirect3DDevice9_BeginScene(device);
8276     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8277     if(SUCCEEDED(hr))
8278     {
8279         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8280         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8281         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8282                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8283         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8284         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8285                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8286         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8287
8288         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8289         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8290         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8291         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8292         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8293                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8294         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8295         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8296                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8297         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8298
8299         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8300         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8301         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8302                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8303         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8304         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8305                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8306         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8307
8308         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8309         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8310         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8311                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8312         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8313         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8314                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8315         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8316
8317         hr = IDirect3DDevice9_EndScene(device);
8318         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8319     }
8320
8321     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8322     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8323     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8324     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8325     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8326     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8327     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8328     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8329     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8330     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8331     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8332     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8333     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8334
8335     /* 2nd pass: Make the stencil values visible */
8336     hr = IDirect3DDevice9_BeginScene(device);
8337     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8338     if(SUCCEEDED(hr))
8339     {
8340         IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8341         for(i = 0; i < 16; i++) {
8342             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8343             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8344
8345             painter[0].diffuse = (i * 16); /* Creates shades of blue */
8346             painter[1].diffuse = (i * 16);
8347             painter[2].diffuse = (i * 16);
8348             painter[3].diffuse = (i * 16);
8349             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8350             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8351         }
8352         hr = IDirect3DDevice9_EndScene(device);
8353         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8354     }
8355
8356     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8357     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8358
8359     color = getPixelColor(device, 160, 420);
8360     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8361     color = getPixelColor(device, 160, 300);
8362     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8363
8364     color = getPixelColor(device, 480, 420);
8365     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8366     color = getPixelColor(device, 480, 300);
8367     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8368
8369     color = getPixelColor(device, 160, 180);
8370     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8371     color = getPixelColor(device, 160, 60);
8372     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8373
8374     color = getPixelColor(device, 480, 180);
8375     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8376     color = getPixelColor(device, 480, 60);
8377     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8378
8379     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8380     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8381 }
8382
8383 static void vpos_register_test(IDirect3DDevice9 *device)
8384 {
8385     HRESULT hr;
8386     DWORD color;
8387     const DWORD shader_code[] = {
8388     0xffff0300,                                                             /* ps_3_0                     */
8389     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8390     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8391     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8392     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8393     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8394     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8395     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8396     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8397     0x0000ffff                                                              /* end                        */
8398     };
8399     const DWORD shader_frac_code[] = {
8400     0xffff0300,                                                             /* ps_3_0                     */
8401     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8402     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8403     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8404     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8405     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8406     0x0000ffff                                                              /* end                        */
8407     };
8408     IDirect3DPixelShader9 *shader, *shader_frac;
8409     IDirect3DSurface9 *surface = NULL, *backbuffer;
8410     const float quad[] = {
8411         -1.0,   -1.0,   0.1,    0.0,    0.0,
8412          1.0,   -1.0,   0.1,    1.0,    0.0,
8413         -1.0,    1.0,   0.1,    0.0,    1.0,
8414          1.0,    1.0,   0.1,    1.0,    1.0,
8415     };
8416     D3DLOCKED_RECT lr;
8417     float constant[4] = {1.0, 0.0, 320, 240};
8418     DWORD *pos;
8419
8420     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8421     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8422     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8423     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8424     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8425     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8426     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8427     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8428     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8429     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8430     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8431     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8432
8433     hr = IDirect3DDevice9_BeginScene(device);
8434     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8435     if(SUCCEEDED(hr)) {
8436         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8437         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8438         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8439         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8440         hr = IDirect3DDevice9_EndScene(device);
8441         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8442     }
8443
8444     /* This has to be pixel exact */
8445     color = getPixelColor(device, 319, 239);
8446     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8447     color = getPixelColor(device, 320, 239);
8448     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8449     color = getPixelColor(device, 319, 240);
8450     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8451     color = getPixelColor(device, 320, 240);
8452     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8453     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8454
8455     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8456                                              &surface, NULL);
8457     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8458     hr = IDirect3DDevice9_BeginScene(device);
8459     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8460     if(SUCCEEDED(hr)) {
8461         constant[2] = 16; constant[3] = 16;
8462         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8463         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8464         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8465         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8466         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8467         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8468         hr = IDirect3DDevice9_EndScene(device);
8469         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8470     }
8471     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8472     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8473
8474     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8475     color = *pos & 0x00ffffff;
8476     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8477     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8478     color = *pos & 0x00ffffff;
8479     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8480     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8481     color = *pos & 0x00ffffff;
8482     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8483     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8484     color = *pos & 0x00ffffff;
8485     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8486
8487     hr = IDirect3DSurface9_UnlockRect(surface);
8488     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8489
8490     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8491      * have full control over the multisampling setting inside this test
8492      */
8493     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8494     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8495     hr = IDirect3DDevice9_BeginScene(device);
8496     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8497     if(SUCCEEDED(hr)) {
8498         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8499         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8500         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8501         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8502         hr = IDirect3DDevice9_EndScene(device);
8503         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8504     }
8505     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8506     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8507
8508     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8509     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8510
8511     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8512     color = *pos & 0x00ffffff;
8513     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8514
8515     hr = IDirect3DSurface9_UnlockRect(surface);
8516     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8517
8518     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8519     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8520     IDirect3DPixelShader9_Release(shader);
8521     IDirect3DPixelShader9_Release(shader_frac);
8522     if(surface) IDirect3DSurface9_Release(surface);
8523     IDirect3DSurface9_Release(backbuffer);
8524 }
8525
8526 static void pointsize_test(IDirect3DDevice9 *device)
8527 {
8528     HRESULT hr;
8529     D3DCAPS9 caps;
8530     D3DMATRIX matrix;
8531     D3DMATRIX identity;
8532     float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8533     DWORD color;
8534     IDirect3DTexture9 *tex1, *tex2;
8535     D3DLOCKED_RECT lr;
8536     const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8537                                 0x00000000, 0x00000000};
8538     const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8539                                 0x00000000, 0x0000ff00};
8540
8541     const float vertices[] = {
8542         64,     64,     0.1,
8543         128,    64,     0.1,
8544         192,    64,     0.1,
8545         256,    64,     0.1,
8546         320,    64,     0.1,
8547         384,    64,     0.1,
8548         448,    64,     0.1,
8549         512,    64,     0.1,
8550         576,    64,     0.1,
8551     };
8552
8553     /* 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 */
8554     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;
8555     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;
8556     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;
8557     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;
8558
8559     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;
8560     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;
8561     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;
8562     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;
8563
8564     memset(&caps, 0, sizeof(caps));
8565     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8566     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8567     if(caps.MaxPointSize < 32.0) {
8568         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8569         return;
8570     }
8571
8572     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8573     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8574     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8575     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8576     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8577     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8578     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8579     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8580
8581     hr = IDirect3DDevice9_BeginScene(device);
8582     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8583     if(SUCCEEDED(hr)) {
8584         ptsize = 16.0;
8585         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8586         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8587         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8588         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8589
8590         ptsize = 32.0;
8591         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8592         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8593         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8594         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8595
8596         ptsize = 31.5;
8597         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8598         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8599         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8600         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8601
8602         if(caps.MaxPointSize >= 64.0) {
8603             ptsize = 64.0;
8604             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8605             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8606             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8607             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8608
8609             ptsize = 63.75;
8610             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8611             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8612             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8613             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8614         }
8615
8616         ptsize = 1.0;
8617         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8618         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8619         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8620         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8621
8622         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8623         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8624         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8625         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8626
8627         /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8628         ptsize = 16.0;
8629         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8630         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8631         ptsize = 1.0;
8632         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8633         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8634         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8635         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8636
8637         /* What happens if POINTSIZE_MAX < POINTSIZE_MIN?
8638          * ptsize = 4.0, ptsize_max = 1.0, ptsize_min = 16.0
8639          */
8640         ptsize = 4.0;
8641         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8642         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8643         ptsize = 16.0;
8644         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8645         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8646         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8647         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8648
8649         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8650         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8651
8652         /* pointsize < pointsize_min < pointsize_max?
8653          * pointsize = 1.0, pointsize_min = 16.0, pointsize_max = default(usually 64.0)
8654          */
8655         ptsize = 1.0;
8656         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8657         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8658         ptsize = 16.0;
8659         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8660         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8661         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[24], sizeof(float) * 3);
8662         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8663
8664         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8665         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8666
8667         hr = IDirect3DDevice9_EndScene(device);
8668         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8669     }
8670     color = getPixelColor(device, 64-9, 64-9);
8671     ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
8672     color = getPixelColor(device, 64-8, 64-8);
8673     ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
8674     color = getPixelColor(device, 64-7, 64-7);
8675     ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
8676     color = getPixelColor(device, 64+7, 64+7);
8677     ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
8678     color = getPixelColor(device, 64+8, 64+8);
8679     ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
8680     color = getPixelColor(device, 64+9, 64+9);
8681     ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
8682
8683     color = getPixelColor(device, 128-17, 64-17);
8684     ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8685     color = getPixelColor(device, 128-16, 64-16);
8686     ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
8687     color = getPixelColor(device, 128-15, 64-15);
8688     ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8689     color = getPixelColor(device, 128+15, 64+15);
8690     ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8691     color = getPixelColor(device, 128+16, 64+16);
8692     ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8693     color = getPixelColor(device, 128+17, 64+17);
8694     ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8695
8696     color = getPixelColor(device, 192-17, 64-17);
8697     ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8698     color = getPixelColor(device, 192-16, 64-16);
8699     todo_wine ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
8700     color = getPixelColor(device, 192-15, 64-15);
8701     ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8702     color = getPixelColor(device, 192+15, 64+15);
8703     ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8704     color = getPixelColor(device, 192+16, 64+16);
8705     ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8706     color = getPixelColor(device, 192+17, 64+17);
8707     ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8708
8709     if(caps.MaxPointSize >= 64.0) {
8710         color = getPixelColor(device, 256-33, 64-33);
8711         ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8712         color = getPixelColor(device, 256-32, 64-32);
8713         todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
8714         color = getPixelColor(device, 256-31, 64-31);
8715         ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8716         color = getPixelColor(device, 256+31, 64+31);
8717         ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8718         color = getPixelColor(device, 256+32, 64+32);
8719         ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8720         color = getPixelColor(device, 256+33, 64+33);
8721         ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8722
8723         color = getPixelColor(device, 384-33, 64-33);
8724         ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8725         color = getPixelColor(device, 384-32, 64-32);
8726         ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
8727         color = getPixelColor(device, 384-31, 64-31);
8728         ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8729         color = getPixelColor(device, 384+31, 64+31);
8730         ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8731         color = getPixelColor(device, 384+32, 64+32);
8732         ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8733         color = getPixelColor(device, 384+33, 64+33);
8734         ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8735     }
8736
8737     color = getPixelColor(device, 320-1, 64-1);
8738     ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
8739     color = getPixelColor(device, 320-0, 64-0);
8740     ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
8741     color = getPixelColor(device, 320+1, 64+1);
8742     ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
8743
8744     /* ptsize = 16, ptsize_max = 1 --> point has size 1 */
8745     color = getPixelColor(device, 448-4, 64-4);
8746     ok(color == 0x000000ff, "pSize: Pixel (448-4),(64-4) has color 0x%08x, expected 0x000000ff\n", color);
8747     color = getPixelColor(device, 448+4, 64+4);
8748     ok(color == 0x000000ff, "pSize: Pixel (448+4),(64+4) has color 0x%08x, expected 0x000000ff\n", color);
8749
8750     /* ptsize = 4, ptsize_max = 1, ptsize_min = 16 --> point has size 1 */
8751     color = getPixelColor(device, 512-4, 64-4);
8752     ok(color == 0x000000ff, "pSize: Pixel (512-4),(64-4) has color 0x%08x, expected 0x000000ff\n", color);
8753     color = getPixelColor(device, 512+4, 64+4);
8754     ok(color == 0x000000ff, "pSize: Pixel (512+4),(64+4) has color 0x%08x, expected 0x000000ff\n", color);
8755
8756     /* ptsize = 1, ptsize_max = default(64), ptsize_min = 16 --> point has size 16
8757      * Don't be overly picky - just show that the point is bigger than 1 pixel
8758      */
8759     color = getPixelColor(device, 576-4, 64-4);
8760     ok(color == 0x00ffffff, "pSize: Pixel (576-4),(64-4) has color 0x%08x, expected 0x00ffffff\n", color);
8761     color = getPixelColor(device, 576+4, 64+4);
8762     ok(color == 0x00ffffff, "pSize: Pixel (576+4),(64+4) has color 0x%08x, expected 0x00ffffff\n", color);
8763
8764     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8765
8766     /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8767      * generates texture coordinates for the point(result: Yes, it does)
8768      *
8769      * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8770      * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8771      * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8772      */
8773     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8774     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8775
8776     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8777     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8778     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8779     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8780     memset(&lr, 0, sizeof(lr));
8781     hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8782     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8783     memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8784     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8785     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8786     memset(&lr, 0, sizeof(lr));
8787     hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8788     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8789     memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8790     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8791     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8792     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8793     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8794     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8795     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8796     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8797     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8798     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8799     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8800     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8801     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8802     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8803     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8804     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8805     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8806
8807     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8808     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8809     ptsize = 32.0;
8810     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8811     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8812
8813     hr = IDirect3DDevice9_BeginScene(device);
8814     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8815     if(SUCCEEDED(hr))
8816     {
8817         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8818         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8819         hr = IDirect3DDevice9_EndScene(device);
8820         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8821     }
8822
8823     color = getPixelColor(device, 64-4, 64-4);
8824     ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
8825     color = getPixelColor(device, 64-4, 64+4);
8826     ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
8827     color = getPixelColor(device, 64+4, 64+4);
8828     ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
8829     color = getPixelColor(device, 64+4, 64-4);
8830     ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
8831     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8832
8833     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8834     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8835     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8836     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8837     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8838     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8839     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8840     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8841     IDirect3DTexture9_Release(tex1);
8842     IDirect3DTexture9_Release(tex2);
8843
8844     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
8845     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8846     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8847     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8848     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8849     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8850 }
8851
8852 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8853 {
8854     HRESULT hr;
8855     IDirect3DPixelShader9 *ps;
8856     IDirect3DTexture9 *tex1, *tex2;
8857     IDirect3DSurface9 *surf1, *surf2, *backbuf;
8858     D3DCAPS9 caps;
8859     DWORD color;
8860     DWORD shader_code[] = {
8861     0xffff0300,                                                             /* ps_3_0             */
8862     0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
8863     0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
8864     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0        */
8865     0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1        */
8866     0x0000ffff                                                              /* END                */
8867     };
8868     float quad[] = {
8869        -1.0,   -1.0,    0.1,
8870         1.0,   -1.0,    0.1,
8871        -1.0,    1.0,    0.1,
8872         1.0,    1.0,    0.1,
8873     };
8874     float texquad[] = {
8875        -1.0,   -1.0,    0.1,    0.0,    0.0,
8876         0.0,   -1.0,    0.1,    1.0,    0.0,
8877        -1.0,    1.0,    0.1,    0.0,    1.0,
8878         0.0,    1.0,    0.1,    1.0,    1.0,
8879
8880         0.0,   -1.0,    0.1,    0.0,    0.0,
8881         1.0,   -1.0,    0.1,    1.0,    0.0,
8882         0.0,    1.0,    0.1,    0.0,    1.0,
8883         1.0,    1.0,    0.1,    1.0,    1.0,
8884     };
8885
8886     memset(&caps, 0, sizeof(caps));
8887     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8888     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8889     if(caps.NumSimultaneousRTs < 2) {
8890         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8891         return;
8892     }
8893
8894     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8895     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8896
8897     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8898     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8899     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8900     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8901     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
8902     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
8903
8904     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8905     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8906     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8907     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8908     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8909     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8910
8911     hr = IDirect3DDevice9_SetPixelShader(device, ps);
8912     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8913     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8914     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8915     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8916     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8917     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8918     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8919
8920     hr = IDirect3DDevice9_BeginScene(device);
8921     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8922     if(SUCCEEDED(hr)) {
8923         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8924         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8925
8926         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8927         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8928         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8929         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8930         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8931         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8932         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8933         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8934
8935         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8936         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8937         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8938         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8939
8940         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8941         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8942         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8943         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8944
8945         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8946         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8947
8948         hr = IDirect3DDevice9_EndScene(device);
8949         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8950     }
8951
8952     color = getPixelColor(device, 160, 240);
8953     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8954     color = getPixelColor(device, 480, 240);
8955     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8956     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8957
8958     IDirect3DPixelShader9_Release(ps);
8959     IDirect3DTexture9_Release(tex1);
8960     IDirect3DTexture9_Release(tex2);
8961     IDirect3DSurface9_Release(surf1);
8962     IDirect3DSurface9_Release(surf2);
8963     IDirect3DSurface9_Release(backbuf);
8964 }
8965
8966 struct formats {
8967     const char *fmtName;
8968     D3DFORMAT textureFormat;
8969     DWORD resultColorBlending;
8970     DWORD resultColorNoBlending;
8971 };
8972
8973 const struct formats test_formats[] = {
8974   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
8975   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8976   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8977   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8978   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8979   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8980   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8981   { NULL, 0 }
8982 };
8983
8984 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8985 {
8986     HRESULT hr;
8987     IDirect3DTexture9 *offscreenTexture = NULL;
8988     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8989     IDirect3D9 *d3d = NULL;
8990     DWORD color;
8991     DWORD r0, g0, b0, r1, g1, b1;
8992     int fmt_index;
8993
8994     static const float quad[][5] = {
8995         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8996         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
8997         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8998         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
8999     };
9000
9001     /* Quad with R=0x10, G=0x20 */
9002     static const struct vertex quad1[] = {
9003         {-1.0f, -1.0f, 0.1f, 0x80102000},
9004         {-1.0f,  1.0f, 0.1f, 0x80102000},
9005         { 1.0f, -1.0f, 0.1f, 0x80102000},
9006         { 1.0f,  1.0f, 0.1f, 0x80102000},
9007     };
9008
9009     /* Quad with R=0x20, G=0x10 */
9010     static const struct vertex quad2[] = {
9011         {-1.0f, -1.0f, 0.1f, 0x80201000},
9012         {-1.0f,  1.0f, 0.1f, 0x80201000},
9013         { 1.0f, -1.0f, 0.1f, 0x80201000},
9014         { 1.0f,  1.0f, 0.1f, 0x80201000},
9015     };
9016
9017     IDirect3DDevice9_GetDirect3D(device, &d3d);
9018
9019     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9020     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
9021     if(!backbuffer) {
9022         goto out;
9023     }
9024
9025     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
9026     {
9027         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
9028         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
9029            skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
9030            continue;
9031         }
9032
9033         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9034         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9035
9036         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
9037         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
9038         if(!offscreenTexture) {
9039             continue;
9040         }
9041
9042         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
9043         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
9044         if(!offscreen) {
9045             continue;
9046         }
9047
9048         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9049         ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9050
9051         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9052         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9053         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9054         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9055         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
9056         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
9057         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
9058         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
9059         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9060         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9061
9062         /* Below we will draw two quads with different colors and try to blend them together.
9063          * The result color is compared with the expected outcome.
9064          */
9065         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
9066             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
9067             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9068             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
9069             ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9070
9071             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9072             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9073
9074             /* Draw a quad using color 0x0010200 */
9075             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
9076             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9077             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
9078             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9079             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9080             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9081
9082             /* Draw a quad using color 0x0020100 */
9083             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9084             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9085             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
9086             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9087             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9088             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9089
9090             /* We don't want to blend the result on the backbuffer */
9091             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9092             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9093
9094             /* Prepare rendering the 'blended' texture quad to the backbuffer */
9095             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9096             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9097             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
9098             ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
9099
9100             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9101             ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9102
9103             /* This time with the texture */
9104             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9105             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
9106
9107             IDirect3DDevice9_EndScene(device);
9108         }
9109
9110         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
9111             /* Compare the color of the center quad with our expectation */
9112             color = getPixelColor(device, 320, 240);
9113             r0 = (color & 0x00ff0000) >> 16;
9114             g0 = (color & 0x0000ff00) >>  8;
9115             b0 = (color & 0x000000ff) >>  0;
9116
9117             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
9118             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
9119             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
9120
9121             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9122                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9123                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9124                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9125         } else {
9126             /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9127              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9128              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9129             color = getPixelColor(device, 320, 240);
9130             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);
9131         }
9132         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9133
9134         IDirect3DDevice9_SetTexture(device, 0, NULL);
9135         if(offscreenTexture) {
9136             IDirect3DTexture9_Release(offscreenTexture);
9137         }
9138         if(offscreen) {
9139             IDirect3DSurface9_Release(offscreen);
9140         }
9141     }
9142
9143 out:
9144     /* restore things */
9145     if(backbuffer) {
9146         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9147         IDirect3DSurface9_Release(backbuffer);
9148     }
9149 }
9150
9151 static void tssargtemp_test(IDirect3DDevice9 *device)
9152 {
9153     HRESULT hr;
9154     DWORD color;
9155     static const struct vertex quad[] = {
9156         {-1.0,     -1.0,    0.1,    0x00ff0000},
9157         { 1.0,     -1.0,    0.1,    0x00ff0000},
9158         {-1.0,      1.0,    0.1,    0x00ff0000},
9159         { 1.0,      1.0,    0.1,    0x00ff0000}
9160     };
9161     D3DCAPS9 caps;
9162
9163     memset(&caps, 0, sizeof(caps));
9164     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9165     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9166     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9167         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9168         return;
9169     }
9170
9171     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9172     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9173
9174     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9175     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9176     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9177     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9178
9179     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9180     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9181     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9182     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9183     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9184     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9185
9186     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9187     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9188     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9189     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9190     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9191     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9192
9193     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9194     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9195
9196     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9197     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9198     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9199     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9200
9201     hr = IDirect3DDevice9_BeginScene(device);
9202     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9203     if(SUCCEEDED(hr)) {
9204         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9205         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9206         hr = IDirect3DDevice9_EndScene(device);
9207         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9208     }
9209     color = getPixelColor(device, 320, 240);
9210     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9211     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9212
9213     /* Set stage 1 back to default */
9214     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9215     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9216     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9217     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9218     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9219     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9220     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9221     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9222     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9223     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9224 }
9225
9226 struct testdata
9227 {
9228     DWORD idxVertex; /* number of instances in the first stream */
9229     DWORD idxColor; /* number of instances in the second stream */
9230     DWORD idxInstance; /* should be 1 ?? */
9231     DWORD color1; /* color 1 instance */
9232     DWORD color2; /* color 2 instance */
9233     DWORD color3; /* color 3 instance */
9234     DWORD color4; /* color 4 instance */
9235     WORD strVertex; /* specify which stream to use 0-2*/
9236     WORD strColor;
9237     WORD strInstance;
9238 };
9239
9240 static const struct testdata testcases[]=
9241 {
9242     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
9243     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
9244     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
9245     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
9246     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  4 */
9247     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
9248     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
9249     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
9250     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  8 */
9251     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  9 */
9252     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
9253     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
9254     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
9255     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
9256     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
9257 /*
9258     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
9259     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9260 */
9261 };
9262
9263 /* Drawing Indexed Geometry with instances*/
9264 static void stream_test(IDirect3DDevice9 *device)
9265 {
9266     IDirect3DVertexBuffer9 *vb = NULL;
9267     IDirect3DVertexBuffer9 *vb2 = NULL;
9268     IDirect3DVertexBuffer9 *vb3 = NULL;
9269     IDirect3DIndexBuffer9 *ib = NULL;
9270     IDirect3DVertexDeclaration9 *pDecl = NULL;
9271     IDirect3DVertexShader9 *shader = NULL;
9272     HRESULT hr;
9273     BYTE *data;
9274     DWORD color;
9275     DWORD ind;
9276     unsigned i;
9277
9278     const DWORD shader_code[] =
9279     {
9280         0xfffe0101,                                     /* vs_1_1 */
9281         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
9282         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
9283         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
9284         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
9285         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9286         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
9287         0x0000ffff
9288     };
9289
9290     const float quad[][3] =
9291     {
9292         {-0.5f, -0.5f,  1.1f}, /*0 */
9293         {-0.5f,  0.5f,  1.1f}, /*1 */
9294         { 0.5f, -0.5f,  1.1f}, /*2 */
9295         { 0.5f,  0.5f,  1.1f}, /*3 */
9296     };
9297
9298     const float vertcolor[][4] =
9299     {
9300         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9301         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9302         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9303         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9304     };
9305
9306     /* 4 position for 4 instances */
9307     const float instancepos[][3] =
9308     {
9309         {-0.6f,-0.6f, 0.0f},
9310         { 0.6f,-0.6f, 0.0f},
9311         { 0.6f, 0.6f, 0.0f},
9312         {-0.6f, 0.6f, 0.0f},
9313     };
9314
9315     short indices[] = {0, 1, 2, 1, 2, 3};
9316
9317     D3DVERTEXELEMENT9 decl[] =
9318     {
9319         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9320         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9321         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9322         D3DDECL_END()
9323     };
9324
9325     /* set the default value because it isn't done in wine? */
9326     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9327     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9328
9329     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9330     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9331     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9332
9333     /* check wrong cases */
9334     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9335     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9336     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9337     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9338     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9339     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9340     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9341     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9342     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9343     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9344     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9345     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9346     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9347     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9348     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9349     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9350     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9351     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9352     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9353     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9354
9355     /* set the default value back */
9356     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9357     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9358
9359     /* create all VertexBuffers*/
9360     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9361     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9362     if(!vb) {
9363         skip("Failed to create a vertex buffer\n");
9364         return;
9365     }
9366     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9367     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9368     if(!vb2) {
9369         skip("Failed to create a vertex buffer\n");
9370         goto out;
9371     }
9372     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9373     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9374     if(!vb3) {
9375         skip("Failed to create a vertex buffer\n");
9376         goto out;
9377     }
9378
9379     /* create IndexBuffer*/
9380     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9381     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9382     if(!ib) {
9383         skip("Failed to create a index buffer\n");
9384         goto out;
9385     }
9386
9387     /* copy all Buffers (Vertex + Index)*/
9388     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9389     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9390     memcpy(data, quad, sizeof(quad));
9391     hr = IDirect3DVertexBuffer9_Unlock(vb);
9392     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9393     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9394     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9395     memcpy(data, vertcolor, sizeof(vertcolor));
9396     hr = IDirect3DVertexBuffer9_Unlock(vb2);
9397     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9398     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9399     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9400     memcpy(data, instancepos, sizeof(instancepos));
9401     hr = IDirect3DVertexBuffer9_Unlock(vb3);
9402     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9403     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9404     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9405     memcpy(data, indices, sizeof(indices));
9406     hr = IDirect3DIndexBuffer9_Unlock(ib);
9407     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9408
9409     /* create VertexShader */
9410     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9411     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9412     if(!shader) {
9413         skip("Failed to create a vetex shader\n");
9414         goto out;
9415     }
9416
9417     hr = IDirect3DDevice9_SetVertexShader(device, shader);
9418     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9419
9420     hr = IDirect3DDevice9_SetIndices(device, ib);
9421     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9422
9423     /* run all tests */
9424     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9425     {
9426         struct testdata act = testcases[i];
9427         decl[0].Stream = act.strVertex;
9428         decl[1].Stream = act.strColor;
9429         decl[2].Stream = act.strInstance;
9430         /* create VertexDeclarations */
9431         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9432         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9433
9434         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9435         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9436
9437         hr = IDirect3DDevice9_BeginScene(device);
9438         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9439         if(SUCCEEDED(hr))
9440         {
9441             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9442             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9443
9444             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9445             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9446             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9447             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9448
9449             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9450             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9451             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9452             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9453
9454             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9455             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9456             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9457             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9458
9459             /* don't know if this is right (1*3 and 4*1)*/
9460             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
9461             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9462             hr = IDirect3DDevice9_EndScene(device);
9463             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9464
9465             /* set all StreamSource && StreamSourceFreq back to default */
9466             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9467             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9468             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9469             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9470             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9471             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9472             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9473             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9474             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9475             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9476             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9477             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9478         }
9479
9480         hr = IDirect3DVertexDeclaration9_Release(pDecl);
9481         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9482
9483         color = getPixelColor(device, 160, 360);
9484         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9485         color = getPixelColor(device, 480, 360);
9486         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9487         color = getPixelColor(device, 480, 120);
9488         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9489         color = getPixelColor(device, 160, 120);
9490         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9491
9492         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9493         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9494     }
9495
9496     hr = IDirect3DDevice9_SetIndices(device, NULL);
9497     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9498
9499 out:
9500     if(vb) IDirect3DVertexBuffer9_Release(vb);
9501     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9502     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9503     if(ib)IDirect3DIndexBuffer9_Release(ib);
9504     if(shader)IDirect3DVertexShader9_Release(shader);
9505 }
9506
9507 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9508     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9509     IDirect3DTexture9 *dsttex = NULL;
9510     HRESULT hr;
9511     DWORD color;
9512     D3DRECT r1 = {0,  0,  50,  50 };
9513     D3DRECT r2 = {50, 0,  100, 50 };
9514     D3DRECT r3 = {50, 50, 100, 100};
9515     D3DRECT r4 = {0,  50,  50, 100};
9516     const float quad[] = {
9517         -1.0,   -1.0,   0.1,    0.0,    0.0,
9518          1.0,   -1.0,   0.1,    1.0,    0.0,
9519         -1.0,    1.0,   0.1,    0.0,    1.0,
9520          1.0,    1.0,   0.1,    1.0,    1.0,
9521     };
9522
9523     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9524     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9525
9526     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9527     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9528     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9529     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9530
9531     if(!src || !dsttex) {
9532         skip("One or more test resources could not be created\n");
9533         goto cleanup;
9534     }
9535
9536     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9537     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9538
9539     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9540     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9541
9542     /* Clear the StretchRect destination for debugging */
9543     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9544     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9545     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9546     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9547
9548     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9549     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9550
9551     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9552     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9553     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9554     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9555     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9556     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9557     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9558     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9559
9560     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9561      * the target -> texture GL blit path
9562      */
9563     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9564     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9565     IDirect3DSurface9_Release(dst);
9566
9567     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9568     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9569
9570     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9571     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9572     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9573     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9574     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9575     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9576     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9577     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9578
9579     hr = IDirect3DDevice9_BeginScene(device);
9580     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9581     if(SUCCEEDED(hr)) {
9582         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9583         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9584         hr = IDirect3DDevice9_EndScene(device);
9585         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9586     }
9587
9588     color = getPixelColor(device, 160, 360);
9589     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9590     color = getPixelColor(device, 480, 360);
9591     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9592     color = getPixelColor(device, 480, 120);
9593     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9594     color = getPixelColor(device, 160, 120);
9595     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9596     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9597     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9598
9599     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9600     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9601     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9602     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9603
9604 cleanup:
9605     if(src) IDirect3DSurface9_Release(src);
9606     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9607     if(dsttex) IDirect3DTexture9_Release(dsttex);
9608 }
9609
9610 static void texop_test(IDirect3DDevice9 *device)
9611 {
9612     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9613     IDirect3DTexture9 *texture = NULL;
9614     D3DLOCKED_RECT locked_rect;
9615     D3DCOLOR color;
9616     D3DCAPS9 caps;
9617     HRESULT hr;
9618     unsigned i;
9619
9620     static const struct {
9621         float x, y, z;
9622         float s, t;
9623         D3DCOLOR diffuse;
9624     } quad[] = {
9625         {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9626         {-1.0f,  1.0f, 0.1f, -1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9627         { 1.0f, -1.0f, 0.1f,  1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9628         { 1.0f,  1.0f, 0.1f,  1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9629     };
9630
9631     static const D3DVERTEXELEMENT9 decl_elements[] = {
9632         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9633         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9634         {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9635         D3DDECL_END()
9636     };
9637
9638     static const struct {
9639         D3DTEXTUREOP op;
9640         const char *name;
9641         DWORD caps_flag;
9642         D3DCOLOR result;
9643     } test_data[] = {
9644         {D3DTOP_SELECTARG1,                "SELECTARG1",                D3DTEXOPCAPS_SELECTARG1,                D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9645         {D3DTOP_SELECTARG2,                "SELECTARG2",                D3DTEXOPCAPS_SELECTARG2,                D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9646         {D3DTOP_MODULATE,                  "MODULATE",                  D3DTEXOPCAPS_MODULATE,                  D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9647         {D3DTOP_MODULATE2X,                "MODULATE2X",                D3DTEXOPCAPS_MODULATE2X,                D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9648         {D3DTOP_MODULATE4X,                "MODULATE4X",                D3DTEXOPCAPS_MODULATE4X,                D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9649         {D3DTOP_ADD,                       "ADD",                       D3DTEXOPCAPS_ADD,                       D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9650         {D3DTOP_ADDSIGNED,                 "ADDSIGNED",                 D3DTEXOPCAPS_ADDSIGNED,                 D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9651         {D3DTOP_ADDSIGNED2X,               "ADDSIGNED2X",               D3DTEXOPCAPS_ADDSIGNED2X,               D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9652         {D3DTOP_SUBTRACT,                  "SUBTRACT",                  D3DTEXOPCAPS_SUBTRACT,                  D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9653         {D3DTOP_ADDSMOOTH,                 "ADDSMOOTH",                 D3DTEXOPCAPS_ADDSMOOTH,                 D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9654         {D3DTOP_BLENDDIFFUSEALPHA,         "BLENDDIFFUSEALPHA",         D3DTEXOPCAPS_BLENDDIFFUSEALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9655         {D3DTOP_BLENDTEXTUREALPHA,         "BLENDTEXTUREALPHA",         D3DTEXOPCAPS_BLENDTEXTUREALPHA,         D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9656         {D3DTOP_BLENDFACTORALPHA,          "BLENDFACTORALPHA",          D3DTEXOPCAPS_BLENDFACTORALPHA,          D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9657         {D3DTOP_BLENDTEXTUREALPHAPM,       "BLENDTEXTUREALPHAPM",       D3DTEXOPCAPS_BLENDTEXTUREALPHAPM,       D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9658         {D3DTOP_BLENDCURRENTALPHA,         "BLENDCURRENTALPHA",         D3DTEXOPCAPS_BLENDCURRENTALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9659         {D3DTOP_MODULATEALPHA_ADDCOLOR,    "MODULATEALPHA_ADDCOLOR",    D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR,    D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9660         {D3DTOP_MODULATECOLOR_ADDALPHA,    "MODULATECOLOR_ADDALPHA",    D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA,    D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9661         {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9662         {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9663         /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9664         {D3DTOP_DOTPRODUCT3,               "DOTPRODUCT3",               D3DTEXOPCAPS_DOTPRODUCT3,               D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9665         {D3DTOP_MULTIPLYADD,               "MULTIPLYADD",               D3DTEXOPCAPS_MULTIPLYADD,               D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9666         {D3DTOP_LERP,                      "LERP",                      D3DTEXOPCAPS_LERP,                      D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9667     };
9668
9669     memset(&caps, 0, sizeof(caps));
9670     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9671     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9672
9673     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9674     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9675     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9676     ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9677
9678     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9679     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9680     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9681     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9682     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9683     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9684     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9685     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9686     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9687
9688     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9689     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9690     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9691     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9692     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9693     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9694
9695     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9696     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9697
9698     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9699     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9700     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9701     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9702     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9703     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9704
9705     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9706     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9707
9708     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9709     {
9710         if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9711         {
9712             skip("tex operation %s not supported\n", test_data[i].name);
9713             continue;
9714         }
9715
9716         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9717         ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9718
9719         hr = IDirect3DDevice9_BeginScene(device);
9720         ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9721
9722         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9723         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9724
9725         hr = IDirect3DDevice9_EndScene(device);
9726         ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9727
9728         color = getPixelColor(device, 320, 240);
9729         ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9730                 test_data[i].name, color, test_data[i].result);
9731
9732         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9733         ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9734     }
9735
9736     if (texture) IDirect3DTexture9_Release(texture);
9737     if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9738 }
9739
9740 static void yuv_color_test(IDirect3DDevice9 *device) {
9741     HRESULT hr;
9742     IDirect3DSurface9 *surface = NULL, *target = NULL;
9743     unsigned int fmt, i;
9744     D3DFORMAT format;
9745     const char *fmt_string;
9746     D3DLOCKED_RECT lr;
9747     IDirect3D9 *d3d;
9748     HRESULT color;
9749     DWORD ref_color_left, ref_color_right;
9750
9751     struct {
9752         DWORD in;           /* The input color */
9753         DWORD uyvy_left;    /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9754         DWORD uyvy_right;   /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9755         DWORD yuy2_left;    /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9756         DWORD yuy2_right;   /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9757     } test_data[] = {
9758     /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9759      * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9760      * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9761      * that
9762      */
9763       { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9764       { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9765       { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9766       { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9767       { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9768       { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9769       { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9770       { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9771       { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9772       { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9773       { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9774       { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9775       { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9776       { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9777
9778       { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9779       { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9780       { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9781       { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9782     };
9783
9784     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9785     ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9786     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9787     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9788
9789     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9790     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9791
9792     for(fmt = 0; fmt < 2; fmt++) {
9793         if(fmt == 0) {
9794             format = D3DFMT_UYVY;
9795             fmt_string = "D3DFMT_UYVY";
9796         } else {
9797             format = D3DFMT_YUY2;
9798             fmt_string = "D3DFMT_YUY2";
9799         }
9800
9801         /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9802                        * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9803                        */
9804         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9805                                         D3DRTYPE_SURFACE, format) != D3D_OK) {
9806             skip("%s is not supported\n", fmt_string);
9807             continue;
9808         }
9809
9810         /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9811         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9812         ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9813
9814         for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9815             if(fmt == 0) {
9816                 ref_color_left = test_data[i].uyvy_left;
9817                 ref_color_right = test_data[i].uyvy_right;
9818             } else {
9819                 ref_color_left = test_data[i].yuy2_left;
9820                 ref_color_right = test_data[i].yuy2_right;
9821             }
9822
9823             memset(&lr, 0, sizeof(lr));
9824             hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9825             ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9826             *((DWORD *) lr.pBits) = test_data[i].in;
9827             hr = IDirect3DSurface9_UnlockRect(surface);
9828             ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9829
9830             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9831             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9832             hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9833             ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9834
9835             /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9836              * prevent running into precision problems, read a far left and far right pixel. In the future we may
9837              * want to add tests for the filtered pixels as well.
9838              *
9839              * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9840              * differently, so we need a max diff of 16
9841              */
9842             color = getPixelColor(device, 40, 240);
9843             ok(color_match(color, ref_color_left, 18),
9844                "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9845                test_data[i].in, color, ref_color_left, fmt_string);
9846             color = getPixelColor(device, 600, 240);
9847             ok(color_match(color, ref_color_right, 18),
9848                "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9849                test_data[i].in, color, ref_color_right, fmt_string);
9850             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9851             ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9852         }
9853         IDirect3DSurface9_Release(surface);
9854     }
9855     IDirect3DSurface9_Release(target);
9856     IDirect3D9_Release(d3d);
9857 }
9858
9859 static void texop_range_test(IDirect3DDevice9 *device)
9860 {
9861     static const struct {
9862         float x, y, z;
9863         D3DCOLOR diffuse;
9864     } quad[] = {
9865         {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9866         {-1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9867         { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9868         { 1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
9869     };
9870     HRESULT hr;
9871     IDirect3DTexture9 *texture;
9872     D3DLOCKED_RECT locked_rect;
9873     D3DCAPS9 caps;
9874     DWORD color;
9875
9876     /* We need ADD and SUBTRACT operations */
9877     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9878     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9879     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
9880         skip("D3DTOP_ADD is not supported, skipping value range test\n");
9881         return;
9882     }
9883     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
9884         skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
9885         return;
9886     }
9887
9888     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9889     ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
9890     /* Stage 1: result = diffuse(=1.0) + diffuse
9891      * stage 2: result = result - tfactor(= 0.5)
9892      */
9893     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9894     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9895     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9896     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9897     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9898     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9899     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9900     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9901     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9902     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9903     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9904     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9905     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9906     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9907
9908     hr = IDirect3DDevice9_BeginScene(device);
9909     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9910     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9911     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9912     hr = IDirect3DDevice9_EndScene(device);
9913     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9914
9915     color = getPixelColor(device, 320, 240);
9916     ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
9917        color);
9918     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9919     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9920
9921     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9922     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9923     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9924     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9925     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
9926     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9927     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9928     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9929     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9930
9931     /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
9932      * stage 2: result = result + diffuse(1.0)
9933      */
9934     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9935     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9936     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9937     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9938     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9939     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9940     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9941     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9942     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9943     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9944     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9945     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9946     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9947     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9948
9949     hr = IDirect3DDevice9_BeginScene(device);
9950     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9951     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9952     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9953     hr = IDirect3DDevice9_EndScene(device);
9954     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9955
9956     color = getPixelColor(device, 320, 240);
9957     ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
9958        color);
9959     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9960     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9961
9962     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9963     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9964     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9965     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9966     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9967     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9968     IDirect3DTexture9_Release(texture);
9969 }
9970
9971 static void alphareplicate_test(IDirect3DDevice9 *device) {
9972     struct vertex quad[] = {
9973         { -1.0,    -1.0,    0.1,    0x80ff00ff },
9974         {  1.0,    -1.0,    0.1,    0x80ff00ff },
9975         { -1.0,     1.0,    0.1,    0x80ff00ff },
9976         {  1.0,     1.0,    0.1,    0x80ff00ff },
9977     };
9978     HRESULT hr;
9979     DWORD color;
9980
9981     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9982     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9983
9984     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9985     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9986
9987     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9988     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9989     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
9990     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9991
9992     hr = IDirect3DDevice9_BeginScene(device);
9993     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9994     if(SUCCEEDED(hr)) {
9995         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9996         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9997         hr = IDirect3DDevice9_EndScene(device);
9998         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
9999     }
10000
10001     color = getPixelColor(device, 320, 240);
10002     ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
10003        color);
10004     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10005     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10006
10007     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10008     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10009
10010 }
10011
10012 static void dp3_alpha_test(IDirect3DDevice9 *device) {
10013     HRESULT hr;
10014     D3DCAPS9 caps;
10015     DWORD color;
10016     struct vertex quad[] = {
10017         { -1.0,    -1.0,    0.1,    0x408080c0 },
10018         {  1.0,    -1.0,    0.1,    0x408080c0 },
10019         { -1.0,     1.0,    0.1,    0x408080c0 },
10020         {  1.0,     1.0,    0.1,    0x408080c0 },
10021     };
10022
10023     memset(&caps, 0, sizeof(caps));
10024     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10025     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10026     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
10027         skip("D3DTOP_DOTPRODUCT3 not supported\n");
10028         return;
10029     }
10030
10031     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10032     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10033
10034     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10035     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10036
10037     /* dp3_x4 r0, diffuse_bias, tfactor_bias
10038      * mov r0.a, diffuse.a
10039      * mov r0, r0.a
10040      *
10041      * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
10042      * 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
10043      * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
10044      */
10045     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
10046     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10047     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10048     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10049     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10050     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10051     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
10052     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10053     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
10054     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10055     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10056     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10057     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
10058     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10059     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10060     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10061     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
10062     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10063
10064     hr = IDirect3DDevice9_BeginScene(device);
10065     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10066     if(SUCCEEDED(hr)) {
10067         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10068         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10069         hr = IDirect3DDevice9_EndScene(device);
10070         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10071     }
10072
10073     color = getPixelColor(device, 320, 240);
10074     ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
10075        color);
10076     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10077     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10078
10079     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10080     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10081     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10082     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10083     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10084     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10085 }
10086
10087 static void zwriteenable_test(IDirect3DDevice9 *device) {
10088     HRESULT hr;
10089     DWORD color;
10090     struct vertex quad1[] = {
10091         { -1.0,  -1.0,  0.1,    0x00ff0000},
10092         { -1.0,   1.0,  0.1,    0x00ff0000},
10093         {  1.0,  -1.0,  0.1,    0x00ff0000},
10094         {  1.0,   1.0,  0.1,    0x00ff0000},
10095     };
10096     struct vertex quad2[] = {
10097         { -1.0,  -1.0,  0.9,    0x0000ff00},
10098         { -1.0,   1.0,  0.9,    0x0000ff00},
10099         {  1.0,  -1.0,  0.9,    0x0000ff00},
10100         {  1.0,   1.0,  0.9,    0x0000ff00},
10101     };
10102
10103     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
10104     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10105
10106     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10107     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10108     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10109     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10110     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10111     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10112     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10113     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10114
10115     hr = IDirect3DDevice9_BeginScene(device);
10116     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10117     if(SUCCEEDED(hr)) {
10118         /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10119          * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10120          * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10121          * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10122          * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10123          * the screen is green, so zenable = D3DZB_FALSE and zwriteenable  = TRUE does NOT write to the z buffer.
10124          */
10125         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10126         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10127         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10128         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10129         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10130         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10131
10132         hr = IDirect3DDevice9_EndScene(device);
10133         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10134     }
10135
10136     color = getPixelColor(device, 320, 240);
10137     ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10138        color);
10139     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10140     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10141
10142     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10143     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10144 }
10145
10146 static void alphatest_test(IDirect3DDevice9 *device) {
10147 #define ALPHATEST_PASSED 0x0000ff00
10148 #define ALPHATEST_FAILED 0x00ff0000
10149     struct {
10150         D3DCMPFUNC  func;
10151         DWORD       color_less;
10152         DWORD       color_equal;
10153         DWORD       color_greater;
10154     } testdata[] = {
10155         {   D3DCMP_NEVER,           ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10156         {   D3DCMP_LESS,            ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10157         {   D3DCMP_EQUAL,           ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10158         {   D3DCMP_LESSEQUAL,       ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10159         {   D3DCMP_GREATER,         ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10160         {   D3DCMP_NOTEQUAL,        ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10161         {   D3DCMP_GREATEREQUAL,    ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10162         {   D3DCMP_ALWAYS,          ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10163     };
10164     unsigned int i, j;
10165     HRESULT hr;
10166     DWORD color;
10167     struct vertex quad[] = {
10168         {   -1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10169         {    1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10170         {   -1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10171         {    1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10172     };
10173     D3DCAPS9 caps;
10174
10175     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10176     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10177     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10178     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10179
10180     for(j = 0; j < 2; j++) {
10181         if(j == 1) {
10182             /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10183              * the alpha test either for performance reasons(floating point RTs) or to work
10184              * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10185              * codepath for ffp and shader in this case, and the test should cover both
10186              */
10187             IDirect3DPixelShader9 *ps;
10188             DWORD shader_code[] = {
10189                 0xffff0101,                                 /* ps_1_1           */
10190                 0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
10191                 0x0000ffff                                  /* end              */
10192             };
10193             memset(&caps, 0, sizeof(caps));
10194             IDirect3DDevice9_GetDeviceCaps(device, &caps);
10195             ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10196             if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10197                 break;
10198             }
10199
10200             hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10201             ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10202             IDirect3DDevice9_SetPixelShader(device, ps);
10203             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10204             IDirect3DPixelShader9_Release(ps);
10205         }
10206
10207         for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10208             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10209             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10210
10211             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10212             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10213             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10214             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10215             hr = IDirect3DDevice9_BeginScene(device);
10216             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10217             if(SUCCEEDED(hr)) {
10218                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10219                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10220                 hr = IDirect3DDevice9_EndScene(device);
10221                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10222             }
10223             color = getPixelColor(device, 320, 240);
10224             ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10225             color, testdata[i].color_less, testdata[i].func);
10226             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10227             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10228
10229             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10230             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10231             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10232             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10233             hr = IDirect3DDevice9_BeginScene(device);
10234             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10235             if(SUCCEEDED(hr)) {
10236                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10237                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10238                 hr = IDirect3DDevice9_EndScene(device);
10239                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10240             }
10241             color = getPixelColor(device, 320, 240);
10242             ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10243             color, testdata[i].color_equal, testdata[i].func);
10244             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10245             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10246
10247             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10248             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10249             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10250             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10251             hr = IDirect3DDevice9_BeginScene(device);
10252             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10253             if(SUCCEEDED(hr)) {
10254                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10255                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10256                 hr = IDirect3DDevice9_EndScene(device);
10257                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10258             }
10259             color = getPixelColor(device, 320, 240);
10260             ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10261             color, testdata[i].color_greater, testdata[i].func);
10262             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10263             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10264         }
10265     }
10266
10267     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10268     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10269     IDirect3DDevice9_SetPixelShader(device, NULL);
10270     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10271 }
10272
10273 static void sincos_test(IDirect3DDevice9 *device) {
10274     const DWORD sin_shader_code[] = {
10275         0xfffe0200,                                                                 /* vs_2_0                       */
10276         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10277         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10278         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10279         0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.y, r1.x, c0, c1    */
10280         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10281         0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002,                             /* mul oPos.y, r0.y, c2.w       */
10282         0x02000001, 0xd00f0000, 0xa0a60002,                                         /* mov oD0, c2.zyzz             */
10283         0x0000ffff                                                                  /* end                          */
10284     };
10285     const DWORD cos_shader_code[] = {
10286         0xfffe0200,                                                                 /* vs_2_0                       */
10287         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10288         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10289         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10290         0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.x, r1.x, c0, c1    */
10291         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10292         0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002,                             /* mul oPos.y, r0.x, c2.w       */
10293         0x02000001, 0xd00f0000, 0xa0a90002,                                         /* mov oD0, c2.yzzz             */
10294         0x0000ffff                                                                  /* end                          */
10295     };
10296     IDirect3DVertexShader9 *sin_shader, *cos_shader;
10297     HRESULT hr;
10298     struct {
10299         float x, y, z;
10300     } data[1280];
10301     unsigned int i;
10302     float sincosc1[4] = {D3DSINCOSCONST1};
10303     float sincosc2[4] = {D3DSINCOSCONST2};
10304
10305     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10306     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10307
10308     hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10309     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10310     hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10311     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10312     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10313     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10314     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10315     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10316     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10317     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10318
10319     /* Generate a point from -1 to 1 every 0.5 pixels */
10320     for(i = 0; i < 1280; i++) {
10321         data[i].x = (-640.0 + i) / 640.0;
10322         data[i].y = 0.0;
10323         data[i].z = 0.1;
10324     }
10325
10326     hr = IDirect3DDevice9_BeginScene(device);
10327     if(SUCCEEDED(hr)) {
10328         hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10329         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10330         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10331         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10332
10333         hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10334         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10335         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10336         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10337
10338         hr = IDirect3DDevice9_EndScene(device);
10339         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10340     }
10341     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10342     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10343     /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10344
10345     IDirect3DDevice9_SetVertexShader(device, NULL);
10346     IDirect3DVertexShader9_Release(sin_shader);
10347     IDirect3DVertexShader9_Release(cos_shader);
10348 }
10349
10350 static void loop_index_test(IDirect3DDevice9 *device) {
10351     const DWORD shader_code[] = {
10352         0xfffe0200,                                                 /* vs_2_0                   */
10353         0x0200001f, 0x80000000, 0x900f0000,                         /* dcl_position v0          */
10354         0x02000001, 0x800f0000, 0xa0e40000,                         /* mov r0, c0               */
10355         0x0200001b, 0xf0e40800, 0xf0e40000,                         /* loop aL, i0              */
10356         0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1]    */
10357         0x0000001d,                                                 /* endloop                  */
10358         0x02000001, 0xc00f0000, 0x90e40000,                         /* mov oPos, v0             */
10359         0x02000001, 0xd00f0000, 0x80e40000,                         /* mov oD0, r0              */
10360         0x0000ffff                                                  /* END                      */
10361     };
10362     IDirect3DVertexShader9 *shader;
10363     HRESULT hr;
10364     DWORD color;
10365     const float quad[] = {
10366         -1.0,   -1.0,   0.1,
10367          1.0,   -1.0,   0.1,
10368         -1.0,    1.0,   0.1,
10369          1.0,    1.0,   0.1
10370     };
10371     const float zero[4] = {0, 0, 0, 0};
10372     const float one[4] = {1, 1, 1, 1};
10373     int i0[4] = {2, 10, -3, 0};
10374     float values[4];
10375
10376     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10377     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10378     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10379     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10380     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10381     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10382     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10383     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10384
10385     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10386     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10387     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10388     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10389     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10390     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10391     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10392     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10393     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10394     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10395     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10396     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10397     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10398     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10399     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10400     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10401     values[0] = 1.0;
10402     values[1] = 1.0;
10403     values[2] = 0.0;
10404     values[3] = 0.0;
10405     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10406     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10407     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10408     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10409     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10410     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10411     values[0] = -1.0;
10412     values[1] = 0.0;
10413     values[2] = 0.0;
10414     values[3] = 0.0;
10415     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10416     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10417     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10418     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10419     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10420     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10421     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10422     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10423     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10424     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10425
10426     hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10427     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10428
10429     hr = IDirect3DDevice9_BeginScene(device);
10430     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10431     if(SUCCEEDED(hr))
10432     {
10433         trace("going to draw index\n");
10434         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10435         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10436         hr = IDirect3DDevice9_EndScene(device);
10437         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10438     }
10439     color = getPixelColor(device, 320, 240);
10440     ok(color_match(color, 0x0000ff00, 1),
10441        "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10442     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10443     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10444
10445     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10446     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10447     IDirect3DVertexShader9_Release(shader);
10448 }
10449
10450 static void sgn_test(IDirect3DDevice9 *device) {
10451     const DWORD shader_code[] = {
10452         0xfffe0200,                                                             /* vs_2_0                       */
10453         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position o0              */
10454         0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10455         0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0   */
10456         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
10457         0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002,             /* sgn r0, c0, r1, r2           */
10458         0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001,                         /* add oD0, r0, c1              */
10459         0x0000ffff                                                              /* end                          */
10460     };
10461     IDirect3DVertexShader9 *shader;
10462     HRESULT hr;
10463     DWORD color;
10464     const float quad[] = {
10465         -1.0,   -1.0,   0.1,
10466          1.0,   -1.0,   0.1,
10467         -1.0,    1.0,   0.1,
10468          1.0,    1.0,   0.1
10469     };
10470
10471     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10472     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10473     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10474     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10475     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10476     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10477     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10478     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10479
10480     hr = IDirect3DDevice9_BeginScene(device);
10481     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10482     if(SUCCEEDED(hr))
10483     {
10484         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10485         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10486         hr = IDirect3DDevice9_EndScene(device);
10487         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10488     }
10489     color = getPixelColor(device, 320, 240);
10490     ok(color_match(color, 0x008000ff, 1),
10491        "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10492     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10493     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10494
10495     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10496     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10497     IDirect3DVertexShader9_Release(shader);
10498 }
10499
10500 static void viewport_test(IDirect3DDevice9 *device) {
10501     HRESULT hr;
10502     DWORD color;
10503     D3DVIEWPORT9 vp, old_vp;
10504     const float quad[] =
10505     {
10506         -0.5,   -0.5,   0.1,
10507          0.5,   -0.5,   0.1,
10508         -0.5,    0.5,   0.1,
10509          0.5,    0.5,   0.1
10510     };
10511
10512     memset(&old_vp, 0, sizeof(old_vp));
10513     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10514     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10515
10516     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10517     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10518
10519     /* Test a viewport with Width and Height bigger than the surface dimensions
10520      *
10521      * TODO: Test Width < surface.width, but X + Width > surface.width
10522      * TODO: Test Width < surface.width, what happens with the height?
10523      */
10524     memset(&vp, 0, sizeof(vp));
10525     vp.X = 0;
10526     vp.Y = 0;
10527     vp.Width = 10000;
10528     vp.Height = 10000;
10529     vp.MinZ = 0.0;
10530     vp.MaxZ = 0.0;
10531     hr = IDirect3DDevice9_SetViewport(device, &vp);
10532     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10533
10534     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10535     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10536     hr = IDirect3DDevice9_BeginScene(device);
10537     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10538     if(SUCCEEDED(hr))
10539     {
10540         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10541         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10542         hr = IDirect3DDevice9_EndScene(device);
10543         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10544     }
10545
10546     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10547     color = getPixelColor(device, 158, 118);
10548     ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10549     color = getPixelColor(device, 162, 118);
10550     ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10551     color = getPixelColor(device, 158, 122);
10552     ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10553     color = getPixelColor(device, 162, 122);
10554     ok(color == 0x00ffffff, "viewport test: (162,122) has color %08x\n", color);
10555
10556     color = getPixelColor(device, 478, 358);
10557     ok(color == 0x00ffffff, "viewport test: (478,358 has color %08x\n", color);
10558     color = getPixelColor(device, 482, 358);
10559     ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10560     color = getPixelColor(device, 478, 362);
10561     ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10562     color = getPixelColor(device, 482, 362);
10563     ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10564
10565     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10566     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10567
10568     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10569     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10570 }
10571
10572 START_TEST(visual)
10573 {
10574     IDirect3DDevice9 *device_ptr;
10575     D3DCAPS9 caps;
10576     HRESULT hr;
10577     DWORD color;
10578
10579     d3d9_handle = LoadLibraryA("d3d9.dll");
10580     if (!d3d9_handle)
10581     {
10582         skip("Could not load d3d9.dll\n");
10583         return;
10584     }
10585
10586     device_ptr = init_d3d9();
10587     if (!device_ptr)
10588     {
10589         skip("Creating the device failed\n");
10590         return;
10591     }
10592
10593     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
10594
10595     /* Check for the reliability of the returned data */
10596     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
10597     if(FAILED(hr))
10598     {
10599         skip("Clear failed, can't assure correctness of the test results, skipping\n");
10600         goto cleanup;
10601     }
10602
10603     color = getPixelColor(device_ptr, 1, 1);
10604     if(color !=0x00ff0000)
10605     {
10606         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
10607         goto cleanup;
10608     }
10609     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
10610
10611     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
10612     if(FAILED(hr))
10613     {
10614         skip("Clear failed, can't assure correctness of the test results, skipping\n");
10615         goto cleanup;
10616     }
10617
10618     color = getPixelColor(device_ptr, 639, 479);
10619     if(color != 0x0000ddee)
10620     {
10621         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
10622         goto cleanup;
10623     }
10624     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
10625
10626     /* Now execute the real tests */
10627     stretchrect_test(device_ptr);
10628     lighting_test(device_ptr);
10629     clear_test(device_ptr);
10630     fog_test(device_ptr);
10631     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
10632     {
10633         test_cube_wrap(device_ptr);
10634     } else {
10635         skip("No cube texture support\n");
10636     }
10637     z_range_test(device_ptr);
10638     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
10639     {
10640         maxmip_test(device_ptr);
10641     }
10642     else
10643     {
10644         skip("No mipmap support\n");
10645     }
10646     offscreen_test(device_ptr);
10647     alpha_test(device_ptr);
10648     shademode_test(device_ptr);
10649     srgbtexture_test(device_ptr);
10650     release_buffer_test(device_ptr);
10651     float_texture_test(device_ptr);
10652     g16r16_texture_test(device_ptr);
10653     pixelshader_blending_test(device_ptr);
10654     texture_transform_flags_test(device_ptr);
10655     autogen_mipmap_test(device_ptr);
10656     fixed_function_decl_test(device_ptr);
10657     conditional_np2_repeat_test(device_ptr);
10658     fixed_function_bumpmap_test(device_ptr);
10659     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
10660         stencil_cull_test(device_ptr);
10661     } else {
10662         skip("No two sided stencil support\n");
10663     }
10664     pointsize_test(device_ptr);
10665     tssargtemp_test(device_ptr);
10666     np2_stretch_rect_test(device_ptr);
10667     yuv_color_test(device_ptr);
10668     zwriteenable_test(device_ptr);
10669     alphatest_test(device_ptr);
10670     viewport_test(device_ptr);
10671
10672     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
10673     {
10674         test_constant_clamp_vs(device_ptr);
10675         test_compare_instructions(device_ptr);
10676     }
10677     else skip("No vs_1_1 support\n");
10678
10679     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
10680     {
10681         test_mova(device_ptr);
10682         loop_index_test(device_ptr);
10683         sincos_test(device_ptr);
10684         sgn_test(device_ptr);
10685         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
10686             test_vshader_input(device_ptr);
10687             test_vshader_float16(device_ptr);
10688             stream_test(device_ptr);
10689         } else {
10690             skip("No vs_3_0 support\n");
10691         }
10692     }
10693     else skip("No vs_2_0 support\n");
10694
10695     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
10696     {
10697         fog_with_shader_test(device_ptr);
10698         fog_srgbwrite_test(device_ptr);
10699     }
10700     else skip("No vs_1_1 and ps_1_1 support\n");
10701
10702     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
10703     {
10704         texbem_test(device_ptr);
10705         texdepth_test(device_ptr);
10706         texkill_test(device_ptr);
10707         x8l8v8u8_test(device_ptr);
10708         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
10709             constant_clamp_ps_test(device_ptr);
10710             cnd_test(device_ptr);
10711             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
10712                 dp2add_ps_test(device_ptr);
10713                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
10714                     nested_loop_test(device_ptr);
10715                     fixed_function_varying_test(device_ptr);
10716                     vFace_register_test(device_ptr);
10717                     vpos_register_test(device_ptr);
10718                     multiple_rendertargets_test(device_ptr);
10719                     if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
10720                         vshader_version_varying_test(device_ptr);
10721                         pshader_version_varying_test(device_ptr);
10722                     } else {
10723                         skip("No vs_3_0 support\n");
10724                     }
10725                 } else {
10726                     skip("No ps_3_0 support\n");
10727                 }
10728             } else {
10729                 skip("No ps_2_0 support\n");
10730             }
10731         }
10732     }
10733     else skip("No ps_1_1 support\n");
10734
10735     texop_test(device_ptr);
10736     texop_range_test(device_ptr);
10737     alphareplicate_test(device_ptr);
10738     dp3_alpha_test(device_ptr);
10739
10740 cleanup:
10741     if(device_ptr) {
10742         D3DPRESENT_PARAMETERS present_parameters;
10743         IDirect3DSwapChain9 *swapchain;
10744         ULONG ref;
10745
10746         IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
10747         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
10748         DestroyWindow(present_parameters.hDeviceWindow);
10749         IDirect3DSwapChain9_Release(swapchain);
10750         ref = IDirect3DDevice9_Release(device_ptr);
10751         ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
10752     }
10753 }