user32: Use the stored color and mask bitmaps instead of the raw bits in GetIconInfo.
[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 static void color_fill_test(IDirect3DDevice9 *device)
642 {
643     HRESULT hr;
644     IDirect3DSurface9 *backbuffer = NULL;
645     IDirect3DSurface9 *rt_surface = NULL;
646     IDirect3DSurface9 *offscreen_surface = NULL;
647     DWORD fill_color, color;
648
649     /* Test ColorFill on a the backbuffer (should pass) */
650     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
651     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
652     if(backbuffer)
653     {
654         fill_color = 0x112233;
655         hr = IDirect3DDevice9_ColorFill(device, backbuffer, NULL, fill_color);
656
657         color = getPixelColor(device, 0, 0);
658         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
659
660         IDirect3DSurface9_Release(backbuffer);
661     }
662
663     /* Test ColorFill on a render target surface (should pass) */
664     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt_surface, NULL );
665     ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
666     if(rt_surface)
667     {
668         fill_color = 0x445566;
669         hr = IDirect3DDevice9_ColorFill(device, rt_surface, NULL, fill_color);
670
671         color = getPixelColorFromSurface(rt_surface, 0, 0);
672         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
673
674         IDirect3DSurface9_Release(rt_surface);
675     }
676
677     /* Test ColorFill on a offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
678     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
679             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen_surface, NULL);
680     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
681     if(offscreen_surface)
682     {
683         fill_color = 0x778899;
684         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, fill_color);
685
686         color = getPixelColorFromSurface(offscreen_surface, 0, 0);
687         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
688
689         IDirect3DSurface9_Release(offscreen_surface);
690     }
691
692     /* Try ColorFill on a offscreen surface in sysmem (should fail) */
693     offscreen_surface = NULL;
694     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
695             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &offscreen_surface, NULL);
696     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
697     if(offscreen_surface)
698     {
699         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, 0);
700         ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
701
702         IDirect3DSurface9_Release(offscreen_surface);
703     }
704 }
705
706 typedef struct {
707     float in[4];
708     DWORD out;
709 } test_data_t;
710
711 /*
712  *  c7      mova    ARGB            mov     ARGB
713  * -2.4     -2      0x00ffff00      -3      0x00ff0000
714  * -1.6     -2      0x00ffff00      -2      0x00ffff00
715  * -0.4      0      0x0000ffff      -1      0x0000ff00
716  *  0.4      0      0x0000ffff       0      0x0000ffff
717  *  1.6      2      0x00ff00ff       1      0x000000ff
718  *  2.4      2      0x00ff00ff       2      0x00ff00ff
719  */
720 static void test_mova(IDirect3DDevice9 *device)
721 {
722     static const DWORD mova_test[] = {
723         0xfffe0200,                                                             /* vs_2_0                       */
724         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
725         0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
726         0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
727         0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
728         0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
729         0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
730         0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
731         0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
732         0x0200002e, 0xb0010000, 0xa0000007,                                     /* mova a0.x, c7.x              */
733         0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000,                         /* mov oD0, c[a0.x + 3]         */
734         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
735         0x0000ffff                                                              /* END                          */
736     };
737     static const DWORD mov_test[] = {
738         0xfffe0101,                                                             /* vs_1_1                       */
739         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
740         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
741         0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
742         0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
743         0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
744         0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
745         0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
746         0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
747         0x00000001, 0xb0010000, 0xa0000007,                                     /* mov a0.x, c7.x               */
748         0x00000001, 0xd00f0000, 0xa0e42003,                                     /* mov oD0, c[a0.x + 3]         */
749         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
750         0x0000ffff                                                              /* END                          */
751     };
752
753     static const test_data_t test_data[2][6] = {
754         {
755             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
756             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
757             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
758             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
759             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
760             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
761         },
762         {
763             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
764             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
765             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
766             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
767             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
768             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
769         }
770     };
771
772     static const float quad[][3] = {
773         {-1.0f, -1.0f, 0.0f},
774         {-1.0f,  1.0f, 0.0f},
775         { 1.0f, -1.0f, 0.0f},
776         { 1.0f,  1.0f, 0.0f},
777     };
778
779     static const D3DVERTEXELEMENT9 decl_elements[] = {
780         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
781         D3DDECL_END()
782     };
783
784     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
785     IDirect3DVertexShader9 *mova_shader = NULL;
786     IDirect3DVertexShader9 *mov_shader = NULL;
787     HRESULT hr;
788     UINT i, j;
789
790     hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
791     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
792     hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
793     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
794     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
795     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
796     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
797     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
798
799     hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
800     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
801     for(j = 0; j < 2; ++j)
802     {
803         for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
804         {
805             DWORD color;
806
807             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
808             ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
809
810             hr = IDirect3DDevice9_BeginScene(device);
811             ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
812
813             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
814             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
815
816             hr = IDirect3DDevice9_EndScene(device);
817             ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
818
819             color = getPixelColor(device, 320, 240);
820             ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
821                test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
822
823             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
824             ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
825
826             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
827             ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
828         }
829         hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
830         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
831     }
832
833     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
834     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
835
836     IDirect3DVertexDeclaration9_Release(vertex_declaration);
837     IDirect3DVertexShader9_Release(mova_shader);
838     IDirect3DVertexShader9_Release(mov_shader);
839 }
840
841 struct sVertex {
842     float x, y, z;
843     DWORD diffuse;
844     DWORD specular;
845 };
846
847 struct sVertexT {
848     float x, y, z, rhw;
849     DWORD diffuse;
850     DWORD specular;
851 };
852
853 static void fog_test(IDirect3DDevice9 *device)
854 {
855     HRESULT hr;
856     D3DCOLOR color;
857     float start = 0.0f, end = 1.0f;
858     D3DCAPS9 caps;
859     int i;
860
861     /* Gets full z based fog with linear fog, no fog with specular color */
862     struct sVertex unstransformed_1[] = {
863         {-1,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
864         {-1,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
865         { 0,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
866         { 0,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
867     };
868     /* Ok, I am too lazy to deal with transform matrices */
869     struct sVertex unstransformed_2[] = {
870         {-1,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
871         {-1,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
872         { 0,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
873         { 0,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
874     };
875     /* Untransformed ones. Give them a different diffuse color to make the test look
876      * nicer. It also makes making sure that they are drawn correctly easier.
877      */
878     struct sVertexT transformed_1[] = {
879         {320,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
880         {640,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
881         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
882         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
883     };
884     struct sVertexT transformed_2[] = {
885         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
886         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
887         {640,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
888         {320,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
889     };
890     struct vertex rev_fog_quads[] = {
891        {-1.0,   -1.0,   0.1,    0x000000ff},
892        {-1.0,    0.0,   0.1,    0x000000ff},
893        { 0.0,    0.0,   0.1,    0x000000ff},
894        { 0.0,   -1.0,   0.1,    0x000000ff},
895
896        { 0.0,   -1.0,   0.9,    0x000000ff},
897        { 0.0,    0.0,   0.9,    0x000000ff},
898        { 1.0,    0.0,   0.9,    0x000000ff},
899        { 1.0,   -1.0,   0.9,    0x000000ff},
900
901        { 0.0,    0.0,   0.4,    0x000000ff},
902        { 0.0,    1.0,   0.4,    0x000000ff},
903        { 1.0,    1.0,   0.4,    0x000000ff},
904        { 1.0,    0.0,   0.4,    0x000000ff},
905
906        {-1.0,    0.0,   0.7,    0x000000ff},
907        {-1.0,    1.0,   0.7,    0x000000ff},
908        { 0.0,    1.0,   0.7,    0x000000ff},
909        { 0.0,    0.0,   0.7,    0x000000ff},
910     };
911     WORD Indices[] = {0, 1, 2, 2, 3, 0};
912
913     memset(&caps, 0, sizeof(caps));
914     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
915     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
916     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
917     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
918
919     /* Setup initial states: No lighting, fog on, fog color */
920     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
921     ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
922     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
923     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
924     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
925     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
926
927     /* First test: Both table fog and vertex fog off */
928     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
929     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
930     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
931     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
932
933     /* Start = 0, end = 1. Should be default, but set them */
934     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
935     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
936     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
937     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
938
939     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
940     {
941         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
942         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
943         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
944         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
945                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
946                                                      sizeof(unstransformed_1[0]));
947         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
948
949         /* That makes it use the Z value */
950         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
951         ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
952         /* Untransformed, vertex fog != none (or table fog != none):
953          * Use the Z value as input into the equation
954          */
955         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
956                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
957                                                      sizeof(unstransformed_1[0]));
958         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
959
960         /* transformed verts */
961         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
962         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
963         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
964         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
965                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
966                                                      sizeof(transformed_1[0]));
967         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
968
969         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
970         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
971         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
972          * equation
973          */
974         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
975                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
976                                                      sizeof(transformed_2[0]));
977         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
978
979         hr = IDirect3DDevice9_EndScene(device);
980         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
981     }
982     else
983     {
984         ok(FALSE, "BeginScene failed\n");
985     }
986
987     color = getPixelColor(device, 160, 360);
988     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
989     color = getPixelColor(device, 160, 120);
990     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
991     color = getPixelColor(device, 480, 120);
992     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
993     if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
994     {
995         color = getPixelColor(device, 480, 360);
996         ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
997     }
998     else
999     {
1000         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1001          * The settings above result in no fogging with vertex fog
1002          */
1003         color = getPixelColor(device, 480, 120);
1004         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1005         trace("Info: Table fog not supported by this device\n");
1006     }
1007     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1008
1009     /* Now test the special case fogstart == fogend */
1010     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1011     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1012
1013     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1014     {
1015         start = 512;
1016         end = 512;
1017         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1018         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1019         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1020         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1021
1022         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1023         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1024         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1025         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1026         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1027         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1028
1029         /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
1030          * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
1031          * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
1032          * The third transformed quad remains unfogged because the fogcoords are read from the specular
1033          * color and has fixed fogstart and fogend.
1034          */
1035         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1036                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
1037                 sizeof(unstransformed_1[0]));
1038         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1039         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1040                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
1041                 sizeof(unstransformed_1[0]));
1042         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1043
1044         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1045         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1046         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1047         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1048                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1049                 sizeof(transformed_1[0]));
1050         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1051
1052         hr = IDirect3DDevice9_EndScene(device);
1053         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1054     }
1055     else
1056     {
1057         ok(FALSE, "BeginScene failed\n");
1058     }
1059     color = getPixelColor(device, 160, 360);
1060     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1061     color = getPixelColor(device, 160, 120);
1062     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1063     color = getPixelColor(device, 480, 120);
1064     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1065     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1066
1067     /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1068      * but without shaders it seems to work everywhere
1069      */
1070     end = 0.2;
1071     start = 0.8;
1072     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1073     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1074     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1075     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1076     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1077     ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1078
1079     /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1080      * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1081      * so skip this for now
1082      */
1083     for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1084         const char *mode = (i ? "table" : "vertex");
1085         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1086         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1087         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1088         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1089         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1090         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1091         hr = IDirect3DDevice9_BeginScene(device);
1092         ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1093         if(SUCCEEDED(hr)) {
1094             WORD Indices2[] = { 0,  1,  2,  2,  3, 0,
1095                                 4,  5,  6,  6,  7, 4,
1096                                 8,  9, 10, 10, 11, 8,
1097                             12, 13, 14, 14, 15, 12};
1098
1099             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1100                     16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1101                     sizeof(rev_fog_quads[0]));
1102             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1103
1104             hr = IDirect3DDevice9_EndScene(device);
1105             ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1106         }
1107         color = getPixelColor(device, 160, 360);
1108         ok(color_match(color, 0x0000ff00, 1),
1109                 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1110
1111         color = getPixelColor(device, 160, 120);
1112         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1113                 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1114
1115         color = getPixelColor(device, 480, 120);
1116         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1117                 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1118
1119         color = getPixelColor(device, 480, 360);
1120         ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1121
1122         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1123
1124         if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1125             skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1126             break;
1127         }
1128     }
1129     /* Turn off the fog master switch to avoid confusing other tests */
1130     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1131     ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1132     start = 0.0;
1133     end = 1.0;
1134     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1135     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1136     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1137     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1138     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1139     ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1140     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1141     ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1142 }
1143
1144 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1145  * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1146  * regardless of the actual addressing mode set. The way this test works is
1147  * that we sample in one of the corners of the cubemap with filtering enabled,
1148  * and check the interpolated color. There are essentially two reasonable
1149  * things an implementation can do: Either pick one of the faces and
1150  * interpolate the edge texel with itself (i.e., clamp within the face), or
1151  * interpolate between the edge texels of the three involved faces. It should
1152  * never involve the border color or the other side (texcoord wrapping) of a
1153  * face in the interpolation. */
1154 static void test_cube_wrap(IDirect3DDevice9 *device)
1155 {
1156     static const float quad[][6] = {
1157         {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1158         {-1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1159         { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1160         { 1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1161     };
1162
1163     static const D3DVERTEXELEMENT9 decl_elements[] = {
1164         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1165         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1166         D3DDECL_END()
1167     };
1168
1169     static const struct {
1170         D3DTEXTUREADDRESS mode;
1171         const char *name;
1172     } address_modes[] = {
1173         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1174         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1175         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1176         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1177         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1178     };
1179
1180     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1181     IDirect3DCubeTexture9 *texture = NULL;
1182     IDirect3DSurface9 *surface = NULL;
1183     IDirect3DSurface9 *face_surface;
1184     D3DLOCKED_RECT locked_rect;
1185     HRESULT hr;
1186     UINT x;
1187     INT y, face;
1188
1189     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1190     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1191     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1192     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1193
1194     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1195             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1196     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1197
1198     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1199             D3DPOOL_DEFAULT, &texture, NULL);
1200     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1201
1202     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1203     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1204
1205     for (y = 0; y < 128; ++y)
1206     {
1207         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1208         for (x = 0; x < 64; ++x)
1209         {
1210             *ptr++ = 0xff0000dd;
1211         }
1212         for (x = 64; x < 128; ++x)
1213         {
1214             *ptr++ = 0xffff0000;
1215         }
1216     }
1217
1218     hr = IDirect3DSurface9_UnlockRect(surface);
1219     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1220
1221     hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
1222     ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1223
1224     hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1225     ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1226
1227     IDirect3DSurface9_Release(face_surface);
1228
1229     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1230     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1231
1232     for (y = 0; y < 128; ++y)
1233     {
1234         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1235         for (x = 0; x < 64; ++x)
1236         {
1237             *ptr++ = 0xffff0000;
1238         }
1239         for (x = 64; x < 128; ++x)
1240         {
1241             *ptr++ = 0xff0000ff;
1242         }
1243     }
1244
1245     hr = IDirect3DSurface9_UnlockRect(surface);
1246     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1247
1248     /* Create cube faces */
1249     for (face = 1; face < 6; ++face)
1250     {
1251         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1252         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1253
1254         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1255         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1256
1257         IDirect3DSurface9_Release(face_surface);
1258     }
1259
1260     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1261     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1262
1263     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1264     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1265     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1266     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1267     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1268     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1269
1270     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1271     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1272
1273     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1274     {
1275         DWORD color;
1276
1277         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1278         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1279         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1280         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1281
1282         hr = IDirect3DDevice9_BeginScene(device);
1283         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1284
1285         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1286         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1287
1288         hr = IDirect3DDevice9_EndScene(device);
1289         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1290
1291         color = getPixelColor(device, 320, 240);
1292         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 11),
1293                 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
1294                 color, address_modes[x].name);
1295
1296         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1297         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1298
1299         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1300         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1301     }
1302
1303     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1304     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1305
1306     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1307     IDirect3DCubeTexture9_Release(texture);
1308     IDirect3DSurface9_Release(surface);
1309 }
1310
1311 static void offscreen_test(IDirect3DDevice9 *device)
1312 {
1313     HRESULT hr;
1314     IDirect3DTexture9 *offscreenTexture = NULL;
1315     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1316     DWORD color;
1317
1318     static const float quad[][5] = {
1319         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1320         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1321         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1322         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1323     };
1324
1325     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1326     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1327
1328     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1329     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1330     if(!offscreenTexture) {
1331         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1332         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1333         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1334         if(!offscreenTexture) {
1335             skip("Cannot create an offscreen render target\n");
1336             goto out;
1337         }
1338     }
1339
1340     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1341     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1342     if(!backbuffer) {
1343         goto out;
1344     }
1345
1346     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1347     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1348     if(!offscreen) {
1349         goto out;
1350     }
1351
1352     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1353     ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1354
1355     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1356     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1357     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1358     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1359     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1360     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1361     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1362     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1363     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1364     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1365
1366     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1367         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1368         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1369         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1370         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1371
1372         /* Draw without textures - Should result in a white quad */
1373         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1374         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1375
1376         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1377         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1378         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1379         ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1380
1381         /* This time with the texture */
1382         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1383         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1384
1385         IDirect3DDevice9_EndScene(device);
1386     }
1387
1388     /* Center quad - should be white */
1389     color = getPixelColor(device, 320, 240);
1390     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1391     /* Some quad in the cleared part of the texture */
1392     color = getPixelColor(device, 170, 240);
1393     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1394     /* Part of the originally cleared back buffer */
1395     color = getPixelColor(device, 10, 10);
1396     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1397     if(0) {
1398         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1399          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1400          * the offscreen rendering mode this test would succeed or fail
1401          */
1402         color = getPixelColor(device, 10, 470);
1403         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1404     }
1405
1406     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1407
1408 out:
1409     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1410     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1411
1412     /* restore things */
1413     if(backbuffer) {
1414         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1415         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1416         IDirect3DSurface9_Release(backbuffer);
1417     }
1418     if(offscreenTexture) {
1419         IDirect3DTexture9_Release(offscreenTexture);
1420     }
1421     if(offscreen) {
1422         IDirect3DSurface9_Release(offscreen);
1423     }
1424 }
1425
1426 /* This test tests fog in combination with shaders.
1427  * What's tested: linear fog (vertex and table) with pixel shader
1428  *                linear table fog with non foggy vertex shader
1429  *                vertex fog with foggy vertex shader, non-linear
1430  *                fog with shader, non-linear fog with foggy shader,
1431  *                linear table fog with foggy shader
1432  */
1433 static void fog_with_shader_test(IDirect3DDevice9 *device)
1434 {
1435     HRESULT hr;
1436     DWORD color;
1437     union {
1438         float f;
1439         DWORD i;
1440     } start, end;
1441     unsigned int i, j;
1442
1443     /* basic vertex shader without fog computation ("non foggy") */
1444     static const DWORD vertex_shader_code1[] = {
1445         0xfffe0101,                                                             /* vs_1_1                       */
1446         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1447         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1448         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1449         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1450         0x0000ffff
1451     };
1452     /* basic vertex shader with reversed fog computation ("foggy") */
1453     static const DWORD vertex_shader_code2[] = {
1454         0xfffe0101,                                                             /* vs_1_1                        */
1455         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1456         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1457         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1458         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1459         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1460         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1461         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1462         0x0000ffff
1463     };
1464     /* basic pixel shader */
1465     static const DWORD pixel_shader_code[] = {
1466         0xffff0101,                                                             /* ps_1_1     */
1467         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, vo */
1468         0x0000ffff
1469     };
1470
1471     static struct vertex quad[] = {
1472         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1473         {-1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1474         { 1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1475         { 1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1476     };
1477
1478     static const D3DVERTEXELEMENT9 decl_elements[] = {
1479         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1480         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1481         D3DDECL_END()
1482     };
1483
1484     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1485     IDirect3DVertexShader9      *vertex_shader[3]   = {NULL, NULL, NULL};
1486     IDirect3DPixelShader9       *pixel_shader[2]    = {NULL, NULL};
1487
1488     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1489     static const struct test_data_t {
1490         int vshader;
1491         int pshader;
1492         D3DFOGMODE vfog;
1493         D3DFOGMODE tfog;
1494         unsigned int color[11];
1495     } test_data[] = {
1496         /* only pixel shader: */
1497         {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1498         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1499         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1500         {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1501         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1502         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1503         {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1504         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1505         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1506         {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1507         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1508         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1509         {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1510         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1511         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1512
1513         /* vertex shader */
1514         {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1515         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1516          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1517         {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1518         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1519         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1520         {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1521         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1522         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1523
1524         {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1525         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1526         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1527         {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1528         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1529         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1530
1531         /* vertex shader and pixel shader */
1532         /* The next 4 tests would read the fog coord output, but it isn't available.
1533          * The result is a fully fogged quad, no matter what the Z coord is. This is on
1534          * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1535          * These tests should be disabled if some other hardware behaves differently
1536          */
1537         {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1538         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1539         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1540         {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1541         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1542         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1543         {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1544         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1545         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1546         {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1547         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1548         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1549
1550         /* These use the Z coordinate with linear table fog */
1551         {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1552         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1553         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1554         {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1555         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1556         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1557         {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1558         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1559         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1560         {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1561         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1562         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1563
1564         /* Non-linear table fog without fog coord */
1565         {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1566         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1567         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1568         {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1569         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1570         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1571
1572 #if 0  /* FIXME: these fail on GeForce 8500 */
1573         /* foggy vertex shader */
1574         {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1575         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1576          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1577         {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1578         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1579          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1580         {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1581         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1582          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1583         {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1584         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1585          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1586 #endif
1587
1588         /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1589          * all using the fixed fog-coord linear fog
1590          */
1591         {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1592         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1593          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1594         {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1595         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1596          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1597         {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1598         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1599          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1600         {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1601         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1602          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1603
1604         /* These use table fog. Here the shader-provided fog coordinate is
1605          * ignored and the z coordinate used instead
1606          */
1607         {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1608         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1609         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1610         {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1611         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1612         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1613         {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1614         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1615         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1616     };
1617
1618     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1619     start.f=0.1f;
1620     end.f=0.9f;
1621
1622     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1623     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1624     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1625     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1626     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1627     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1628     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1629     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1630
1631     /* Setup initial states: No lighting, fog on, fog color */
1632     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1633     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1634     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1635     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1636     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1637     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1638     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1639     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1640
1641     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1642     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1643     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1644     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1645
1646     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1647     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1648     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1649     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1650     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1651
1652     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1653     {
1654         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1655         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1656         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1657         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1658         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1659         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1660         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1661         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1662
1663         for(j=0; j < 11; j++)
1664         {
1665             /* Don't use the whole zrange to prevent rounding errors */
1666             quad[0].z = 0.001f + (float)j / 10.02f;
1667             quad[1].z = 0.001f + (float)j / 10.02f;
1668             quad[2].z = 0.001f + (float)j / 10.02f;
1669             quad[3].z = 0.001f + (float)j / 10.02f;
1670
1671             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1672             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1673
1674             hr = IDirect3DDevice9_BeginScene(device);
1675             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1676
1677             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1678             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1679
1680             hr = IDirect3DDevice9_EndScene(device);
1681             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1682
1683             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1684             color = getPixelColor(device, 128, 240);
1685             ok(color_match(color, test_data[i].color[j], 13),
1686                 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1687                 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1688
1689             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1690         }
1691     }
1692
1693     /* reset states */
1694     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1695     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1696     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1697     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1698     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1699     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1700     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1701     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1702
1703     IDirect3DVertexShader9_Release(vertex_shader[1]);
1704     IDirect3DVertexShader9_Release(vertex_shader[2]);
1705     IDirect3DPixelShader9_Release(pixel_shader[1]);
1706     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1707 }
1708
1709 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1710     unsigned int i, x, y;
1711     HRESULT hr;
1712     IDirect3DTexture9 *texture[2] = {NULL, NULL};
1713     D3DLOCKED_RECT locked_rect;
1714
1715     /* Generate the textures */
1716     for(i=0; i<2; i++)
1717     {
1718         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1719                                             D3DPOOL_MANAGED, &texture[i], NULL);
1720         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1721
1722         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1723         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1724         for (y = 0; y < 128; ++y)
1725         {
1726             if(i)
1727             { /* Set up black texture with 2x2 texel white spot in the middle */
1728                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1729                 for (x = 0; x < 128; ++x)
1730                 {
1731                     if(y>62 && y<66 && x>62 && x<66)
1732                         *ptr++ = 0xffffffff;
1733                     else
1734                         *ptr++ = 0xff000000;
1735                 }
1736             }
1737             else
1738             { /* Set up a displacement map which points away from the center parallel to the closest axis.
1739                * (if multiplied with bumpenvmat)
1740               */
1741                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1742                 for (x = 0; x < 128; ++x)
1743                 {
1744                     if(abs(x-64)>abs(y-64))
1745                     {
1746                         if(x < 64)
1747                             *ptr++ = 0xc000;
1748                         else
1749                             *ptr++ = 0x4000;
1750                     }
1751                     else
1752                     {
1753                         if(y < 64)
1754                             *ptr++ = 0x0040;
1755                         else
1756                             *ptr++ = 0x00c0;
1757                     }
1758                 }
1759             }
1760         }
1761         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1762         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1763
1764         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1765         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1766
1767         /* Disable texture filtering */
1768         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1769         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1770         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1771         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1772
1773         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1774         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1775         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1776         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1777     }
1778 }
1779
1780 /* test the behavior of the texbem instruction
1781  * with normal 2D and projective 2D textures
1782  */
1783 static void texbem_test(IDirect3DDevice9 *device)
1784 {
1785     HRESULT hr;
1786     DWORD color;
1787     int i;
1788
1789     static const DWORD pixel_shader_code[] = {
1790         0xffff0101,                         /* ps_1_1*/
1791         0x00000042, 0xb00f0000,             /* tex t0*/
1792         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1793         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1794         0x0000ffff
1795     };
1796     static const DWORD double_texbem_code[] =  {
1797         0xffff0103,                                         /* ps_1_3           */
1798         0x00000042, 0xb00f0000,                             /* tex t0           */
1799         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
1800         0x00000042, 0xb00f0002,                             /* tex t2           */
1801         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
1802         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
1803         0x0000ffff                                          /* end              */
1804     };
1805
1806
1807     static const float quad[][7] = {
1808         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1809         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1810         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1811         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1812     };
1813     static const float quad_proj[][9] = {
1814         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
1815         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
1816         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
1817         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1818     };
1819
1820     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1821         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1822         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1823         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1824         D3DDECL_END()
1825     },{
1826         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1827         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1828         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1829         D3DDECL_END()
1830     } };
1831
1832     /* use asymmetric matrix to test loading */
1833     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1834
1835     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1836     IDirect3DPixelShader9       *pixel_shader       = NULL;
1837     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
1838     D3DLOCKED_RECT locked_rect;
1839
1840     generate_bumpmap_textures(device);
1841
1842     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1843     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1844     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1845     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1846     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1847
1848     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1849     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1850
1851     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1852     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1853
1854     for(i=0; i<2; i++)
1855     {
1856         if(i)
1857         {
1858             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1859             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1860         }
1861
1862         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1863         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1864         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1865         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1866
1867         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1868         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1869         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1870         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1871
1872         hr = IDirect3DDevice9_BeginScene(device);
1873         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1874
1875         if(!i)
1876             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1877         else
1878             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1879         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1880
1881         hr = IDirect3DDevice9_EndScene(device);
1882         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1883
1884         color = getPixelColor(device, 320-32, 240);
1885         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1886         color = getPixelColor(device, 320+32, 240);
1887         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1888         color = getPixelColor(device, 320, 240-32);
1889         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1890         color = getPixelColor(device, 320, 240+32);
1891         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1892
1893         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1894         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1895
1896         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1897         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1898         IDirect3DPixelShader9_Release(pixel_shader);
1899
1900         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1901         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1902         IDirect3DVertexDeclaration9_Release(vertex_declaration);
1903     }
1904
1905     /* clean up */
1906     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1907     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1908
1909     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1910     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1911
1912     for(i=0; i<2; i++)
1913     {
1914         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1915         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1916         IDirect3DTexture9_Release(texture); /* For the GetTexture */
1917         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1918         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1919         IDirect3DTexture9_Release(texture);
1920     }
1921
1922     /* Test double texbem */
1923     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1924     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1925     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1926     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1927     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1928     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1929     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1930     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1931
1932     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1933     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1934     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1935     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1936
1937     hr = IDirect3DTexture9_UnlockRect(texture, 0);
1938     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1939
1940     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1941     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1942     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1943     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1944     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1945     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1946
1947     {
1948         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1949 #define tex  0x00ff0000
1950 #define tex1 0x0000ff00
1951 #define origin 0x000000ff
1952         static const DWORD pixel_data[] = {
1953             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1954             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1955             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1956             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1957             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
1958             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1959             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1960             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1961         };
1962 #undef tex1
1963 #undef tex2
1964 #undef origin
1965
1966         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1967         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1968         for(i = 0; i < 8; i++) {
1969             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1970         }
1971         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1972         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1973     }
1974
1975     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1976     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1977     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1978     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1979     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1980     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1981     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1982     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1983     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1984     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1985     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1986     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1987
1988     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
1989     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
1990     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1991     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1992     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1993     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1994     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1995     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1996     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1997     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1998
1999     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
2000     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
2001     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2002     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2003     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2004     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2005     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2006     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2007     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2008     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2009
2010     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2011     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2012     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2013     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2014     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2015     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2016     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2017     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2018     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2019     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2020     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2021     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2022     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2023     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2024     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2025     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2026
2027     hr = IDirect3DDevice9_BeginScene(device);
2028     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2029     if(SUCCEEDED(hr)) {
2030         static const float double_quad[] = {
2031             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2032              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2033             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2034              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2035         };
2036
2037         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
2038         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2039         hr = IDirect3DDevice9_EndScene(device);
2040         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2041     }
2042     color = getPixelColor(device, 320, 240);
2043     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2044
2045     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2046     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2047     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
2048     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2049     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
2050     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2051     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
2052     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2053     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2054     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2055
2056     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2057     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2058
2059     IDirect3DPixelShader9_Release(pixel_shader);
2060     IDirect3DTexture9_Release(texture);
2061     IDirect3DTexture9_Release(texture1);
2062     IDirect3DTexture9_Release(texture2);
2063 }
2064
2065 static void z_range_test(IDirect3DDevice9 *device)
2066 {
2067     const struct vertex quad[] =
2068     {
2069         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
2070         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
2071         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
2072         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
2073     };
2074     const struct vertex quad2[] =
2075     {
2076         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
2077         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
2078         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
2079         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
2080     };
2081
2082     const struct tvertex quad3[] =
2083     {
2084         {    0,   240,   1.1f,  1.0,                    0xffffff00},
2085         {    0,   480,   1.1f,  1.0,                    0xffffff00},
2086         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
2087         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
2088     };
2089     const struct tvertex quad4[] =
2090     {
2091         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
2092         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
2093         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
2094         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
2095     };
2096     HRESULT hr;
2097     DWORD color;
2098     IDirect3DVertexShader9 *shader;
2099     IDirect3DVertexDeclaration9 *decl;
2100     D3DCAPS9 caps;
2101     const DWORD shader_code[] = {
2102         0xfffe0101,                                     /* vs_1_1           */
2103         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
2104         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
2105         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
2106         0x0000ffff                                      /* end              */
2107     };
2108     static const D3DVERTEXELEMENT9 decl_elements[] = {
2109         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2110         D3DDECL_END()
2111     };
2112     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2113      * then call Present. Then clear the color buffer to make sure it has some defined content
2114      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2115      * by the depth value.
2116      */
2117     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2118     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2119     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2120     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2121     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2122     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2123
2124     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2125     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2126     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2127     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2128     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2129     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2130     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2131     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2132     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2133     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2134
2135     hr = IDirect3DDevice9_BeginScene(device);
2136     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2137     if(hr == D3D_OK)
2138     {
2139         /* Test the untransformed vertex path */
2140         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2141         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2142         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2143         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2144         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2145         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2146
2147         /* Test the transformed vertex path */
2148         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2149         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2150
2151         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2152         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2153         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2154         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2155         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2156         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2157
2158         hr = IDirect3DDevice9_EndScene(device);
2159         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2160     }
2161
2162     /* Do not test the exact corner pixels, but go pretty close to them */
2163
2164     /* Clipped because z > 1.0 */
2165     color = getPixelColor(device, 28, 238);
2166     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2167     color = getPixelColor(device, 28, 241);
2168     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2169
2170     /* Not clipped, > z buffer clear value(0.75) */
2171     color = getPixelColor(device, 31, 238);
2172     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2173     color = getPixelColor(device, 31, 241);
2174     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2175     color = getPixelColor(device, 100, 238);
2176     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2177     color = getPixelColor(device, 100, 241);
2178     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2179
2180     /* Not clipped, < z buffer clear value */
2181     color = getPixelColor(device, 104, 238);
2182     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2183     color = getPixelColor(device, 104, 241);
2184     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2185     color = getPixelColor(device, 318, 238);
2186     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2187     color = getPixelColor(device, 318, 241);
2188     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2189
2190     /* Clipped because z < 0.0 */
2191     color = getPixelColor(device, 321, 238);
2192     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2193     color = getPixelColor(device, 321, 241);
2194     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2195
2196     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2197     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2198
2199     /* Test the shader path */
2200     IDirect3DDevice9_GetDeviceCaps(device, &caps);
2201     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2202         skip("Vertex shaders not supported\n");
2203         goto out;
2204     }
2205     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2206     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2207     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2208     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2209
2210     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2211
2212     IDirect3DDevice9_SetVertexDeclaration(device, decl);
2213     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2214     IDirect3DDevice9_SetVertexShader(device, shader);
2215     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2216
2217     hr = IDirect3DDevice9_BeginScene(device);
2218     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2219     if(hr == D3D_OK)
2220     {
2221         float colorf[] = {1.0, 0.0, 0.0, 1.0};
2222         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2223         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2224         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2225         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2226         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2227         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2228         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2229         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2230         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2231
2232         hr = IDirect3DDevice9_EndScene(device);
2233         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2234     }
2235
2236     IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2237     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2238     IDirect3DDevice9_SetVertexShader(device, NULL);
2239     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2240
2241     IDirect3DVertexDeclaration9_Release(decl);
2242     IDirect3DVertexShader9_Release(shader);
2243
2244     /* Z < 1.0 */
2245     color = getPixelColor(device, 28, 238);
2246     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2247
2248     /* 1.0 < z < 0.75 */
2249     color = getPixelColor(device, 31, 238);
2250     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2251     color = getPixelColor(device, 100, 238);
2252     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2253
2254     /* 0.75 < z < 0.0 */
2255     color = getPixelColor(device, 104, 238);
2256     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2257     color = getPixelColor(device, 318, 238);
2258     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2259
2260     /* 0.0 < z */
2261     color = getPixelColor(device, 321, 238);
2262     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2263
2264     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2265     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2266
2267     out:
2268     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2269     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2270     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2271     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2272     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2273     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2274 }
2275
2276 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2277 {
2278     D3DSURFACE_DESC desc;
2279     D3DLOCKED_RECT l;
2280     HRESULT hr;
2281     unsigned int x, y;
2282     DWORD *mem;
2283
2284     memset(&desc, 0, sizeof(desc));
2285     memset(&l, 0, sizeof(l));
2286     hr = IDirect3DSurface9_GetDesc(surface, &desc);
2287     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2288     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2289     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2290     if(FAILED(hr)) return;
2291
2292     for(y = 0; y < desc.Height; y++)
2293     {
2294         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2295         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2296         {
2297             mem[x] = color;
2298         }
2299     }
2300     hr = IDirect3DSurface9_UnlockRect(surface);
2301     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2302 }
2303
2304 /* This tests a variety of possible StretchRect() situations */
2305 static void stretchrect_test(IDirect3DDevice9 *device)
2306 {
2307     HRESULT hr;
2308     IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL, *tex_rt_dest640_480 = NULL;
2309     IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL, *surf_tex_rt_dest640_480 = NULL;
2310     IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2311     IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2312     IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2313     IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2314     IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2315     IDirect3DSurface9 *orig_rt = NULL;
2316     IDirect3DSurface9 *backbuffer = NULL;
2317     DWORD color;
2318
2319     RECT src_rect64 = {0, 0, 64, 64};
2320     RECT src_rect64_flipy = {0, 64, 64, 0};
2321     RECT dst_rect64 = {0, 0, 64, 64};
2322     RECT dst_rect64_flipy = {0, 64, 64, 0};
2323
2324     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2325     ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2326     if(!orig_rt) {
2327         goto out;
2328     }
2329
2330     /* Create our temporary surfaces in system memory */
2331     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2332     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2333     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2334     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2335
2336     /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2337     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2338     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2339     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2340     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2341     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2342     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2343
2344     /* Create render target surfaces */
2345     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2346     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2347     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2348     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2349     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2350     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2351     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2352     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2353
2354     /* Create render target textures */
2355     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2356     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2357     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2358     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2359     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2360     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2361     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
2362     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2363     if (tex_rt32) {
2364         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2365         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2366     }
2367     if (tex_rt64) {
2368         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2369         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2370     }
2371     if (tex_rt_dest64) {
2372         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2373         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2374     }
2375     if (tex_rt_dest64) {
2376         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
2377         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2378     }
2379
2380     /* Create regular textures in D3DPOOL_DEFAULT */
2381     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2382     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2383     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2384     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2385     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2386     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2387     if (tex32) {
2388         hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2389         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2390     }
2391     if (tex64) {
2392         hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2393         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2394     }
2395     if (tex_dest64) {
2396         hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2397         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2398     }
2399
2400     /*********************************************************************
2401      * Tests for when the source parameter is an offscreen plain surface *
2402      *********************************************************************/
2403
2404     /* Fill the offscreen 64x64 surface with green */
2405     if (surf_offscreen64)
2406         fill_surface(surf_offscreen64, 0xff00ff00);
2407
2408     /* offscreenplain ==> offscreenplain, same size */
2409     if(surf_offscreen64 && surf_offscreen_dest64) {
2410         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2411         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2412
2413         if (hr == D3D_OK) {
2414             color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2415             ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2416         }
2417
2418         /* Blit without scaling */
2419         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64, 0);
2420         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2421
2422         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2423         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_offscreen_dest64, &dst_rect64, 0);
2424         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2425
2426         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2427         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64_flipy, 0);
2428         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2429     }
2430
2431     /* offscreenplain ==> rendertarget texture, same size */
2432     if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2433         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2434         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2435
2436         /* We can't lock rendertarget textures, so copy to our temp surface first */
2437         if (hr == D3D_OK) {
2438             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2439             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2440         }
2441
2442         if (hr == D3D_OK) {
2443             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2444             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2445         }
2446
2447         /* Blit without scaling */
2448         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2449         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2450
2451         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2452         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2453         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2454
2455         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2456         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2457         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2458     }
2459
2460     /* offscreenplain ==> rendertarget surface, same size */
2461     if(surf_offscreen64 && surf_rt_dest64) {
2462         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2463         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2464
2465         if (hr == D3D_OK) {
2466             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2467             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2468         }
2469
2470         /* Blit without scaling */
2471         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2472         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2473
2474         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2475         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2476         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2477
2478         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2479         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2480         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2481     }
2482
2483     /* offscreenplain ==> texture, same size (should fail) */
2484     if(surf_offscreen64 && surf_tex_dest64) {
2485         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2486         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2487     }
2488
2489     /* Fill the smaller offscreen surface with red */
2490     fill_surface(surf_offscreen32, 0xffff0000);
2491
2492     /* offscreenplain ==> offscreenplain, scaling (should fail) */
2493     if(surf_offscreen32 && surf_offscreen64) {
2494         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2495         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2496     }
2497
2498     /* offscreenplain ==> rendertarget texture, scaling */
2499     if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2500         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2501         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2502
2503         /* We can't lock rendertarget textures, so copy to our temp surface first */
2504         if (hr == D3D_OK) {
2505             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2506             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2507         }
2508
2509         if (hr == D3D_OK) {
2510             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2511             ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2512         }
2513     }
2514
2515     /* offscreenplain ==> rendertarget surface, scaling */
2516     if(surf_offscreen32 && surf_rt_dest64) {
2517         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2518         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2519
2520         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2521         ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2522     }
2523
2524     /* offscreenplain ==> texture, scaling (should fail) */
2525     if(surf_offscreen32 && surf_tex_dest64) {
2526         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2527         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2528     }
2529
2530     /************************************************************
2531      * Tests for when the source parameter is a regular texture *
2532      ************************************************************/
2533
2534     /* Fill the surface of the regular texture with blue */
2535     if (surf_tex64 && surf_temp64) {
2536         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2537         fill_surface(surf_temp64, 0xff0000ff);
2538         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2539         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2540     }
2541
2542     /* texture ==> offscreenplain, same size */
2543     if(surf_tex64 && surf_offscreen64) {
2544         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2545         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2546     }
2547
2548     /* texture ==> rendertarget texture, same size */
2549     if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2550         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2551         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2552
2553         /* We can't lock rendertarget textures, so copy to our temp surface first */
2554         if (hr == D3D_OK) {
2555             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2556             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2557         }
2558
2559         if (hr == D3D_OK) {
2560             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2561             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2562         }
2563
2564         /* Blit without scaling */
2565         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2566         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2567
2568         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2569         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2570         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2571
2572         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2573         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2574         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2575     }
2576
2577     /* texture ==> rendertarget surface, same size */
2578     if(surf_tex64 && surf_rt_dest64) {
2579         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2580         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2581
2582         if (hr == D3D_OK) {
2583             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2584             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2585         }
2586
2587         /* Blit without scaling */
2588         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2589         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2590
2591         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2592         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2593         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2594
2595         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2596         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2597         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2598     }
2599
2600     /* texture ==> texture, same size (should fail) */
2601     if(surf_tex64 && surf_tex_dest64) {
2602         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2603         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2604     }
2605
2606     /* Fill the surface of the smaller regular texture with red */
2607     if (surf_tex32 && surf_temp32) {
2608         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2609         fill_surface(surf_temp32, 0xffff0000);
2610         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2611         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2612     }
2613
2614     /* texture ==> offscreenplain, scaling (should fail) */
2615     if(surf_tex32 && surf_offscreen64) {
2616         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2617         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2618     }
2619
2620     /* texture ==> rendertarget texture, scaling */
2621     if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2622         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2623         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2624
2625         /* We can't lock rendertarget textures, so copy to our temp surface first */
2626         if (hr == D3D_OK) {
2627             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2628             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2629         }
2630
2631         if (hr == D3D_OK) {
2632             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2633             ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2634         }
2635     }
2636
2637     /* texture ==> rendertarget surface, scaling */
2638     if(surf_tex32 && surf_rt_dest64) {
2639         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2640         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2641
2642         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2643         ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2644     }
2645
2646     /* texture ==> texture, scaling (should fail) */
2647     if(surf_tex32 && surf_tex_dest64) {
2648         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2649         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2650     }
2651
2652     /*****************************************************************
2653      * Tests for when the source parameter is a rendertarget texture *
2654      *****************************************************************/
2655
2656     /* Fill the surface of the rendertarget texture with white */
2657     if (surf_tex_rt64 && surf_temp64) {
2658         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2659         fill_surface(surf_temp64, 0xffffffff);
2660         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2661         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2662     }
2663
2664     /* rendertarget texture ==> offscreenplain, same size */
2665     if(surf_tex_rt64 && surf_offscreen64) {
2666         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2667         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2668     }
2669
2670     /* rendertarget texture ==> rendertarget texture, same size */
2671     if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2672         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2673         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2674
2675         /* We can't lock rendertarget textures, so copy to our temp surface first */
2676         if (hr == D3D_OK) {
2677             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2678             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2679         }
2680
2681         if (hr == D3D_OK) {
2682             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2683             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2684         }
2685
2686         /* Blit without scaling */
2687         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2688         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2689
2690         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2691         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2692         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2693
2694         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2695         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2696         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2697     }
2698
2699     /* rendertarget texture ==> rendertarget surface, same size */
2700     if(surf_tex_rt64 && surf_rt_dest64) {
2701         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2702         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2703
2704         if (hr == D3D_OK) {
2705             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2706             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2707         }
2708
2709         /* Blit without scaling */
2710         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2711         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2712
2713         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2714         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2715         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2716
2717         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2718         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2719         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2720     }
2721
2722     /* rendertarget texture ==> texture, same size (should fail) */
2723     if(surf_tex_rt64 && surf_tex_dest64) {
2724         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2725         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2726     }
2727
2728     /* Fill the surface of the smaller rendertarget texture with red */
2729     if (surf_tex_rt32 && surf_temp32) {
2730         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2731         fill_surface(surf_temp32, 0xffff0000);
2732         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2733         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2734     }
2735
2736     /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2737     if(surf_tex_rt32 && surf_offscreen64) {
2738         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2739         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2740     }
2741
2742     /* rendertarget texture ==> rendertarget texture, scaling */
2743     if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2744         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2745         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2746
2747         /* We can't lock rendertarget textures, so copy to our temp surface first */
2748         if (hr == D3D_OK) {
2749             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2750             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2751         }
2752
2753         if (hr == D3D_OK) {
2754             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2755             ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2756         }
2757     }
2758
2759     /* rendertarget texture ==> rendertarget surface, scaling */
2760     if(surf_tex_rt32 && surf_rt_dest64) {
2761         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2762         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2763
2764         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2765         ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2766     }
2767
2768     /* rendertarget texture ==> texture, scaling (should fail) */
2769     if(surf_tex_rt32 && surf_tex_dest64) {
2770         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2771         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2772     }
2773
2774     /*****************************************************************
2775      * Tests for when the source parameter is a rendertarget surface *
2776      *****************************************************************/
2777
2778     /* Fill the surface of the rendertarget surface with black */
2779     if (surf_rt64)
2780         fill_surface(surf_rt64, 0xff000000);
2781
2782     /* rendertarget texture ==> offscreenplain, same size */
2783     if(surf_rt64 && surf_offscreen64) {
2784         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2785         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2786     }
2787
2788     /* rendertarget surface ==> rendertarget texture, same size */
2789     if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2790         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2791         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2792
2793         /* We can't lock rendertarget textures, so copy to our temp surface first */
2794         if (hr == D3D_OK) {
2795             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2796             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2797         }
2798
2799         if (hr == D3D_OK) {
2800             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2801             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2802         }
2803
2804         /* Blit without scaling */
2805         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2806         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2807
2808         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2809         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2810         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2811
2812         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2813         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2814         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2815     }
2816
2817     /* rendertarget surface ==> rendertarget surface, same size */
2818     if(surf_rt64 && surf_rt_dest64) {
2819         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2820         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2821
2822         if (hr == D3D_OK) {
2823             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2824             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2825         }
2826
2827         /* Blit without scaling */
2828         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2829         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2830
2831         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2832         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64_flipy, 0);
2833         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2834
2835         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2836         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2837         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2838     }
2839
2840     /* rendertarget surface ==> texture, same size (should fail) */
2841     if(surf_rt64 && surf_tex_dest64) {
2842         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2843         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2844     }
2845
2846     /* Fill the surface of the smaller rendertarget texture with red */
2847     if (surf_rt32)
2848         fill_surface(surf_rt32, 0xffff0000);
2849
2850     /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2851     if(surf_rt32 && surf_offscreen64) {
2852         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2853         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2854     }
2855
2856     /* rendertarget surface ==> rendertarget texture, scaling */
2857     if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2858         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2859         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2860
2861         /* We can't lock rendertarget textures, so copy to our temp surface first */
2862         if (hr == D3D_OK) {
2863             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2864             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2865         }
2866
2867         if (hr == D3D_OK) {
2868             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2869             ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2870         }
2871     }
2872
2873     /* rendertarget surface ==> rendertarget surface, scaling */
2874     if(surf_rt32 && surf_rt_dest64) {
2875         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2876         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2877
2878         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2879         ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2880     }
2881
2882     /* rendertarget surface ==> texture, scaling (should fail) */
2883     if(surf_rt32 && surf_tex_dest64) {
2884         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2885         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2886     }
2887
2888     /* backbuffer ==> surface tests (no scaling) */
2889     if(backbuffer && surf_tex_rt_dest640_480)
2890     {
2891         RECT src_rect = {0, 0, 640, 480};
2892         RECT src_rect_flipy = {0, 480, 640, 0};
2893         RECT dst_rect = {0, 0, 640, 480};
2894         RECT dst_rect_flipy = {0, 480, 640, 0};
2895
2896         /* Blit with NULL rectangles */
2897         hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, 0);
2898         ok( hr == D3D_OK, "StretchRect backbuffer ==> texture same size failed:\n");
2899
2900         /* Blit without scaling */
2901         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect, 0);
2902         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2903
2904         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2905         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy, surf_tex_rt_dest640_480, &dst_rect, 0);
2906         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2907
2908         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2909         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect_flipy, 0);
2910         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2911     }
2912
2913     /* TODO: Test format conversions */
2914
2915
2916 out:
2917     /* Clean up */
2918     if (backbuffer)
2919         IDirect3DSurface9_Release(backbuffer);
2920     if (surf_rt32)
2921         IDirect3DSurface9_Release(surf_rt32);
2922     if (surf_rt64)
2923         IDirect3DSurface9_Release(surf_rt64);
2924     if (surf_rt_dest64)
2925         IDirect3DSurface9_Release(surf_rt_dest64);
2926     if (surf_temp32)
2927         IDirect3DSurface9_Release(surf_temp32);
2928     if (surf_temp64)
2929         IDirect3DSurface9_Release(surf_temp64);
2930     if (surf_offscreen32)
2931         IDirect3DSurface9_Release(surf_offscreen32);
2932     if (surf_offscreen64)
2933         IDirect3DSurface9_Release(surf_offscreen64);
2934     if (surf_offscreen_dest64)
2935         IDirect3DSurface9_Release(surf_offscreen_dest64);
2936
2937     if (tex_rt32) {
2938         if (surf_tex_rt32)
2939             IDirect3DSurface9_Release(surf_tex_rt32);
2940         IDirect3DTexture9_Release(tex_rt32);
2941     }
2942     if (tex_rt64) {
2943         if (surf_tex_rt64)
2944             IDirect3DSurface9_Release(surf_tex_rt64);
2945         IDirect3DTexture9_Release(tex_rt64);
2946     }
2947     if (tex_rt_dest64) {
2948         if (surf_tex_rt_dest64)
2949             IDirect3DSurface9_Release(surf_tex_rt_dest64);
2950         IDirect3DTexture9_Release(tex_rt_dest64);
2951     }
2952     if (tex_rt_dest640_480) {
2953         if (surf_tex_rt_dest640_480)
2954             IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
2955         IDirect3DTexture9_Release(tex_rt_dest640_480);
2956     }
2957     if (tex32) {
2958         if (surf_tex32)
2959             IDirect3DSurface9_Release(surf_tex32);
2960         IDirect3DTexture9_Release(tex32);
2961     }
2962     if (tex64) {
2963         if (surf_tex64)
2964             IDirect3DSurface9_Release(surf_tex64);
2965         IDirect3DTexture9_Release(tex64);
2966     }
2967     if (tex_dest64) {
2968         if (surf_tex_dest64)
2969             IDirect3DSurface9_Release(surf_tex_dest64);
2970         IDirect3DTexture9_Release(tex_dest64);
2971     }
2972
2973     if (orig_rt) {
2974         hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2975         ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
2976         IDirect3DSurface9_Release(orig_rt);
2977     }
2978 }
2979
2980 static void maxmip_test(IDirect3DDevice9 *device)
2981 {
2982     IDirect3DTexture9 *texture = NULL;
2983     IDirect3DSurface9 *surface = NULL;
2984     HRESULT hr;
2985     DWORD color;
2986     const float quads[] = {
2987         -1.0,   -1.0,   0.0,    0.0,    0.0,
2988         -1.0,    0.0,   0.0,    0.0,    1.0,
2989          0.0,   -1.0,   0.0,    1.0,    0.0,
2990          0.0,    0.0,   0.0,    1.0,    1.0,
2991
2992          0.0,   -1.0,   0.0,    0.0,    0.0,
2993          0.0,    0.0,   0.0,    0.0,    1.0,
2994          1.0,   -1.0,   0.0,    1.0,    0.0,
2995          1.0,    0.0,   0.0,    1.0,    1.0,
2996
2997          0.0,    0.0,   0.0,    0.0,    0.0,
2998          0.0,    1.0,   0.0,    0.0,    1.0,
2999          1.0,    0.0,   0.0,    1.0,    0.0,
3000          1.0,    1.0,   0.0,    1.0,    1.0,
3001
3002         -1.0,    0.0,   0.0,    0.0,    0.0,
3003         -1.0,    1.0,   0.0,    0.0,    1.0,
3004          0.0,    0.0,   0.0,    1.0,    0.0,
3005          0.0,    1.0,   0.0,    1.0,    1.0,
3006     };
3007
3008     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3009     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3010
3011     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
3012                                         &texture, NULL);
3013     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3014     if(!texture)
3015     {
3016         skip("Failed to create test texture\n");
3017         return;
3018     }
3019
3020     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3021     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3022     fill_surface(surface, 0xffff0000);
3023     IDirect3DSurface9_Release(surface);
3024     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
3025     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3026     fill_surface(surface, 0xff00ff00);
3027     IDirect3DSurface9_Release(surface);
3028     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3029     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3030     fill_surface(surface, 0xff0000ff);
3031     IDirect3DSurface9_Release(surface);
3032
3033     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3034     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3035     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3036     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3037
3038     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3039     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3040
3041     hr = IDirect3DDevice9_BeginScene(device);
3042     if(SUCCEEDED(hr))
3043     {
3044         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3045         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3046         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
3047         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3048
3049         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3050         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3051         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
3052         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3053
3054         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3055         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3056         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
3057         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3058
3059         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3060         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3061         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
3062         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3063         hr = IDirect3DDevice9_EndScene(device);
3064         ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
3065     }
3066
3067     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
3068     color = getPixelColor(device, 160, 360);
3069     ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
3070     color = getPixelColor(device, 160, 120);
3071     ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
3072     color = getPixelColor(device, 480, 120);
3073     ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
3074     color = getPixelColor(device, 480, 360);
3075     ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
3076     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3077     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3078
3079     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3080     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3081
3082     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3083     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3084
3085     hr = IDirect3DDevice9_BeginScene(device);
3086     if(SUCCEEDED(hr))
3087     {
3088         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3089         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3090         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
3091         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3092
3093         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3094         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3095         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
3096         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3097
3098         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3099         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3100         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
3101         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3102
3103         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3104         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3105         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
3106         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3107         hr = IDirect3DDevice9_EndScene(device);
3108         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
3109     }
3110
3111     /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
3112      * samples from the highest level in the texture(level 2)
3113      */
3114     color = getPixelColor(device, 160, 360);
3115     ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
3116     color = getPixelColor(device, 160, 120);
3117     ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
3118     color = getPixelColor(device, 480, 120);
3119     ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
3120     color = getPixelColor(device, 480, 360);
3121     ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
3122     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3123     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3124
3125     hr = IDirect3DDevice9_BeginScene(device);
3126     if(SUCCEEDED(hr))
3127     {
3128         DWORD ret;
3129
3130         /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
3131         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3132         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3133         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3134         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3135         ret = IDirect3DTexture9_SetLOD(texture, 1);
3136         ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
3137         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
3138         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3139
3140         /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
3141         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3142         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3143         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3144         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3145         ret = IDirect3DTexture9_SetLOD(texture, 2);
3146         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3147         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
3148         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3149
3150         /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
3151         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3152         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3153         ret = IDirect3DTexture9_SetLOD(texture, 1);
3154         ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
3155         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
3156         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3157
3158         /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
3159         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3160         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3161         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3162         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3163         ret = IDirect3DTexture9_SetLOD(texture, 1);
3164         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3165         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
3166         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3167         hr = IDirect3DDevice9_EndScene(device);
3168     }
3169
3170     /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
3171      * samples from the highest level in the texture(level 2)
3172      */
3173     color = getPixelColor(device, 160, 360);
3174     ok(color == 0x0000FF00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x\n", color);
3175     color = getPixelColor(device, 160, 120);
3176     ok(color == 0x0000FF00, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x\n", color);
3177     color = getPixelColor(device, 480, 120);
3178     ok(color == 0x000000FF, "MapMip 2, LOD 1, point mipfilter has color 0x%08x\n", color);
3179     color = getPixelColor(device, 480, 360);
3180     ok(color == 0x000000FF, "MapMip 2, LOD 1, none mipfilter has color 0x%08x\n", color);
3181     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3182     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3183
3184     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3185     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3186     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3187     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3188     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3189     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3190     IDirect3DTexture9_Release(texture);
3191 }
3192
3193 static void release_buffer_test(IDirect3DDevice9 *device)
3194 {
3195     IDirect3DVertexBuffer9 *vb = NULL;
3196     IDirect3DIndexBuffer9 *ib = NULL;
3197     HRESULT hr;
3198     BYTE *data;
3199     LONG ref;
3200
3201     static const struct vertex quad[] = {
3202         {-1.0,      -1.0,       0.1,        0xffff0000},
3203         {-1.0,       1.0,       0.1,        0xffff0000},
3204         { 1.0,       1.0,       0.1,        0xffff0000},
3205
3206         {-1.0,      -1.0,       0.1,        0xff00ff00},
3207         {-1.0,       1.0,       0.1,        0xff00ff00},
3208         { 1.0,       1.0,       0.1,        0xff00ff00}
3209     };
3210     short indices[] = {3, 4, 5};
3211
3212     /* Index and vertex buffers should always be creatable */
3213     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
3214                                               D3DPOOL_MANAGED, &vb, NULL);
3215     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
3216     if(!vb) {
3217         skip("Failed to create a vertex buffer\n");
3218         return;
3219     }
3220     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3221     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
3222     if(!ib) {
3223         skip("Failed to create an index buffer\n");
3224         return;
3225     }
3226
3227     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3228     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3229     memcpy(data, quad, sizeof(quad));
3230     hr = IDirect3DVertexBuffer9_Unlock(vb);
3231     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3232
3233     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3234     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3235     memcpy(data, indices, sizeof(indices));
3236     hr = IDirect3DIndexBuffer9_Unlock(ib);
3237     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3238
3239     hr = IDirect3DDevice9_SetIndices(device, ib);
3240     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3241     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3242     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3243     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3244     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3245
3246     /* Now destroy the bound index buffer and draw again */
3247     ref = IDirect3DIndexBuffer9_Release(ib);
3248     ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3249
3250     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3251     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3252
3253     hr = IDirect3DDevice9_BeginScene(device);
3254     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3255     if(SUCCEEDED(hr))
3256     {
3257         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3258          * making assumptions about the indices or vertices
3259          */
3260         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3261         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3262         hr = IDirect3DDevice9_EndScene(device);
3263         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3264     }
3265
3266     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3267     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3268
3269     hr = IDirect3DDevice9_SetIndices(device, NULL);
3270     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3271     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3272     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3273
3274     /* Index buffer was already destroyed as part of the test */
3275     IDirect3DVertexBuffer9_Release(vb);
3276 }
3277
3278 static void float_texture_test(IDirect3DDevice9 *device)
3279 {
3280     IDirect3D9 *d3d = NULL;
3281     HRESULT hr;
3282     IDirect3DTexture9 *texture = NULL;
3283     D3DLOCKED_RECT lr;
3284     float *data;
3285     DWORD color;
3286     float quad[] = {
3287         -1.0,      -1.0,       0.1,     0.0,    0.0,
3288         -1.0,       1.0,       0.1,     0.0,    1.0,
3289          1.0,      -1.0,       0.1,     1.0,    0.0,
3290          1.0,       1.0,       0.1,     1.0,    1.0,
3291     };
3292
3293     memset(&lr, 0, sizeof(lr));
3294     IDirect3DDevice9_GetDirect3D(device, &d3d);
3295     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3296                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3297         skip("D3DFMT_R32F textures not supported\n");
3298         goto out;
3299     }
3300
3301     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3302                                         D3DPOOL_MANAGED, &texture, NULL);
3303     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3304     if(!texture) {
3305         skip("Failed to create R32F texture\n");
3306         goto out;
3307     }
3308
3309     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3310     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3311     data = lr.pBits;
3312     *data = 0.0;
3313     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3314     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3315
3316     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3317     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3318
3319     hr = IDirect3DDevice9_BeginScene(device);
3320     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3321     if(SUCCEEDED(hr))
3322     {
3323         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3324         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3325
3326         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3327         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3328
3329         hr = IDirect3DDevice9_EndScene(device);
3330         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3331     }
3332     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3333     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3334
3335     color = getPixelColor(device, 240, 320);
3336     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3337
3338     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3339     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3340
3341 out:
3342     if(texture) IDirect3DTexture9_Release(texture);
3343     IDirect3D9_Release(d3d);
3344 }
3345
3346 static void g16r16_texture_test(IDirect3DDevice9 *device)
3347 {
3348     IDirect3D9 *d3d = NULL;
3349     HRESULT hr;
3350     IDirect3DTexture9 *texture = NULL;
3351     D3DLOCKED_RECT lr;
3352     DWORD *data;
3353     DWORD color;
3354     float quad[] = {
3355        -1.0,      -1.0,       0.1,     0.0,    0.0,
3356        -1.0,       1.0,       0.1,     0.0,    1.0,
3357         1.0,      -1.0,       0.1,     1.0,    0.0,
3358         1.0,       1.0,       0.1,     1.0,    1.0,
3359     };
3360
3361     memset(&lr, 0, sizeof(lr));
3362     IDirect3DDevice9_GetDirect3D(device, &d3d);
3363     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3364        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3365            skip("D3DFMT_G16R16 textures not supported\n");
3366            goto out;
3367     }
3368
3369     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3370                                         D3DPOOL_MANAGED, &texture, NULL);
3371     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3372     if(!texture) {
3373         skip("Failed to create D3DFMT_G16R16 texture\n");
3374         goto out;
3375     }
3376
3377     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3378     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3379     data = lr.pBits;
3380     *data = 0x0f00f000;
3381     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3382     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3383
3384     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3385     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3386
3387     hr = IDirect3DDevice9_BeginScene(device);
3388     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3389     if(SUCCEEDED(hr))
3390     {
3391         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3392         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3393
3394         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3395         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3396
3397         hr = IDirect3DDevice9_EndScene(device);
3398         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3399     }
3400     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3401     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3402
3403     color = getPixelColor(device, 240, 320);
3404     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3405        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3406
3407     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3408     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3409
3410 out:
3411     if(texture) IDirect3DTexture9_Release(texture);
3412     IDirect3D9_Release(d3d);
3413 }
3414
3415 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3416 {
3417     HRESULT hr;
3418     IDirect3D9 *d3d;
3419     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3420     D3DCAPS9 caps;
3421     IDirect3DTexture9 *texture = NULL;
3422     IDirect3DVolumeTexture9 *volume = NULL;
3423     unsigned int x, y, z;
3424     D3DLOCKED_RECT lr;
3425     D3DLOCKED_BOX lb;
3426     DWORD color;
3427     UINT w, h;
3428     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3429     float identity[16] = {1.0, 0.0, 0.0, 0.0,
3430                            0.0, 1.0, 0.0, 0.0,
3431                            0.0, 0.0, 1.0, 0.0,
3432                            0.0, 0.0, 0.0, 1.0};
3433     static const D3DVERTEXELEMENT9 decl_elements[] = {
3434         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3435         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3436         D3DDECL_END()
3437     };
3438     static const D3DVERTEXELEMENT9 decl_elements2[] = {
3439         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3440         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3441         D3DDECL_END()
3442     };
3443     static const D3DVERTEXELEMENT9 decl_elements3[] = {
3444         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3445         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3446         D3DDECL_END()
3447     };
3448     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3449                                                  0x00, 0xff, 0x00, 0x00,
3450                                                  0x00, 0x00, 0x00, 0x00,
3451                                                  0x00, 0x00, 0x00, 0x00};
3452
3453     memset(&lr, 0, sizeof(lr));
3454     memset(&lb, 0, sizeof(lb));
3455     IDirect3DDevice9_GetDirect3D(device, &d3d);
3456     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3457                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3458         fmt = D3DFMT_A16B16G16R16;
3459     }
3460     IDirect3D9_Release(d3d);
3461
3462     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3463     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3464     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3465     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3466     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3467     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3468     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3469     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3470     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3471     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3472     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3473     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3474     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3475     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3476     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3477     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3478     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3479     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3480     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3481     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3482     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3483     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3484     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3485     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3486
3487     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3488     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3489     w = min(1024, caps.MaxTextureWidth);
3490     h = min(1024, caps.MaxTextureHeight);
3491     hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3492                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3493     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3494     if(!texture) {
3495         skip("Failed to create the test texture\n");
3496         return;
3497     }
3498
3499     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3500      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3501      * 1.0 in red and green for the x and y coords
3502      */
3503     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3504     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3505     for(y = 0; y < h; y++) {
3506         for(x = 0; x < w; x++) {
3507             double r_f = (double) y / (double) h;
3508             double g_f = (double) x / (double) w;
3509             if(fmt == D3DFMT_A16B16G16R16) {
3510                 unsigned short r, g;
3511                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3512                 r = (unsigned short) (r_f * 65536.0);
3513                 g = (unsigned short) (g_f * 65536.0);
3514                 dst[0] = r;
3515                 dst[1] = g;
3516                 dst[2] = 0;
3517                 dst[3] = 65535;
3518             } else {
3519                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3520                 unsigned char r = (unsigned char) (r_f * 255.0);
3521                 unsigned char g = (unsigned char) (g_f * 255.0);
3522                 dst[0] = 0;
3523                 dst[1] = g;
3524                 dst[2] = r;
3525                 dst[3] = 255;
3526             }
3527         }
3528     }
3529     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3530     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3531     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3532     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3533
3534     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3535     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3536     hr = IDirect3DDevice9_BeginScene(device);
3537     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3538     if(SUCCEEDED(hr))
3539     {
3540         float quad1[] = {
3541             -1.0,      -1.0,       0.1,     1.0,    1.0,
3542             -1.0,       0.0,       0.1,     1.0,    1.0,
3543              0.0,      -1.0,       0.1,     1.0,    1.0,
3544              0.0,       0.0,       0.1,     1.0,    1.0,
3545         };
3546         float quad2[] = {
3547             -1.0,       0.0,       0.1,     1.0,    1.0,
3548             -1.0,       1.0,       0.1,     1.0,    1.0,
3549              0.0,       0.0,       0.1,     1.0,    1.0,
3550              0.0,       1.0,       0.1,     1.0,    1.0,
3551         };
3552         float quad3[] = {
3553              0.0,       0.0,       0.1,     0.5,    0.5,
3554              0.0,       1.0,       0.1,     0.5,    0.5,
3555              1.0,       0.0,       0.1,     0.5,    0.5,
3556              1.0,       1.0,       0.1,     0.5,    0.5,
3557         };
3558         float quad4[] = {
3559              320,       480,       0.1,     1.0,    0.0,    1.0,
3560              320,       240,       0.1,     1.0,    0.0,    1.0,
3561              640,       480,       0.1,     1.0,    0.0,    1.0,
3562              640,       240,       0.1,     1.0,    0.0,    1.0,
3563         };
3564         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3565                           0.0, 0.0, 0.0, 0.0,
3566                           0.0, 0.0, 0.0, 0.0,
3567                           0.0, 0.0, 0.0, 0.0};
3568
3569         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3570         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3571         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3572         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3573         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3574
3575         /* What happens with transforms enabled? */
3576         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3577         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3578         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3579         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3580
3581         /* What happens if 4 coords are used, but only 2 given ?*/
3582         mat[8] = 1.0;
3583         mat[13] = 1.0;
3584         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3585         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3586         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3587         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3588         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3589         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3590
3591         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3592          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3593          * due to the coords in the vertices. (turns out red, indeed)
3594          */
3595         memset(mat, 0, sizeof(mat));
3596         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3597         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3598         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3599         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3600         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3601         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3602         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3603         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3604
3605         hr = IDirect3DDevice9_EndScene(device);
3606         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3607     }
3608     color = getPixelColor(device, 160, 360);
3609     ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3610     color = getPixelColor(device, 160, 120);
3611     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3612     color = getPixelColor(device, 480, 120);
3613     ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
3614     color = getPixelColor(device, 480, 360);
3615     ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
3616     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3617     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3618
3619     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3620     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3621
3622     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3623     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3624     hr = IDirect3DDevice9_BeginScene(device);
3625     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3626     if(SUCCEEDED(hr))
3627     {
3628         float quad1[] = {
3629             -1.0,      -1.0,       0.1,     0.8,    0.2,
3630             -1.0,       0.0,       0.1,     0.8,    0.2,
3631              0.0,      -1.0,       0.1,     0.8,    0.2,
3632              0.0,       0.0,       0.1,     0.8,    0.2,
3633         };
3634         float quad2[] = {
3635             -1.0,       0.0,       0.1,     0.5,    1.0,
3636             -1.0,       1.0,       0.1,     0.5,    1.0,
3637              0.0,       0.0,       0.1,     0.5,    1.0,
3638              0.0,       1.0,       0.1,     0.5,    1.0,
3639         };
3640         float quad3[] = {
3641              0.0,       0.0,       0.1,     0.5,    1.0,
3642              0.0,       1.0,       0.1,     0.5,    1.0,
3643              1.0,       0.0,       0.1,     0.5,    1.0,
3644              1.0,       1.0,       0.1,     0.5,    1.0,
3645         };
3646         float quad4[] = {
3647              0.0,      -1.0,       0.1,     0.8,    0.2,
3648              0.0,       0.0,       0.1,     0.8,    0.2,
3649              1.0,      -1.0,       0.1,     0.8,    0.2,
3650              1.0,       0.0,       0.1,     0.8,    0.2,
3651         };
3652         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3653                           0.0, 0.0, 0.0, 0.0,
3654                           0.0, 1.0, 0.0, 0.0,
3655                           0.0, 0.0, 0.0, 0.0};
3656
3657         /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3658          */
3659         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3660         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3661         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3662         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3663
3664         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3665         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3666
3667         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3668          * it behaves like COUNT2 because normal textures require 2 coords
3669          */
3670         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3671         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3672         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3673         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3674
3675         /* Just to be sure, the same as quad2 above */
3676         memset(mat, 0, sizeof(mat));
3677         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3678         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3679         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3680         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3681         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3682         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3683
3684         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3685          * used? And what happens to the first?
3686          */
3687         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3688         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3689         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3690         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3691
3692         hr = IDirect3DDevice9_EndScene(device);
3693         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3694     }
3695     color = getPixelColor(device, 160, 360);
3696     ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
3697     color = getPixelColor(device, 160, 120);
3698     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3699     color = getPixelColor(device, 480, 120);
3700     ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
3701        "quad 3 has color %08x, expected 0x00ff8000\n", color);
3702     color = getPixelColor(device, 480, 360);
3703     ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
3704        "quad 4 has color %08x, expected 0x0033cc00\n", color);
3705     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3706     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3707
3708     IDirect3DTexture9_Release(texture);
3709
3710     /* Test projected textures, without any fancy matrices */
3711     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3712     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3713     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3714     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3715     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3716     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3717     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3718     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3719
3720     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3721     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3722     for(x = 0; x < 4; x++) {
3723         memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3724     }
3725     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3726     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3727     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3728     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3729
3730     hr = IDirect3DDevice9_BeginScene(device);
3731     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3732     if(SUCCEEDED(hr))
3733     {
3734         const float proj_quads[] = {
3735            -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3736             1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3737            -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3738             1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3739            -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3740             1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3741            -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3742             1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3743         };
3744
3745         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3746         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3747         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3748         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3749
3750         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3751         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3752         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3753         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3754
3755         hr = IDirect3DDevice9_EndScene(device);
3756         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3757     }
3758
3759     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3760     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3761     IDirect3DTexture9_Release(texture);
3762
3763     color = getPixelColor(device, 158, 118);
3764     ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3765     color = getPixelColor(device, 162, 118);
3766     ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3767     color = getPixelColor(device, 158, 122);
3768     ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3769     color = getPixelColor(device, 162, 122);
3770     ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3771
3772     color = getPixelColor(device, 158, 178);
3773     ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3774     color = getPixelColor(device, 162, 178);
3775     ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3776     color = getPixelColor(device, 158, 182);
3777     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3778     color = getPixelColor(device, 162, 182);
3779     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3780
3781     color = getPixelColor(device, 318, 118);
3782     ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3783     color = getPixelColor(device, 322, 118);
3784     ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3785     color = getPixelColor(device, 318, 122);
3786     ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3787     color = getPixelColor(device, 322, 122);
3788     ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3789
3790     color = getPixelColor(device, 318, 178);
3791     ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3792     color = getPixelColor(device, 322, 178);
3793     ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3794     color = getPixelColor(device, 318, 182);
3795     ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3796     color = getPixelColor(device, 322, 182);
3797     ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3798
3799     color = getPixelColor(device, 238, 298);
3800     ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3801     color = getPixelColor(device, 242, 298);
3802     ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3803     color = getPixelColor(device, 238, 302);
3804     ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3805     color = getPixelColor(device, 242, 302);
3806     ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3807
3808     color = getPixelColor(device, 238, 388);
3809     ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3810     color = getPixelColor(device, 242, 388);
3811     ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3812     color = getPixelColor(device, 238, 392);
3813     ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3814     color = getPixelColor(device, 242, 392);
3815     ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3816
3817     color = getPixelColor(device, 478, 298);
3818     ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3819     color = getPixelColor(device, 482, 298);
3820     ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3821     color = getPixelColor(device, 478, 302);
3822     ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3823     color = getPixelColor(device, 482, 302);
3824     ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3825
3826     color = getPixelColor(device, 478, 388);
3827     ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3828     color = getPixelColor(device, 482, 388);
3829     ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3830     color = getPixelColor(device, 478, 392);
3831     ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3832     color = getPixelColor(device, 482, 392);
3833     ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3834
3835     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3836     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3837
3838     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3839     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3840     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3841      * Thus watch out if sampling from texels between 0 and 1.
3842      */
3843     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3844     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3845        "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3846     if(!volume) {
3847         skip("Failed to create a volume texture\n");
3848         goto out;
3849     }
3850
3851     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3852     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3853     for(z = 0; z < 32; z++) {
3854         for(y = 0; y < 32; y++) {
3855             for(x = 0; x < 32; x++) {
3856                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3857                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3858                 float r_f = (float) x / 31.0;
3859                 float g_f = (float) y / 31.0;
3860                 float b_f = (float) z / 31.0;
3861
3862                 if(fmt == D3DFMT_A16B16G16R16) {
3863                     unsigned short *mem_s = mem;
3864                     mem_s[0]  = r_f * 65535.0;
3865                     mem_s[1]  = g_f * 65535.0;
3866                     mem_s[2]  = b_f * 65535.0;
3867                     mem_s[3]  = 65535;
3868                 } else {
3869                     unsigned char *mem_c = mem;
3870                     mem_c[0]  = b_f * 255.0;
3871                     mem_c[1]  = g_f * 255.0;
3872                     mem_c[2]  = r_f * 255.0;
3873                     mem_c[3]  = 255;
3874                 }
3875             }
3876         }
3877     }
3878     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3879     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3880
3881     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3882     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3883
3884     hr = IDirect3DDevice9_BeginScene(device);
3885     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3886     if(SUCCEEDED(hr))
3887     {
3888         float quad1[] = {
3889             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3890             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3891              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3892              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3893         };
3894         float quad2[] = {
3895             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3896             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
3897              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3898              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
3899         };
3900         float quad3[] = {
3901              0.0,       0.0,       0.1,     0.0,    0.0,
3902              0.0,       1.0,       0.1,     0.0,    0.0,
3903              1.0,       0.0,       0.1,     0.0,    0.0,
3904              1.0,       1.0,       0.1,     0.0,    0.0
3905         };
3906         float quad4[] = {
3907              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3908              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3909              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3910              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
3911         };
3912         float mat[16] = {1.0, 0.0, 0.0, 0.0,
3913                          0.0, 0.0, 1.0, 0.0,
3914                          0.0, 1.0, 0.0, 0.0,
3915                          0.0, 0.0, 0.0, 1.0};
3916         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3917         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3918
3919         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3920          * values
3921          */
3922         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3923         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3924         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3925         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3926         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3927         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3928
3929         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3930          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3931          * otherwise the w will be missing(blue).
3932          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3933          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3934          */
3935         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3936         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3937         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3938         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3939
3940         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
3941         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3942         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3943         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3944         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3945         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3946         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3947         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3948         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3949
3950         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3951          * disable. ATI extends it up to the amount of values needed for the volume texture
3952          */
3953         memset(mat, 0, sizeof(mat));
3954         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3955         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3956         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3957         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3958         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3959         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3960         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3961         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3962
3963         hr = IDirect3DDevice9_EndScene(device);
3964         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3965     }
3966
3967     color = getPixelColor(device, 160, 360);
3968     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3969     color = getPixelColor(device, 160, 120);
3970     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3971        "quad 2 has color %08x, expected 0x00ffff00\n", color);
3972     color = getPixelColor(device, 480, 120);
3973     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3974     color = getPixelColor(device, 480, 360);
3975     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3976
3977     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3978     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3979
3980     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3981     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3982     hr = IDirect3DDevice9_BeginScene(device);
3983     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3984     if(SUCCEEDED(hr))
3985     {
3986         float quad1[] = {
3987             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3988             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3989              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3990              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3991         };
3992         float quad2[] = {
3993             -1.0,       0.0,       0.1,
3994             -1.0,       1.0,       0.1,
3995              0.0,       0.0,       0.1,
3996              0.0,       1.0,       0.1,
3997         };
3998         float quad3[] = {
3999              0.0,       0.0,       0.1,     1.0,
4000              0.0,       1.0,       0.1,     1.0,
4001              1.0,       0.0,       0.1,     1.0,
4002              1.0,       1.0,       0.1,     1.0
4003         };
4004         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
4005                            0.0, 0.0, 0.0, 0.0,
4006                            0.0, 0.0, 0.0, 0.0,
4007                            0.0, 1.0, 0.0, 0.0};
4008         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
4009                            1.0, 0.0, 0.0, 0.0,
4010                            0.0, 1.0, 0.0, 0.0,
4011                            0.0, 0.0, 1.0, 0.0};
4012         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4013         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4014
4015         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
4016          */
4017         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4018         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4019         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
4020         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4021         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4022         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4023
4024         /* None passed */
4025         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4026         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4027         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4028         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4029         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4030         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4031
4032         /* 4 used, 1 passed */
4033         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4034         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4035         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
4036         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4037         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4038         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4039
4040         hr = IDirect3DDevice9_EndScene(device);
4041         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4042     }
4043     color = getPixelColor(device, 160, 360);
4044     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4045     color = getPixelColor(device, 160, 120);
4046     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4047     color = getPixelColor(device, 480, 120);
4048     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4049     /* Quad4: unused */
4050
4051     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4052     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4053
4054     IDirect3DVolumeTexture9_Release(volume);
4055
4056     out:
4057     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4058     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4059     IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
4060     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4061     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4062     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4063     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4064     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4065     IDirect3DVertexDeclaration9_Release(decl);
4066     IDirect3DVertexDeclaration9_Release(decl2);
4067     IDirect3DVertexDeclaration9_Release(decl3);
4068 }
4069
4070 static void texdepth_test(IDirect3DDevice9 *device)
4071 {
4072     IDirect3DPixelShader9 *shader;
4073     HRESULT hr;
4074     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
4075     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
4076     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
4077     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
4078     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
4079     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
4080     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
4081     DWORD shader_code[] = {
4082         0xffff0104,                                                                 /* ps_1_4               */
4083         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
4084         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
4085         0x0000fffd,                                                                 /* phase                */
4086         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
4087         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
4088         0x0000ffff                                                                  /* end                  */
4089     };
4090     DWORD color;
4091     float vertex[] = {
4092        -1.0,   -1.0,    0.0,
4093         1.0,   -1.0,    1.0,
4094        -1.0,    1.0,    0.0,
4095         1.0,    1.0,    1.0
4096     };
4097
4098     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4099     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4100
4101     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4102     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4103     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4104     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4105     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4106     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4107     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4108     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4109     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4110     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4111
4112     /* Fill the depth buffer with a gradient */
4113     hr = IDirect3DDevice9_BeginScene(device);
4114     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4115     if(SUCCEEDED(hr))
4116     {
4117         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4118         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4119         hr = IDirect3DDevice9_EndScene(device);
4120         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4121     }
4122
4123     /* Now perform the actual tests. Same geometry, but with the shader */
4124     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4125     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4126     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4127     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4128     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4129     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4130
4131     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4132     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4133     hr = IDirect3DDevice9_BeginScene(device);
4134     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4135     if(SUCCEEDED(hr))
4136     {
4137         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4138         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4139
4140         hr = IDirect3DDevice9_EndScene(device);
4141         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4142     }
4143
4144     color = getPixelColor(device, 158, 240);
4145     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4146     color = getPixelColor(device, 162, 240);
4147     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
4148
4149     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4150     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4151
4152     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4153     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4154
4155     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
4156     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4157     hr = IDirect3DDevice9_BeginScene(device);
4158     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4159     if(SUCCEEDED(hr))
4160     {
4161         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4162         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4163
4164         hr = IDirect3DDevice9_EndScene(device);
4165         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4166     }
4167
4168     color = getPixelColor(device, 318, 240);
4169     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4170     color = getPixelColor(device, 322, 240);
4171     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4172
4173     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4174     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4175
4176     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4177     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4178
4179     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4180     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4181     hr = IDirect3DDevice9_BeginScene(device);
4182     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4183     if(SUCCEEDED(hr))
4184     {
4185         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4186         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4187
4188         hr = IDirect3DDevice9_EndScene(device);
4189         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4190     }
4191
4192     color = getPixelColor(device, 1, 240);
4193     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4194
4195     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4196     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4197
4198     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4199     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4200
4201     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4202     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4203     hr = IDirect3DDevice9_BeginScene(device);
4204     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4205     if(SUCCEEDED(hr))
4206     {
4207         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4208         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4209
4210         hr = IDirect3DDevice9_EndScene(device);
4211         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4212     }
4213     color = getPixelColor(device, 318, 240);
4214     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4215     color = getPixelColor(device, 322, 240);
4216     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
4217
4218     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4219     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4220
4221     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4222     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4223
4224     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
4225     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4226     hr = IDirect3DDevice9_BeginScene(device);
4227     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4228     if(SUCCEEDED(hr))
4229     {
4230         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4231         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4232
4233         hr = IDirect3DDevice9_EndScene(device);
4234         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4235     }
4236
4237     color = getPixelColor(device, 1, 240);
4238     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4239
4240     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4241     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4242
4243     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4244     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4245
4246     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4247     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4248     hr = IDirect3DDevice9_BeginScene(device);
4249     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4250     if(SUCCEEDED(hr))
4251     {
4252         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4253         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4254
4255         hr = IDirect3DDevice9_EndScene(device);
4256         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4257     }
4258
4259     color = getPixelColor(device, 638, 240);
4260     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4261
4262     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4263     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4264
4265     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4266     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4267
4268     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4269     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4270     hr = IDirect3DDevice9_BeginScene(device);
4271     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4272     if(SUCCEEDED(hr))
4273     {
4274         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4275         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4276
4277         hr = IDirect3DDevice9_EndScene(device);
4278         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4279     }
4280
4281     color = getPixelColor(device, 638, 240);
4282     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4283
4284     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4285     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4286
4287     /* Cleanup */
4288     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4289     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4290     IDirect3DPixelShader9_Release(shader);
4291
4292     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4293     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4294     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4295     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4296 }
4297
4298 static void texkill_test(IDirect3DDevice9 *device)
4299 {
4300     IDirect3DPixelShader9 *shader;
4301     HRESULT hr;
4302     DWORD color;
4303
4304     const float vertex[] = {
4305     /*                          bottom  top    right    left */
4306         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
4307          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
4308         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
4309          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
4310     };
4311
4312     DWORD shader_code_11[] = {
4313     0xffff0101,                                                             /* ps_1_1                     */
4314     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4315     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
4316     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
4317     0x0000ffff                                                              /* end                        */
4318     };
4319     DWORD shader_code_20[] = {
4320     0xffff0200,                                                             /* ps_2_0                     */
4321     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
4322     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4323     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
4324     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
4325     0x0000ffff                                                              /* end                        */
4326     };
4327
4328     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4329     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4330     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4331     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4332
4333     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4334     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4335     hr = IDirect3DDevice9_BeginScene(device);
4336     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4337     if(SUCCEEDED(hr))
4338     {
4339         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4340         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4341         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4342         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4343         hr = IDirect3DDevice9_EndScene(device);
4344         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4345     }
4346     color = getPixelColor(device, 63, 46);
4347     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4348     color = getPixelColor(device, 66, 46);
4349     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4350     color = getPixelColor(device, 63, 49);
4351     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4352     color = getPixelColor(device, 66, 49);
4353     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4354
4355     color = getPixelColor(device, 578, 46);
4356     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4357     color = getPixelColor(device, 575, 46);
4358     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4359     color = getPixelColor(device, 578, 49);
4360     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4361     color = getPixelColor(device, 575, 49);
4362     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4363
4364     color = getPixelColor(device, 63, 430);
4365     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4366     color = getPixelColor(device, 63, 433);
4367     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4368     color = getPixelColor(device, 66, 433);
4369     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4370     color = getPixelColor(device, 66, 430);
4371     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4372
4373     color = getPixelColor(device, 578, 430);
4374     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4375     color = getPixelColor(device, 578, 433);
4376     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4377     color = getPixelColor(device, 575, 433);
4378     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4379     color = getPixelColor(device, 575, 430);
4380     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4381
4382     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4383     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4384
4385     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4386     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4387     IDirect3DPixelShader9_Release(shader);
4388
4389     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4390     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4391     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4392     if(FAILED(hr)) {
4393         skip("Failed to create 2.0 test shader, most likely not supported\n");
4394         return;
4395     }
4396
4397     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4398     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4399     hr = IDirect3DDevice9_BeginScene(device);
4400     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4401     if(SUCCEEDED(hr))
4402     {
4403         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4404         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4405         hr = IDirect3DDevice9_EndScene(device);
4406         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4407     }
4408
4409     color = getPixelColor(device, 63, 46);
4410     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4411     color = getPixelColor(device, 66, 46);
4412     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4413     color = getPixelColor(device, 63, 49);
4414     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4415     color = getPixelColor(device, 66, 49);
4416     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4417
4418     color = getPixelColor(device, 578, 46);
4419     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4420     color = getPixelColor(device, 575, 46);
4421     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4422     color = getPixelColor(device, 578, 49);
4423     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4424     color = getPixelColor(device, 575, 49);
4425     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4426
4427     color = getPixelColor(device, 63, 430);
4428     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4429     color = getPixelColor(device, 63, 433);
4430     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4431     color = getPixelColor(device, 66, 433);
4432     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4433     color = getPixelColor(device, 66, 430);
4434     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4435
4436     color = getPixelColor(device, 578, 430);
4437     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4438     color = getPixelColor(device, 578, 433);
4439     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4440     color = getPixelColor(device, 575, 433);
4441     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4442     color = getPixelColor(device, 575, 430);
4443     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4444
4445     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4446     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4447
4448     /* Cleanup */
4449     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4450     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4451     IDirect3DPixelShader9_Release(shader);
4452 }
4453
4454 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4455 {
4456     IDirect3D9 *d3d9;
4457     HRESULT hr;
4458     IDirect3DTexture9 *texture;
4459     IDirect3DPixelShader9 *shader;
4460     IDirect3DPixelShader9 *shader2;
4461     D3DLOCKED_RECT lr;
4462     DWORD color;
4463     DWORD shader_code[] = {
4464         0xffff0101,                             /* ps_1_1       */
4465         0x00000042, 0xb00f0000,                 /* tex t0       */
4466         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
4467         0x0000ffff                              /* end          */
4468     };
4469     DWORD shader_code2[] = {
4470         0xffff0101,                             /* ps_1_1       */
4471         0x00000042, 0xb00f0000,                 /* tex t0       */
4472         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
4473         0x0000ffff                              /* end          */
4474     };
4475
4476     float quad[] = {
4477        -1.0,   -1.0,   0.1,     0.5,    0.5,
4478         1.0,   -1.0,   0.1,     0.5,    0.5,
4479        -1.0,    1.0,   0.1,     0.5,    0.5,
4480         1.0,    1.0,   0.1,     0.5,    0.5,
4481     };
4482
4483     memset(&lr, 0, sizeof(lr));
4484     IDirect3DDevice9_GetDirect3D(device, &d3d9);
4485     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4486                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4487     IDirect3D9_Release(d3d9);
4488     if(FAILED(hr)) {
4489         skip("No D3DFMT_X8L8V8U8 support\n");
4490         return;
4491     };
4492
4493     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4494     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4495
4496     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4497     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4498     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4499     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4500     *((DWORD *) lr.pBits) = 0x11ca3141;
4501     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4502     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4503
4504     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4505     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4506     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4507     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4508
4509     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4510     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4511     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4512     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4513     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4514     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4515
4516     hr = IDirect3DDevice9_BeginScene(device);
4517     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4518     if(SUCCEEDED(hr))
4519     {
4520         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4521         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4522
4523         hr = IDirect3DDevice9_EndScene(device);
4524         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4525     }
4526     color = getPixelColor(device, 578, 430);
4527     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4528        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4529     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4530     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4531
4532     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4533     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4534     hr = IDirect3DDevice9_BeginScene(device);
4535     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4536     if(SUCCEEDED(hr))
4537     {
4538         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4539         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4540
4541         hr = IDirect3DDevice9_EndScene(device);
4542         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4543     }
4544     color = getPixelColor(device, 578, 430);
4545     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4546     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4547     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4548
4549     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4550     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4551     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4552     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4553     IDirect3DPixelShader9_Release(shader);
4554     IDirect3DPixelShader9_Release(shader2);
4555     IDirect3DTexture9_Release(texture);
4556 }
4557
4558 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4559 {
4560     HRESULT hr;
4561     IDirect3D9 *d3d;
4562     IDirect3DTexture9 *texture = NULL;
4563     IDirect3DSurface9 *surface;
4564     DWORD color;
4565     const RECT r1 = {256, 256, 512, 512};
4566     const RECT r2 = {512, 256, 768, 512};
4567     const RECT r3 = {256, 512, 512, 768};
4568     const RECT r4 = {512, 512, 768, 768};
4569     unsigned int x, y;
4570     D3DLOCKED_RECT lr;
4571     memset(&lr, 0, sizeof(lr));
4572
4573     IDirect3DDevice9_GetDirect3D(device, &d3d);
4574     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4575        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4576         skip("No autogenmipmap support\n");
4577         IDirect3D9_Release(d3d);
4578         return;
4579     }
4580     IDirect3D9_Release(d3d);
4581
4582     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4583     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4584
4585     /* Make the mipmap big, so that a smaller mipmap is used
4586      */
4587     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4588                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4589     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4590
4591     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4592     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4593     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4594     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4595     for(y = 0; y < 1024; y++) {
4596         for(x = 0; x < 1024; x++) {
4597             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4598             POINT pt;
4599
4600             pt.x = x;
4601             pt.y = y;
4602             if(PtInRect(&r1, pt)) {
4603                 *dst = 0xffff0000;
4604             } else if(PtInRect(&r2, pt)) {
4605                 *dst = 0xff00ff00;
4606             } else if(PtInRect(&r3, pt)) {
4607                 *dst = 0xff0000ff;
4608             } else if(PtInRect(&r4, pt)) {
4609                 *dst = 0xff000000;
4610             } else {
4611                 *dst = 0xffffffff;
4612             }
4613         }
4614     }
4615     hr = IDirect3DSurface9_UnlockRect(surface);
4616     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4617     IDirect3DSurface9_Release(surface);
4618
4619     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4620     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4621     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4622     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4623
4624     hr = IDirect3DDevice9_BeginScene(device);
4625     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4626     if(SUCCEEDED(hr)) {
4627         const float quad[] =  {
4628            -0.5,   -0.5,    0.1,    0.0,    0.0,
4629            -0.5,    0.5,    0.1,    0.0,    1.0,
4630             0.5,   -0.5,    0.1,    1.0,    0.0,
4631             0.5,    0.5,    0.1,    1.0,    1.0
4632         };
4633
4634         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4635         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4636         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4637         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4638         hr = IDirect3DDevice9_EndScene(device);
4639         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4640     }
4641     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4642     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4643     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4644     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4645     IDirect3DTexture9_Release(texture);
4646
4647     color = getPixelColor(device, 200, 200);
4648     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4649     color = getPixelColor(device, 280, 200);
4650     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4651     color = getPixelColor(device, 360, 200);
4652     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4653     color = getPixelColor(device, 440, 200);
4654     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4655     color = getPixelColor(device, 200, 270);
4656     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4657     color = getPixelColor(device, 280, 270);
4658     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4659     color = getPixelColor(device, 360, 270);
4660     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4661     color = getPixelColor(device, 440, 270);
4662     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4663     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4664     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4665 }
4666
4667 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4668 {
4669     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4670     IDirect3DVertexDeclaration9 *decl;
4671     HRESULT hr;
4672     DWORD color;
4673     DWORD shader_code_11[] =  {
4674         0xfffe0101,                                         /* vs_1_1           */
4675         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4676         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4677         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4678         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4679         0x0000ffff                                          /* end              */
4680     };
4681     DWORD shader_code_11_2[] =  {
4682         0xfffe0101,                                         /* vs_1_1           */
4683         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4684         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4685         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4686         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4687         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4688         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4689         0x0000ffff                                          /* end              */
4690     };
4691     DWORD shader_code_20[] =  {
4692         0xfffe0200,                                         /* vs_2_0           */
4693         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4694         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4695         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4696         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4697         0x0000ffff                                          /* end              */
4698     };
4699     DWORD shader_code_20_2[] =  {
4700         0xfffe0200,                                         /* vs_2_0           */
4701         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4702         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4703         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4704         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4705         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4706         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4707         0x0000ffff                                          /* end              */
4708     };
4709     static const D3DVERTEXELEMENT9 decl_elements[] = {
4710         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4711         D3DDECL_END()
4712     };
4713     float quad1[] = {
4714         -1.0,   -1.0,   0.1,
4715          0.0,   -1.0,   0.1,
4716         -1.0,    0.0,   0.1,
4717          0.0,    0.0,   0.1
4718     };
4719     float quad2[] = {
4720          0.0,   -1.0,   0.1,
4721          1.0,   -1.0,   0.1,
4722          0.0,    0.0,   0.1,
4723          1.0,    0.0,   0.1
4724     };
4725     float quad3[] = {
4726          0.0,    0.0,   0.1,
4727          1.0,    0.0,   0.1,
4728          0.0,    1.0,   0.1,
4729          1.0,    1.0,   0.1
4730     };
4731     float quad4[] = {
4732         -1.0,    0.0,   0.1,
4733          0.0,    0.0,   0.1,
4734         -1.0,    1.0,   0.1,
4735          0.0,    1.0,   0.1
4736     };
4737     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4738     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4739
4740     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4741     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4742
4743     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4744     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4745     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4746     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4747     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4748     if(FAILED(hr)) shader_20 = NULL;
4749     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4750     if(FAILED(hr)) shader_20_2 = NULL;
4751     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4752     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4753
4754     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4755     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4756     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4757     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4758     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4759     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4760
4761     hr = IDirect3DDevice9_BeginScene(device);
4762     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4763     if(SUCCEEDED(hr))
4764     {
4765         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4766         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4767         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4768         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4769
4770         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4771         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4772         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4773         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4774
4775         if(shader_20) {
4776             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4777             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4778             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4779             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4780         }
4781
4782         if(shader_20_2) {
4783             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4784             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4785             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4786             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4787         }
4788
4789         hr = IDirect3DDevice9_EndScene(device);
4790         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4791     }
4792
4793     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4794     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4795     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4796     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4797
4798     color = getPixelColor(device, 160, 360);
4799     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4800        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4801     color = getPixelColor(device, 480, 360);
4802     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4803        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4804     if(shader_20) {
4805         color = getPixelColor(device, 160, 120);
4806         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4807            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4808     }
4809     if(shader_20_2) {
4810         color = getPixelColor(device, 480, 120);
4811         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4812            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4813     }
4814     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4815     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4816
4817     IDirect3DVertexDeclaration9_Release(decl);
4818     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4819     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4820     IDirect3DVertexShader9_Release(shader_11_2);
4821     IDirect3DVertexShader9_Release(shader_11);
4822 }
4823
4824 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4825 {
4826     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4827     HRESULT hr;
4828     DWORD color;
4829     DWORD shader_code_11[] =  {
4830         0xffff0101,                                         /* ps_1_1           */
4831         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4832         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4833         0x0000ffff                                          /* end              */
4834     };
4835     DWORD shader_code_12[] =  {
4836         0xffff0102,                                         /* ps_1_2           */
4837         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4838         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4839         0x0000ffff                                          /* end              */
4840     };
4841     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4842      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4843      * During development of this test, 1.3 shaders were verified too
4844      */
4845     DWORD shader_code_14[] =  {
4846         0xffff0104,                                         /* ps_1_4           */
4847         /* Try to make one constant local. It gets clamped too, although the binary contains
4848          * the bigger numbers
4849          */
4850         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4851         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4852         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4853         0x0000ffff                                          /* end              */
4854     };
4855     DWORD shader_code_20[] =  {
4856         0xffff0200,                                         /* ps_2_0           */
4857         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4858         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4859         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
4860         0x0000ffff                                          /* end              */
4861     };
4862     float quad1[] = {
4863         -1.0,   -1.0,   0.1,
4864          0.0,   -1.0,   0.1,
4865         -1.0,    0.0,   0.1,
4866          0.0,    0.0,   0.1
4867     };
4868     float quad2[] = {
4869          0.0,   -1.0,   0.1,
4870          1.0,   -1.0,   0.1,
4871          0.0,    0.0,   0.1,
4872          1.0,    0.0,   0.1
4873     };
4874     float quad3[] = {
4875          0.0,    0.0,   0.1,
4876          1.0,    0.0,   0.1,
4877          0.0,    1.0,   0.1,
4878          1.0,    1.0,   0.1
4879     };
4880     float quad4[] = {
4881         -1.0,    0.0,   0.1,
4882          0.0,    0.0,   0.1,
4883         -1.0,    1.0,   0.1,
4884          0.0,    1.0,   0.1
4885     };
4886     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4887     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4888
4889     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4890     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4891
4892     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4893     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4894     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4895     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4896     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4897     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4898     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4899     if(FAILED(hr)) shader_20 = NULL;
4900
4901     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4902     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4903     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4904     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4905     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4906     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4907
4908     hr = IDirect3DDevice9_BeginScene(device);
4909     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4910     if(SUCCEEDED(hr))
4911     {
4912         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4913         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4914         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4915         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4916
4917         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4918         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4919         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4920         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4921
4922         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4923         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4924         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4925         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4926
4927         if(shader_20) {
4928             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4929             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4930             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4931             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4932         }
4933
4934         hr = IDirect3DDevice9_EndScene(device);
4935         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4936     }
4937     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4938     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4939
4940     color = getPixelColor(device, 160, 360);
4941     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4942        "quad 1 has color %08x, expected 0x00808000\n", color);
4943     color = getPixelColor(device, 480, 360);
4944     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4945        "quad 2 has color %08x, expected 0x00808000\n", color);
4946     color = getPixelColor(device, 480, 120);
4947     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4948        "quad 3 has color %08x, expected 0x00808000\n", color);
4949     if(shader_20) {
4950         color = getPixelColor(device, 160, 120);
4951         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4952            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4953     }
4954     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4955     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4956
4957     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4958     IDirect3DPixelShader9_Release(shader_14);
4959     IDirect3DPixelShader9_Release(shader_12);
4960     IDirect3DPixelShader9_Release(shader_11);
4961 }
4962
4963 static void dp2add_ps_test(IDirect3DDevice9 *device)
4964 {
4965     IDirect3DPixelShader9 *shader_dp2add = NULL;
4966     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4967     HRESULT hr;
4968     DWORD color;
4969
4970     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
4971      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4972      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
4973      * r0 first.
4974      * The result here for the r,g,b components should be roughly 0.5:
4975      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4976     static const DWORD shader_code_dp2add[] =  {
4977         0xffff0200,                                                             /* ps_2_0                       */
4978         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
4979
4980         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
4981         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
4982
4983         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
4984         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
4985         0x0000ffff                                                              /* end                          */
4986     };
4987
4988     /* Test the _sat modifier, too.  Result here should be:
4989      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4990      *      _SAT: ==> 1.0
4991      *   ADD: (1.0 + -0.5) = 0.5
4992      */
4993     static const DWORD shader_code_dp2add_sat[] =  {
4994         0xffff0200,                                                             /* ps_2_0                           */
4995         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
4996
4997         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
4998         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
4999         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
5000
5001         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
5002         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
5003         0x0000ffff                                                              /* end                              */
5004     };
5005
5006     const float quad[] = {
5007         -1.0,   -1.0,   0.1,
5008          1.0,   -1.0,   0.1,
5009         -1.0,    1.0,   0.1,
5010          1.0,    1.0,   0.1
5011     };
5012
5013
5014     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
5015     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5016
5017     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
5018     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5019
5020     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
5021     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5022
5023     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5024     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5025
5026     if (shader_dp2add) {
5027
5028         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5029         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5030
5031         hr = IDirect3DDevice9_BeginScene(device);
5032         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5033         if(SUCCEEDED(hr))
5034         {
5035             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5036             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5037
5038             hr = IDirect3DDevice9_EndScene(device);
5039             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5040         }
5041
5042         color = getPixelColor(device, 360, 240);
5043         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5044                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5045
5046         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5047         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5048
5049         IDirect3DPixelShader9_Release(shader_dp2add);
5050     } else {
5051         skip("dp2add shader creation failed\n");
5052     }
5053
5054     if (shader_dp2add_sat) {
5055
5056         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5057         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5058
5059         hr = IDirect3DDevice9_BeginScene(device);
5060         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5061         if(SUCCEEDED(hr))
5062         {
5063             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5064             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5065
5066             hr = IDirect3DDevice9_EndScene(device);
5067             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5068         }
5069
5070         color = getPixelColor(device, 360, 240);
5071         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5072                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5073
5074         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5075         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5076
5077         IDirect3DPixelShader9_Release(shader_dp2add_sat);
5078     } else {
5079         skip("dp2add shader creation failed\n");
5080     }
5081
5082     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5083     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5084 }
5085
5086 static void cnd_test(IDirect3DDevice9 *device)
5087 {
5088     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
5089     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
5090     HRESULT hr;
5091     DWORD color;
5092     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
5093      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
5094      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
5095      */
5096     DWORD shader_code_11[] =  {
5097         0xffff0101,                                                                 /* ps_1_1               */
5098         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5099         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5100         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
5101         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5102         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5103         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5104         0x0000ffff                                                                  /* end                  */
5105     };
5106     DWORD shader_code_12[] =  {
5107         0xffff0102,                                                                 /* ps_1_2               */
5108         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5109         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5110         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5111         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5112         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5113         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5114         0x0000ffff                                                                  /* end                  */
5115     };
5116     DWORD shader_code_13[] =  {
5117         0xffff0103,                                                                 /* ps_1_3               */
5118         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5119         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5120         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5121         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
5122         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5123         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5124         0x0000ffff                                                                  /* end                  */
5125     };
5126     DWORD shader_code_14[] =  {
5127         0xffff0104,                                                                 /* ps_1_3               */
5128         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
5129         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
5130         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
5131         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
5132         0x0000ffff                                                                  /* end                  */
5133     };
5134
5135     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
5136      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
5137      * set by the compiler, it was added manually after compilation. It isn't always allowed,
5138      * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
5139      * native CreatePixelShader returns an error.
5140      *
5141      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
5142      * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
5143      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
5144      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
5145      */
5146     DWORD shader_code_11_coissue[] =  {
5147         0xffff0101,                                                             /* ps_1_1                   */
5148         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5149         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5150         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5151         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5152         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5153         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5154         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5155         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5156         /* 0x40000000 = D3DSI_COISSUE */
5157         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5158         0x0000ffff                                                              /* end                      */
5159     };
5160     DWORD shader_code_12_coissue[] =  {
5161         0xffff0102,                                                             /* ps_1_2                   */
5162         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5163         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5164         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5165         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5166         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5167         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5168         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5169         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5170         /* 0x40000000 = D3DSI_COISSUE */
5171         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5172         0x0000ffff                                                              /* end                      */
5173     };
5174     DWORD shader_code_13_coissue[] =  {
5175         0xffff0103,                                                             /* ps_1_3                   */
5176         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5177         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5178         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5179         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5180         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5181         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5182         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5183         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5184         /* 0x40000000 = D3DSI_COISSUE */
5185         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5186         0x0000ffff                                                              /* end                      */
5187     };
5188     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
5189      * compare against 0.5
5190      */
5191     DWORD shader_code_14_coissue[] =  {
5192         0xffff0104,                                                             /* ps_1_4                   */
5193         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
5194         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
5195         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
5196         /* 0x40000000 = D3DSI_COISSUE */
5197         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
5198         0x0000ffff                                                              /* end                      */
5199     };
5200     float quad1[] = {
5201         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5202          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5203         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5204          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
5205     };
5206     float quad2[] = {
5207          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5208          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5209          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5210          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
5211     };
5212     float quad3[] = {
5213          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5214          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5215          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5216          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
5217     };
5218     float quad4[] = {
5219         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5220          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5221         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5222          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
5223     };
5224     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
5225     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
5226     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
5227     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
5228
5229     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5230     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5231
5232     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5233     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5234     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5235     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5236     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
5237     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5238     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5239     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5240     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
5241     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5242     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5243     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5244     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5245     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5246     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5247     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5248
5249     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5250     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5251     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5252     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5253     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5254     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5255
5256     hr = IDirect3DDevice9_BeginScene(device);
5257     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5258     if(SUCCEEDED(hr))
5259     {
5260         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5261         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5262         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5263         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5264
5265         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5266         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5267         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5268         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5269
5270         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5271         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5272         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5273         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5274
5275         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5276         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5277         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5278         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5279
5280         hr = IDirect3DDevice9_EndScene(device);
5281         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5282     }
5283
5284     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5285     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5286
5287     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5288     color = getPixelColor(device, 158, 118);
5289     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5290     color = getPixelColor(device, 162, 118);
5291     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5292     color = getPixelColor(device, 158, 122);
5293     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5294     color = getPixelColor(device, 162, 122);
5295     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5296
5297     /* 1.1 shader. All 3 components get set, based on the .w comparison */
5298     color = getPixelColor(device, 158, 358);
5299     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5300     color = getPixelColor(device, 162, 358);
5301     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5302         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5303     color = getPixelColor(device, 158, 362);
5304     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5305     color = getPixelColor(device, 162, 362);
5306     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5307         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5308
5309     /* 1.2 shader */
5310     color = getPixelColor(device, 478, 358);
5311     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5312     color = getPixelColor(device, 482, 358);
5313     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5314         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5315     color = getPixelColor(device, 478, 362);
5316     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5317     color = getPixelColor(device, 482, 362);
5318     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5319         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5320
5321     /* 1.3 shader */
5322     color = getPixelColor(device, 478, 118);
5323     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5324     color = getPixelColor(device, 482, 118);
5325     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5326         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5327     color = getPixelColor(device, 478, 122);
5328     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5329     color = getPixelColor(device, 482, 122);
5330     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5331         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5332
5333     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5334     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5335
5336     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5337     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5338     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5339     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5340     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5341     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5342
5343     hr = IDirect3DDevice9_BeginScene(device);
5344     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5345     if(SUCCEEDED(hr))
5346     {
5347         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5348         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5349         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5350         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5351
5352         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5353         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5354         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5355         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5356
5357         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5358         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5359         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5360         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5361
5362         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5363         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5364         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5365         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5366
5367         hr = IDirect3DDevice9_EndScene(device);
5368         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5369     }
5370
5371     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5372     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5373
5374     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5375      * that we swapped the values in c1 and c2 to make the other tests return some color
5376      */
5377     color = getPixelColor(device, 158, 118);
5378     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5379     color = getPixelColor(device, 162, 118);
5380     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5381     color = getPixelColor(device, 158, 122);
5382     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5383     color = getPixelColor(device, 162, 122);
5384     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5385
5386     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
5387     color = getPixelColor(device, 158, 358);
5388     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5389         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5390     color = getPixelColor(device, 162, 358);
5391     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5392         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5393     color = getPixelColor(device, 158, 362);
5394     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5395         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5396     color = getPixelColor(device, 162, 362);
5397     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5398         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5399
5400     /* 1.2 shader */
5401     color = getPixelColor(device, 478, 358);
5402     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5403         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5404     color = getPixelColor(device, 482, 358);
5405     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5406         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5407     color = getPixelColor(device, 478, 362);
5408     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5409         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5410     color = getPixelColor(device, 482, 362);
5411     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5412         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5413
5414     /* 1.3 shader */
5415     color = getPixelColor(device, 478, 118);
5416     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5417         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5418     color = getPixelColor(device, 482, 118);
5419     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5420         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5421     color = getPixelColor(device, 478, 122);
5422     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5423         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5424     color = getPixelColor(device, 482, 122);
5425     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5426         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5427
5428     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5429     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5430
5431     IDirect3DPixelShader9_Release(shader_14_coissue);
5432     IDirect3DPixelShader9_Release(shader_13_coissue);
5433     IDirect3DPixelShader9_Release(shader_12_coissue);
5434     IDirect3DPixelShader9_Release(shader_11_coissue);
5435     IDirect3DPixelShader9_Release(shader_14);
5436     IDirect3DPixelShader9_Release(shader_13);
5437     IDirect3DPixelShader9_Release(shader_12);
5438     IDirect3DPixelShader9_Release(shader_11);
5439 }
5440
5441 static void nested_loop_test(IDirect3DDevice9 *device) {
5442     const DWORD shader_code[] = {
5443         0xffff0300,                                                             /* ps_3_0               */
5444         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
5445         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5446         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
5447         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
5448         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5449         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5450         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
5451         0x0000001d,                                                             /* endloop              */
5452         0x0000001d,                                                             /* endloop              */
5453         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
5454         0x0000ffff                                                              /* end                  */
5455     };
5456     IDirect3DPixelShader9 *shader;
5457     HRESULT hr;
5458     DWORD color;
5459     const float quad[] = {
5460         -1.0,   -1.0,   0.1,
5461          1.0,   -1.0,   0.1,
5462         -1.0,    1.0,   0.1,
5463          1.0,    1.0,   0.1
5464     };
5465
5466     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5467     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5468     hr = IDirect3DDevice9_SetPixelShader(device, shader);
5469     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5470     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5471     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5472     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5473     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5474
5475     hr = IDirect3DDevice9_BeginScene(device);
5476     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5477     if(SUCCEEDED(hr))
5478     {
5479         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5480         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5481         hr = IDirect3DDevice9_EndScene(device);
5482         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5483     }
5484
5485     color = getPixelColor(device, 360, 240);
5486     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5487        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5488
5489     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5490     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5491
5492     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5493     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5494     IDirect3DPixelShader9_Release(shader);
5495 }
5496
5497 struct varying_test_struct
5498 {
5499     const DWORD             *shader_code;
5500     IDirect3DPixelShader9   *shader;
5501     DWORD                   color, color_rhw;
5502     const char              *name;
5503     BOOL                    todo, todo_rhw;
5504 };
5505
5506 struct hugeVertex
5507 {
5508     float pos_x,        pos_y,      pos_z,      rhw;
5509     float weight_1,     weight_2,   weight_3,   weight_4;
5510     float index_1,      index_2,    index_3,    index_4;
5511     float normal_1,     normal_2,   normal_3,   normal_4;
5512     float fog_1,        fog_2,      fog_3,      fog_4;
5513     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
5514     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
5515     float binormal_1,   binormal_2, binormal_3, binormal_4;
5516     float depth_1,      depth_2,    depth_3,    depth_4;
5517     DWORD diffuse, specular;
5518 };
5519
5520 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5521     /* dcl_position: fails to compile */
5522     const DWORD blendweight_code[] = {
5523         0xffff0300,                             /* ps_3_0                   */
5524         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
5525         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5526         0x0000ffff                              /* end                      */
5527     };
5528     const DWORD blendindices_code[] = {
5529         0xffff0300,                             /* ps_3_0                   */
5530         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
5531         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5532         0x0000ffff                              /* end                      */
5533     };
5534     const DWORD normal_code[] = {
5535         0xffff0300,                             /* ps_3_0                   */
5536         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
5537         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5538         0x0000ffff                              /* end                      */
5539     };
5540     /* psize: fails? */
5541     const DWORD texcoord0_code[] = {
5542         0xffff0300,                             /* ps_3_0                   */
5543         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
5544         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5545         0x0000ffff                              /* end                      */
5546     };
5547     const DWORD tangent_code[] = {
5548         0xffff0300,                             /* ps_3_0                   */
5549         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
5550         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5551         0x0000ffff                              /* end                      */
5552     };
5553     const DWORD binormal_code[] = {
5554         0xffff0300,                             /* ps_3_0                   */
5555         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
5556         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5557         0x0000ffff                              /* end                      */
5558     };
5559     /* tessfactor: fails */
5560     /* positiont: fails */
5561     const DWORD color_code[] = {
5562         0xffff0300,                             /* ps_3_0                   */
5563         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
5564         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5565         0x0000ffff                              /* end                      */
5566     };
5567     const DWORD fog_code[] = {
5568         0xffff0300,                             /* ps_3_0                   */
5569         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
5570         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5571         0x0000ffff                              /* end                      */
5572     };
5573     const DWORD depth_code[] = {
5574         0xffff0300,                             /* ps_3_0                   */
5575         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
5576         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5577         0x0000ffff                              /* end                      */
5578     };
5579     const DWORD specular_code[] = {
5580         0xffff0300,                             /* ps_3_0                   */
5581         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
5582         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5583         0x0000ffff                              /* end                      */
5584     };
5585     /* sample: fails */
5586
5587     struct varying_test_struct tests[] = {
5588        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
5589        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
5590        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
5591        /* Why does dx not forward the texcoord? */
5592        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
5593        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
5594        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
5595        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
5596        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
5597        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
5598        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
5599     };
5600     /* Declare a monster vertex type :-) */
5601     static const D3DVERTEXELEMENT9 decl_elements[] = {
5602         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5603         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5604         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5605         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5606         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5607         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5608         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5609         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5610         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5611         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5612         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5613         D3DDECL_END()
5614     };
5615     static const D3DVERTEXELEMENT9 decl_elements2[] = {
5616         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
5617         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5618         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5619         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5620         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5621         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5622         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5623         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5624         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5625         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5626         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5627         D3DDECL_END()
5628     };
5629     struct hugeVertex data[4] = {
5630         {
5631             -1.0,   -1.0,   0.1,    1.0,
5632              0.1,    0.1,   0.1,    0.1,
5633              0.2,    0.2,   0.2,    0.2,
5634              0.3,    0.3,   0.3,    0.3,
5635              0.4,    0.4,   0.4,    0.4,
5636              0.50,   0.55,  0.55,   0.55,
5637              0.6,    0.6,   0.6,    0.7,
5638              0.7,    0.7,   0.7,    0.6,
5639              0.8,    0.8,   0.8,    0.8,
5640              0xe6e6e6e6, /* 0.9 * 256 */
5641              0x224488ff  /* Nothing special */
5642         },
5643         {
5644              1.0,   -1.0,   0.1,    1.0,
5645              0.1,    0.1,   0.1,    0.1,
5646              0.2,    0.2,   0.2,    0.2,
5647              0.3,    0.3,   0.3,    0.3,
5648              0.4,    0.4,   0.4,    0.4,
5649              0.50,   0.55,  0.55,   0.55,
5650              0.6,    0.6,   0.6,    0.7,
5651              0.7,    0.7,   0.7,    0.6,
5652              0.8,    0.8,   0.8,    0.8,
5653              0xe6e6e6e6, /* 0.9 * 256 */
5654              0x224488ff /* Nothing special */
5655         },
5656         {
5657             -1.0,    1.0,   0.1,    1.0,
5658              0.1,    0.1,   0.1,    0.1,
5659              0.2,    0.2,   0.2,    0.2,
5660              0.3,    0.3,   0.3,    0.3,
5661              0.4,    0.4,   0.4,    0.4,
5662              0.50,   0.55,  0.55,   0.55,
5663              0.6,    0.6,   0.6,    0.7,
5664              0.7,    0.7,   0.7,    0.6,
5665              0.8,    0.8,   0.8,    0.8,
5666              0xe6e6e6e6, /* 0.9 * 256 */
5667              0x224488ff /* Nothing special */
5668         },
5669         {
5670              1.0,    1.0,   0.1,    1.0,
5671              0.1,    0.1,   0.1,    0.1,
5672              0.2,    0.2,   0.2,    0.2,
5673              0.3,    0.3,   0.3,    0.3,
5674              0.4,    0.4,   0.4,    0.4,
5675              0.50,   0.55,  0.55,   0.55,
5676              0.6,    0.6,   0.6,    0.7,
5677              0.7,    0.7,   0.7,    0.6,
5678              0.8,    0.8,   0.8,    0.8,
5679              0xe6e6e6e6, /* 0.9 * 256 */
5680              0x224488ff /* Nothing special */
5681         },
5682     };
5683     struct hugeVertex data2[4];
5684     IDirect3DVertexDeclaration9 *decl;
5685     IDirect3DVertexDeclaration9 *decl2;
5686     HRESULT hr;
5687     unsigned int i;
5688     DWORD color, r, g, b, r_e, g_e, b_e;
5689     BOOL drawok;
5690
5691     memcpy(data2, data, sizeof(data2));
5692     data2[0].pos_x = 0;     data2[0].pos_y = 0;
5693     data2[1].pos_x = 640;   data2[1].pos_y = 0;
5694     data2[2].pos_x = 0;     data2[2].pos_y = 480;
5695     data2[3].pos_x = 640;   data2[3].pos_y = 480;
5696
5697     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5698     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5699     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5700     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5701     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5702     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5703
5704     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5705     {
5706         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5707         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5708            tests[i].name, hr);
5709     }
5710
5711     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5712     {
5713         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5714         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5715
5716         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5717         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5718
5719         hr = IDirect3DDevice9_BeginScene(device);
5720         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5721         drawok = FALSE;
5722         if(SUCCEEDED(hr))
5723         {
5724             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5725             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5726             drawok = SUCCEEDED(hr);
5727             hr = IDirect3DDevice9_EndScene(device);
5728             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5729         }
5730
5731         /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5732          * the failure and do not check the color if it failed
5733          */
5734         if(!drawok) {
5735             continue;
5736         }
5737
5738         color = getPixelColor(device, 360, 240);
5739         r = color & 0x00ff0000 >> 16;
5740         g = color & 0x0000ff00 >>  8;
5741         b = color & 0x000000ff;
5742         r_e = tests[i].color & 0x00ff0000 >> 16;
5743         g_e = tests[i].color & 0x0000ff00 >>  8;
5744         b_e = tests[i].color & 0x000000ff;
5745
5746         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5747         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5748
5749         if(tests[i].todo) {
5750             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5751                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5752                          tests[i].name, color, tests[i].color);
5753         } else {
5754             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5755                "Test %s returned color 0x%08x, expected 0x%08x\n",
5756                tests[i].name, color, tests[i].color);
5757         }
5758     }
5759
5760     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5761     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5762     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5763     {
5764         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5765         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5766
5767         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5768         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5769
5770         hr = IDirect3DDevice9_BeginScene(device);
5771         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5772         if(SUCCEEDED(hr))
5773         {
5774             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5775             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5776             hr = IDirect3DDevice9_EndScene(device);
5777             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5778         }
5779
5780         color = getPixelColor(device, 360, 240);
5781         r = color & 0x00ff0000 >> 16;
5782         g = color & 0x0000ff00 >>  8;
5783         b = color & 0x000000ff;
5784         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5785         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
5786         b_e = tests[i].color_rhw & 0x000000ff;
5787
5788         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5789         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5790
5791         if(tests[i].todo_rhw) {
5792             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5793              * pipeline
5794              */
5795             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5796                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5797                          tests[i].name, color, tests[i].color_rhw);
5798         } else {
5799             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5800                "Test %s returned color 0x%08x, expected 0x%08x\n",
5801                tests[i].name, color, tests[i].color_rhw);
5802         }
5803     }
5804
5805     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5806     {
5807         IDirect3DPixelShader9_Release(tests[i].shader);
5808     }
5809
5810     IDirect3DVertexDeclaration9_Release(decl2);
5811     IDirect3DVertexDeclaration9_Release(decl);
5812 }
5813
5814 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5815     static const DWORD ps_code[] = {
5816     0xffff0300,                                                             /* ps_3_0                       */
5817     0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0          */
5818     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5819     0x0200001f, 0x8001000a, 0x900f0003,                                     /* dcl_color1 v3                */
5820     0x0200001f, 0x8000000b, 0x900f0004,                                     /* dcl_fog v4                   */
5821     0x0200001f, 0x80030005, 0x900f0005,                                     /* dcl_texcoord3 v5             */
5822     0x0200001f, 0x80000003, 0x900f0006,                                     /* dcl_normal v6                */
5823     0x0200001f, 0x80000006, 0x900f0007,                                     /* dcl_tangent v7               */
5824     0x0200001f, 0x80000001, 0x900f0008,                                     /* dcl_blendweight v8           */
5825     0x0200001f, 0x8000000c, 0x900f0009,                                     /* dcl_depth v9                 */
5826
5827     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5828     0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0                  */
5829     0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800,             /* add r0, r0, v0[aL]           */
5830     0x0000001d,                                                             /* endloop                      */
5831     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5832     0x0000ffff                                                              /* end                          */
5833     };
5834     static const DWORD vs_1_code[] = {
5835     0xfffe0101,                                                             /* vs_1_1                       */
5836     0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5837     0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5838     0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5839     0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5840     0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5841     0x00000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5842     0x00000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5843     0x00000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5844     0x00000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5845     0x00000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5846     0x00000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5847     0x00000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5848     0x00000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5849     0x00000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5850     0x00000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5851     0x00000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5852     0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5853     0x0000ffff
5854     };
5855     DWORD vs_2_code[] = {
5856     0xfffe0200,                                                             /* vs_2_0                       */
5857     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5858     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5859     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5860     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5861     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5862     0x02000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5863     0x02000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5864     0x02000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5865     0x02000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5866     0x02000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5867     0x02000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5868     0x02000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5869     0x02000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5870     0x02000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5871     0x02000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5872     0x02000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5873     0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5874     0x0000ffff                                                              /* end                          */
5875     };
5876     /* TODO: Define normal, tangent, blendweight and depth here */
5877     static const DWORD vs_3_code[] = {
5878     0xfffe0300,                                                             /* vs_3_0                       */
5879     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5880     0x0200001f, 0x8001000a, 0xe00f0009,                                     /* dcl_color1 o9                */
5881     0x0200001f, 0x8000000b, 0xe00f0002,                                     /* dcl_fog o2                   */
5882     0x0200001f, 0x80030005, 0xe00f0005,                                     /* dcl_texcoord3 o5             */
5883     0x0200001f, 0x80000000, 0xe00f000b,                                     /* dcl_position o11             */
5884     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5885     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5886     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5887     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5888     0x02000001, 0xe00f0009, 0xa0e40000,                                     /* mov o9, c0                   */
5889     0x02000001, 0xe00f0002, 0xa0e40001,                                     /* mov o2, c1                   */
5890     0x02000001, 0xe00f0005, 0xa0e40002,                                     /* mov o5, c2                   */
5891     0x02000001, 0xe00f000b, 0x90e40000,                                     /* mov o11, v0                  */
5892     0x0000ffff                                                              /* end                          */
5893     };
5894     float quad1[] =  {
5895         -1.0,   -1.0,   0.1,
5896          0.0,   -1.0,   0.1,
5897         -1.0,    0.0,   0.1,
5898          0.0,    0.0,   0.1
5899     };
5900     float quad2[] =  {
5901          0.0,   -1.0,   0.1,
5902          1.0,   -1.0,   0.1,
5903          0.0,    0.0,   0.1,
5904          1.0,    0.0,   0.1
5905     };
5906     float quad3[] =  {
5907         -1.0,    0.0,   0.1,
5908          0.0,    0.0,   0.1,
5909         -1.0,    1.0,   0.1,
5910          0.0,    1.0,   0.1
5911     };
5912
5913     HRESULT hr;
5914     DWORD color;
5915     IDirect3DPixelShader9 *pixelshader = NULL;
5916     IDirect3DVertexShader9 *vs_1_shader = NULL;
5917     IDirect3DVertexShader9 *vs_2_shader = NULL;
5918     IDirect3DVertexShader9 *vs_3_shader = NULL;
5919
5920     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5921     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5922
5923     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5924     ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %08x\n", hr);
5925     hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5926     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5927     hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5928     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5929     hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5930     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5931     hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5932     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5933     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5934
5935     hr = IDirect3DDevice9_BeginScene(device);
5936     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5937     if(SUCCEEDED(hr))
5938     {
5939         hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5940         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5941         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5942         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5943
5944         hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5945         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5946         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5947         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5948
5949         hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5950         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5951         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5952         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5953
5954         hr = IDirect3DDevice9_EndScene(device);
5955         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5956     }
5957
5958     color = getPixelColor(device, 160, 120);
5959     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x1a, 0x34, 0x67), 1),
5960        "vs_3_0 returned color 0x%08x, expected 0x00193366\n", color);
5961     /* Accept two ways of oFog handling:
5962      *
5963      * oFog is supposed to be a scalar. The pixel shader declares a vec4 oFog input and reads all components.
5964      * The vertex shader writes oFog without a writemask. There are two ways windows drivers deal with this:
5965      *
5966      * 1) Keep oFog a scalar, and assign v4 = {oFog, 0, 0, 0}. oFog = 0x33, so the result color is 004d0067.
5967      *    This happens with software vertex processing and on Intel cards
5968      *
5969      * 2) Make oFog a vec4, and assign v4 = {oFog.x, oFog.y, oFog.z, oFog.w}. This way the result color is
5970      *    0x004d339a. This happens on Nvidia Geforce 6+ cards
5971      */
5972     color = getPixelColor(device, 160, 360);
5973     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5974        color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5975        "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5976     color = getPixelColor(device, 480, 360);
5977     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5978        color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5979        "vs_2_0 returned color 0x%08x, expected 0x004d0067 or 0x004d33a0\n", color);
5980
5981     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5982     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5983
5984     /* cleanup */
5985     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5986     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5987     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5988     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5989     if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5990     if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5991     if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5992     if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5993 }
5994
5995 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5996     static const DWORD vs_code[] = {
5997     0xfffe0300,                                                             /* vs_3_0                       */
5998     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5999     0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0              */
6000     0x0200001f, 0x8000000a, 0xe00f0001,                                     /* dcl_color0 o1                */
6001     0x0200001f, 0x80000005, 0xe00f0002,                                     /* dcl_texcoord0 o2             */
6002     0x0200001f, 0x8000000b, 0xe00f0003,                                     /* dcl_fog o3                   */
6003     0x0200001f, 0x80000003, 0xe00f0004,                                     /* dcl_normal o4                */
6004     0x0200001f, 0x8000000c, 0xe00f0005,                                     /* dcl_depth o5                 */
6005     0x0200001f, 0x80000006, 0xe00f0006,                                     /* dcl_tangent o6               */
6006     0x0200001f, 0x80000001, 0xe00f0007,                                     /* dcl_blendweight o7           */
6007     0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0   */
6008     0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0   */
6009     0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0   */
6010     0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0   */
6011
6012     0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                   */
6013     0x02000001, 0xe00f0001, 0xa0e40001,                                     /* mov o1, c1                   */
6014     0x02000001, 0xe00f0002, 0xa0e40002,                                     /* mov o2, c2                   */
6015     0x02000001, 0xe00f0003, 0xa0e40003,                                     /* mov o3, c3                   */
6016     0x02000001, 0xe00f0004, 0xa0e40000,                                     /* mov o4, c0                   */
6017     0x02000001, 0xe00f0005, 0xa0e40000,                                     /* mov o5, c0                   */
6018     0x02000001, 0xe00f0006, 0xa0e40000,                                     /* mov o6, c0                   */
6019     0x02000001, 0xe00f0007, 0xa0e40000,                                     /* mov o7, c0                   */
6020     0x0000ffff                                                              /* end                          */
6021     };
6022     static const DWORD ps_1_code[] = {
6023     0xffff0104,                                                             /* ps_1_4                       */
6024     0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
6025     0x00000040, 0x80070001, 0xb0e40000,                                     /* texcrd r1.xyz, t0            */
6026     0x00000001, 0x80080001, 0xa0ff0000,                                     /* mov r1.a, c0.a               */
6027     0x00000002, 0x800f0000, 0x90e40000, 0x80e40001,                         /* add r0, v0, r1               */
6028     0x0000ffff                                                              /* end                          */
6029     };
6030     static const DWORD ps_2_code[] = {
6031     0xffff0200,                                                             /* ps_2_0                       */
6032     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
6033     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl v0                       */
6034     0x0200001f, 0x80000000, 0x900f0001,                                     /* dcl v1                       */
6035
6036     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
6037     0x03000002, 0x800f0000, 0x80e40000,0xb0e40000,                          /* add r0, r0, t0               */
6038     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
6039     0x0000ffff                                                              /* end                          */
6040     };
6041     static const DWORD ps_3_code[] = {
6042     0xffff0300,                                                             /* ps_3_0                       */
6043     0x0200001f, 0x80000005, 0x900f0000,                                     /* dcl_texcoord0 v0             */
6044     0x0200001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
6045     0x0200001f, 0x8000000b, 0x900f0002,                                     /* dcl_fog v2                   */
6046
6047     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
6048     0x03000002, 0x800f0000, 0x80e40000, 0x90e40001,                         /* add r0, r0, v1               */
6049     0x03000002, 0x800f0000, 0x80e40000, 0x90e40002,                         /* mov r0, r0, v2               */
6050     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
6051     0x0000ffff                                                              /* end                          */
6052     };
6053
6054     float quad1[] =  {
6055         -1.0,   -1.0,   0.1,
6056          0.0,   -1.0,   0.1,
6057         -1.0,    0.0,   0.1,
6058          0.0,    0.0,   0.1
6059     };
6060     float quad2[] =  {
6061          0.0,   -1.0,   0.1,
6062          1.0,   -1.0,   0.1,
6063          0.0,    0.0,   0.1,
6064          1.0,    0.0,   0.1
6065     };
6066     float quad3[] =  {
6067         -1.0,    0.0,   0.1,
6068          0.0,    0.0,   0.1,
6069         -1.0,    1.0,   0.1,
6070          0.0,    1.0,   0.1
6071     };
6072     float quad4[] =  {
6073          0.0,    0.0,   0.1,
6074          1.0,    0.0,   0.1,
6075          0.0,    1.0,   0.1,
6076          1.0,    1.0,   0.1
6077     };
6078
6079     HRESULT hr;
6080     DWORD color;
6081     IDirect3DVertexShader9 *vertexshader = NULL;
6082     IDirect3DPixelShader9 *ps_1_shader = NULL;
6083     IDirect3DPixelShader9 *ps_2_shader = NULL;
6084     IDirect3DPixelShader9 *ps_3_shader = NULL;
6085     IDirect3DTexture9 *texture = NULL;
6086     D3DLOCKED_RECT lr;
6087     unsigned int x, y;
6088
6089     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6090     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6091
6092     hr = IDirect3DDevice9_CreateTexture(device, 512,  512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
6093     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
6094     if(FAILED(hr)) {
6095         skip("D3DFMT_A16B16G16R16 textures not supported\n");
6096         return;
6097     }
6098     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
6099     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
6100     for(y = 0; y < 512; y++) {
6101         for(x = 0; x < 512; x++) {
6102             double r_f = (double) x / (double) 512;
6103             double g_f = (double) y / (double) 512;
6104             unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
6105             unsigned short r = (unsigned short) (r_f * 65535.0);
6106             unsigned short g = (unsigned short) (g_f * 65535.0);
6107             dst[0] = r;
6108             dst[1] = g;
6109             dst[2] = 0;
6110             dst[3] = 65535;
6111         }
6112     }
6113     hr = IDirect3DTexture9_UnlockRect(texture, 0);
6114     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
6115
6116     hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
6117     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6118     hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
6119     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6120     hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
6121     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6122     hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
6123     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6124     hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
6125     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6126     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6127
6128     hr = IDirect3DDevice9_BeginScene(device);
6129     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6130     if(SUCCEEDED(hr))
6131     {
6132         hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
6133         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6134         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6135         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6136
6137         hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
6138         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6139         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
6140         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6141
6142         hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
6143         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6144         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6145         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6146
6147         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6148         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6149         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6150         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
6151         hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
6152         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
6153         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
6154         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
6155         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6156         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
6157         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
6158         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
6159         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6160         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6161
6162         hr = IDirect3DDevice9_EndScene(device);
6163         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6164     }
6165
6166     color = getPixelColor(device, 160, 120);
6167     ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
6168        (color & 0x0000ff00) == 0x0000ff00 &&
6169        (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
6170        "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
6171     color = getPixelColor(device, 160, 360);
6172     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
6173        (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
6174        (color & 0x000000ff) == 0x00000000,
6175        "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
6176     color = getPixelColor(device, 480, 360);
6177     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
6178        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
6179        (color & 0x000000ff) == 0x00000000,
6180        "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
6181     color = getPixelColor(device, 480, 160);
6182     ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
6183        (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
6184        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
6185        (color & 0x000000ff) == 0x00000000),
6186        "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
6187
6188     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6189     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6190
6191     /* cleanup */
6192     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6193     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
6194     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6195     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6196     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6197     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6198     if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
6199     if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
6200     if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
6201     if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
6202     if(texture) IDirect3DTexture9_Release(texture);
6203 }
6204
6205 static void test_compare_instructions(IDirect3DDevice9 *device)
6206 {
6207     DWORD shader_sge_vec_code[] = {
6208         0xfffe0101,                                         /* vs_1_1                   */
6209         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6210         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6211         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6212         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
6213         0x0000ffff                                          /* end                      */
6214     };
6215     DWORD shader_slt_vec_code[] = {
6216         0xfffe0101,                                         /* vs_1_1                   */
6217         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6218         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6219         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6220         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
6221         0x0000ffff                                          /* end                      */
6222     };
6223     DWORD shader_sge_scalar_code[] = {
6224         0xfffe0101,                                         /* vs_1_1                   */
6225         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6226         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6227         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6228         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
6229         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
6230         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
6231         0x0000ffff                                          /* end                      */
6232     };
6233     DWORD shader_slt_scalar_code[] = {
6234         0xfffe0101,                                         /* vs_1_1                   */
6235         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6236         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6237         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6238         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
6239         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
6240         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
6241         0x0000ffff                                          /* end                      */
6242     };
6243     IDirect3DVertexShader9 *shader_sge_vec;
6244     IDirect3DVertexShader9 *shader_slt_vec;
6245     IDirect3DVertexShader9 *shader_sge_scalar;
6246     IDirect3DVertexShader9 *shader_slt_scalar;
6247     HRESULT hr, color;
6248     float quad1[] =  {
6249         -1.0,   -1.0,   0.1,
6250          0.0,   -1.0,   0.1,
6251         -1.0,    0.0,   0.1,
6252          0.0,    0.0,   0.1
6253     };
6254     float quad2[] =  {
6255          0.0,   -1.0,   0.1,
6256          1.0,   -1.0,   0.1,
6257          0.0,    0.0,   0.1,
6258          1.0,    0.0,   0.1
6259     };
6260     float quad3[] =  {
6261         -1.0,    0.0,   0.1,
6262          0.0,    0.0,   0.1,
6263         -1.0,    1.0,   0.1,
6264          0.0,    1.0,   0.1
6265     };
6266     float quad4[] =  {
6267          0.0,    0.0,   0.1,
6268          1.0,    0.0,   0.1,
6269          0.0,    1.0,   0.1,
6270          1.0,    1.0,   0.1
6271     };
6272     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
6273     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
6274
6275     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6276     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6277
6278     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
6279     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6280     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
6281     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6282     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
6283     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6284     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
6285     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6286     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6287     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6288     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
6289     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6290     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6291     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
6292
6293     hr = IDirect3DDevice9_BeginScene(device);
6294     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6295     if(SUCCEEDED(hr))
6296     {
6297         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
6298         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6299         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6300         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6301
6302         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
6303         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6304         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
6305         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6306
6307         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
6308         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6309         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6310         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6311
6312         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6313         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6314
6315         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
6316         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6317         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6318         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6319
6320         hr = IDirect3DDevice9_EndScene(device);
6321         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6322     }
6323
6324     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6325     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6326
6327     color = getPixelColor(device, 160, 360);
6328     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
6329     color = getPixelColor(device, 480, 360);
6330     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
6331     color = getPixelColor(device, 160, 120);
6332     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
6333     color = getPixelColor(device, 480, 160);
6334     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
6335
6336     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6337     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6338
6339     IDirect3DVertexShader9_Release(shader_sge_vec);
6340     IDirect3DVertexShader9_Release(shader_slt_vec);
6341     IDirect3DVertexShader9_Release(shader_sge_scalar);
6342     IDirect3DVertexShader9_Release(shader_slt_scalar);
6343 }
6344
6345 static void test_vshader_input(IDirect3DDevice9 *device)
6346 {
6347     DWORD swapped_shader_code_3[] = {
6348         0xfffe0300,                                         /* vs_3_0               */
6349         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6350         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6351         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6352         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6353         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6354         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6355         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6356         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6357         0x0000ffff                                          /* end                  */
6358     };
6359     DWORD swapped_shader_code_1[] = {
6360         0xfffe0101,                                         /* vs_1_1               */
6361         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6362         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6363         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6364         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6365         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6366         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6367         0x0000ffff                                          /* end                  */
6368     };
6369     DWORD swapped_shader_code_2[] = {
6370         0xfffe0200,                                         /* vs_2_0               */
6371         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6372         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6373         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6374         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6375         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6376         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6377         0x0000ffff                                          /* end                  */
6378     };
6379     DWORD texcoord_color_shader_code_3[] = {
6380         0xfffe0300,                                         /* vs_3_0               */
6381         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6382         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6383         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6384         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6385         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6386         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
6387         0x0000ffff                                          /* end                  */
6388     };
6389     DWORD texcoord_color_shader_code_2[] = {
6390         0xfffe0200,                                         /* vs_2_0               */
6391         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6392         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6393         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6394         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6395         0x0000ffff                                          /* end                  */
6396     };
6397     DWORD texcoord_color_shader_code_1[] = {
6398         0xfffe0101,                                         /* vs_1_1               */
6399         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6400         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6401         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6402         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6403         0x0000ffff                                          /* end                  */
6404     };
6405     DWORD color_color_shader_code_3[] = {
6406         0xfffe0300,                                         /* vs_3_0               */
6407         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6408         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6409         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6410         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6411         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6412         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
6413         0x0000ffff                                          /* end                  */
6414     };
6415     DWORD color_color_shader_code_2[] = {
6416         0xfffe0200,                                         /* vs_2_0               */
6417         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6418         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6419         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6420         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6421         0x0000ffff                                          /* end                  */
6422     };
6423     DWORD color_color_shader_code_1[] = {
6424         0xfffe0101,                                         /* vs_1_1               */
6425         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6426         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6427         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6428         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6429         0x0000ffff                                          /* end                  */
6430     };
6431     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6432     HRESULT hr;
6433     DWORD color;
6434     float quad1[] =  {
6435         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6436          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6437         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6438          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6439     };
6440     float quad2[] =  {
6441          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6442          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6443          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6444          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6445     };
6446     float quad3[] =  {
6447         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
6448          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
6449         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
6450          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6451     };
6452     float quad4[] =  {
6453          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6454          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6455          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6456          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6457     };
6458     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6459         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6460         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6461         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6462         D3DDECL_END()
6463     };
6464     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6465         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6466         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6467         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6468         D3DDECL_END()
6469     };
6470     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6471         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6472         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6473         D3DDECL_END()
6474     };
6475     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6476         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6477         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6478         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
6479         D3DDECL_END()
6480     };
6481     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6482         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6483         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6484         D3DDECL_END()
6485     };
6486     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6487         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6488         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6489         D3DDECL_END()
6490     };
6491     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6492         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6493         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6494         D3DDECL_END()
6495     };
6496     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6497         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6498         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6499         D3DDECL_END()
6500     };
6501     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6502     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6503     unsigned int i;
6504     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6505     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6506
6507     struct vertex quad1_color[] =  {
6508        {-1.0,   -1.0,   0.1,    0x00ff8040},
6509        { 0.0,   -1.0,   0.1,    0x00ff8040},
6510        {-1.0,    0.0,   0.1,    0x00ff8040},
6511        { 0.0,    0.0,   0.1,    0x00ff8040}
6512     };
6513     struct vertex quad2_color[] =  {
6514        { 0.0,   -1.0,   0.1,    0x00ff8040},
6515        { 1.0,   -1.0,   0.1,    0x00ff8040},
6516        { 0.0,    0.0,   0.1,    0x00ff8040},
6517        { 1.0,    0.0,   0.1,    0x00ff8040}
6518     };
6519     struct vertex quad3_color[] =  {
6520        {-1.0,    0.0,   0.1,    0x00ff8040},
6521        { 0.0,    0.0,   0.1,    0x00ff8040},
6522        {-1.0,    1.0,   0.1,    0x00ff8040},
6523        { 0.0,    1.0,   0.1,    0x00ff8040}
6524     };
6525     float quad4_color[] =  {
6526          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6527          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6528          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6529          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6530     };
6531
6532     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6533     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6534     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6535     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6536     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6537     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6538     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6539     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6540
6541     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6542     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6543     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6544     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6545     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6546     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6547     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6548     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6549
6550     for(i = 1; i <= 3; i++) {
6551         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6552         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6553         if(i == 3) {
6554             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6555             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6556         } else if(i == 2){
6557             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6558             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6559         } else if(i == 1) {
6560             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6561             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6562         }
6563
6564         hr = IDirect3DDevice9_BeginScene(device);
6565         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6566         if(SUCCEEDED(hr))
6567         {
6568             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6569             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6570
6571             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6572             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6573             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6574             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6575
6576             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6577             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6578             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6579             if(i == 3 || i == 2) {
6580                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6581             } else if(i == 1) {
6582                 /* Succeeds or fails, depending on SW or HW vertex processing */
6583                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6584             }
6585
6586             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6587             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6588             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6589             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6590
6591             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6592             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6593             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6594             if(i == 3 || i == 2) {
6595                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6596             } else if(i == 1) {
6597                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6598             }
6599
6600             hr = IDirect3DDevice9_EndScene(device);
6601             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6602         }
6603
6604         if(i == 3 || i == 2) {
6605             color = getPixelColor(device, 160, 360);
6606             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6607                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6608
6609             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6610             color = getPixelColor(device, 480, 360);
6611             ok(color == 0x00FFFF00 || color ==0x00FF0000,
6612                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6613             color = getPixelColor(device, 160, 120);
6614             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6615             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6616                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6617
6618             color = getPixelColor(device, 480, 160);
6619             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6620         } else if(i == 1) {
6621             color = getPixelColor(device, 160, 360);
6622             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6623                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6624             color = getPixelColor(device, 480, 360);
6625             /* Accept the clear color as well in this case, since SW VP returns an error */
6626             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6627             color = getPixelColor(device, 160, 120);
6628             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6629                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6630             color = getPixelColor(device, 480, 160);
6631             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6632         }
6633
6634         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6635         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6636
6637         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6638         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6639
6640         /* Now find out if the whole streams are re-read, or just the last active value for the
6641          * vertices is used.
6642          */
6643         hr = IDirect3DDevice9_BeginScene(device);
6644         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6645         if(SUCCEEDED(hr))
6646         {
6647             float quad1_modified[] =  {
6648                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6649                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6650                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6651                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6652             };
6653             float quad2_modified[] =  {
6654                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6655                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6656                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6657                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6658             };
6659
6660             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6661             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6662
6663             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6664             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6665             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6666             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6667
6668             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6669             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6670             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6671             if(i == 3 || i == 2) {
6672                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6673             } else if(i == 1) {
6674                 /* Succeeds or fails, depending on SW or HW vertex processing */
6675                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6676             }
6677
6678             hr = IDirect3DDevice9_EndScene(device);
6679             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6680         }
6681
6682         color = getPixelColor(device, 480, 350);
6683         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6684          * as well.
6685          *
6686          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6687          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6688          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6689          * refrast's result.
6690          *
6691          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6692          */
6693         ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6694            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6695
6696         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6697         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6698
6699         IDirect3DDevice9_SetVertexShader(device, NULL);
6700         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6701
6702         IDirect3DVertexShader9_Release(swapped_shader);
6703     }
6704
6705     for(i = 1; i <= 3; i++) {
6706         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6707         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6708         if(i == 3) {
6709             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6710             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6711             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6712             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6713         } else if(i == 2){
6714             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6715             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6716             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6717             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6718         } else if(i == 1) {
6719             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6720             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6721             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6722             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6723         }
6724
6725         hr = IDirect3DDevice9_BeginScene(device);
6726         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6727         if(SUCCEEDED(hr))
6728         {
6729             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6730             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6731             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6732             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6733             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6734             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6735
6736             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6737             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6738
6739             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6740             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6741             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6742             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6743             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6744             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6745
6746             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6747             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6748             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6749             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6750             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6751             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6752
6753             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6754             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6755             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6756             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6757
6758             hr = IDirect3DDevice9_EndScene(device);
6759             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6760         }
6761         IDirect3DDevice9_SetVertexShader(device, NULL);
6762         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6763
6764         color = getPixelColor(device, 160, 360);
6765         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6766            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6767         color = getPixelColor(device, 480, 360);
6768         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6769            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6770         color = getPixelColor(device, 160, 120);
6771         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6772            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6773         color = getPixelColor(device, 480, 160);
6774         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6775            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6776
6777         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6778         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6779
6780         IDirect3DVertexShader9_Release(texcoord_color_shader);
6781         IDirect3DVertexShader9_Release(color_color_shader);
6782     }
6783
6784     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6785     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6786     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6787     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6788
6789     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6790     IDirect3DVertexDeclaration9_Release(decl_color_color);
6791     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6792     IDirect3DVertexDeclaration9_Release(decl_color_float);
6793 }
6794
6795 static void srgbtexture_test(IDirect3DDevice9 *device)
6796 {
6797     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6798      * texture stage state to render a quad using that texture.  The resulting
6799      * color components should be 0x36 (~ 0.21), per this formula:
6800      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6801      * This is true where srgb_color > 0.04045.
6802      */
6803     IDirect3D9 *d3d = NULL;
6804     HRESULT hr;
6805     LPDIRECT3DTEXTURE9 texture = NULL;
6806     LPDIRECT3DSURFACE9 surface = NULL;
6807     D3DLOCKED_RECT lr;
6808     DWORD color;
6809     float quad[] = {
6810         -1.0,       1.0,       0.0,     0.0,    0.0,
6811          1.0,       1.0,       0.0,     1.0,    0.0,
6812         -1.0,      -1.0,       0.0,     0.0,    1.0,
6813          1.0,      -1.0,       0.0,     1.0,    1.0,
6814     };
6815
6816
6817     memset(&lr, 0, sizeof(lr));
6818     IDirect3DDevice9_GetDirect3D(device, &d3d);
6819     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6820                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6821                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6822         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6823         goto out;
6824     }
6825
6826     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6827                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6828                                         &texture, NULL);
6829     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6830     if(!texture) {
6831         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6832         goto out;
6833     }
6834     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6835     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6836
6837     fill_surface(surface, 0xff7f7f7f);
6838     IDirect3DSurface9_Release(surface);
6839
6840     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6841     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6842     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6843     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6844
6845     hr = IDirect3DDevice9_BeginScene(device);
6846     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6847     if(SUCCEEDED(hr))
6848     {
6849         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6850         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6851
6852         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6853         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6854
6855
6856         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6857         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6858
6859         hr = IDirect3DDevice9_EndScene(device);
6860         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6861     }
6862
6863     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6864     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6865     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6866     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6867
6868     color = getPixelColor(device, 320, 240);
6869     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6870
6871     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6872     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6873
6874 out:
6875     if(texture) IDirect3DTexture9_Release(texture);
6876     IDirect3D9_Release(d3d);
6877 }
6878
6879 static void shademode_test(IDirect3DDevice9 *device)
6880 {
6881     /* Render a quad and try all of the different fixed function shading models. */
6882     HRESULT hr;
6883     DWORD color0, color1;
6884     DWORD color0_gouraud = 0, color1_gouraud = 0;
6885     DWORD shademode = D3DSHADE_FLAT;
6886     DWORD primtype = D3DPT_TRIANGLESTRIP;
6887     LPVOID data = NULL;
6888     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6889     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6890     UINT i, j;
6891     struct vertex quad_strip[] =
6892     {
6893         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6894         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6895         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6896         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6897     };
6898     struct vertex quad_list[] =
6899     {
6900         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6901         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6902         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6903
6904         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6905         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6906         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6907     };
6908
6909     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6910                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6911     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6912     if (FAILED(hr)) goto bail;
6913
6914     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6915                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6916     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6917     if (FAILED(hr)) goto bail;
6918
6919     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6920     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6921
6922     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6923     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6924
6925     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6926     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6927     memcpy(data, quad_strip, sizeof(quad_strip));
6928     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6929     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6930
6931     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6932     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6933     memcpy(data, quad_list, sizeof(quad_list));
6934     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6935     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6936
6937     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
6938      * the color fixups we have to do for FLAT shading will be dependent on that. */
6939     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6940     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6941
6942     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6943     for (j=0; j<2; j++) {
6944
6945         /* Inner loop just changes the D3DRS_SHADEMODE */
6946         for (i=0; i<3; i++) {
6947             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6948             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6949
6950             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6951             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6952
6953             hr = IDirect3DDevice9_BeginScene(device);
6954             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6955             if(SUCCEEDED(hr))
6956             {
6957                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6958                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6959
6960                 hr = IDirect3DDevice9_EndScene(device);
6961                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6962             }
6963
6964             /* Sample two spots from the output */
6965             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6966             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6967             switch(shademode) {
6968                 case D3DSHADE_FLAT:
6969                     /* Should take the color of the first vertex of each triangle */
6970                     if (0)
6971                     {
6972                         /* This test depends on EXT_provoking_vertex being
6973                          * available. This extension is currently (20090810)
6974                          * not common enough to let the test fail if it isn't
6975                          * present. */
6976                         ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
6977                         ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
6978                     }
6979                     shademode = D3DSHADE_GOURAUD;
6980                     break;
6981                 case D3DSHADE_GOURAUD:
6982                     /* Should be an interpolated blend */
6983
6984                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6985                        "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6986                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6987                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6988
6989                     color0_gouraud = color0;
6990                     color1_gouraud = color1;
6991
6992                     shademode = D3DSHADE_PHONG;
6993                     break;
6994                 case D3DSHADE_PHONG:
6995                     /* Should be the same as GOURAUD, since no hardware implements this */
6996                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6997                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6998                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6999                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
7000
7001                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7002                             color0_gouraud, color0);
7003                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7004                             color1_gouraud, color1);
7005                     break;
7006             }
7007         }
7008
7009         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7010         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7011
7012         /* Now, do it all over again with a TRIANGLELIST */
7013         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
7014         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7015         primtype = D3DPT_TRIANGLELIST;
7016         shademode = D3DSHADE_FLAT;
7017     }
7018
7019 bail:
7020     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7021     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7022     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
7023     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7024
7025     if (vb_strip)
7026         IDirect3DVertexBuffer9_Release(vb_strip);
7027     if (vb_list)
7028         IDirect3DVertexBuffer9_Release(vb_list);
7029 }
7030
7031
7032 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
7033 {
7034     /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
7035      * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
7036      * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
7037      * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
7038      * 0.73
7039      *
7040      * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
7041      * so use shaders for this task
7042      */
7043     IDirect3DPixelShader9 *pshader;
7044     IDirect3DVertexShader9 *vshader;
7045     IDirect3D9 *d3d;
7046     DWORD vshader_code[] = {
7047         0xfffe0101,                                                             /* vs_1_1                       */
7048         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
7049         0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0   */
7050         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
7051         0x00000001, 0xc00f0001, 0xa0000000,                                     /* mov oFog, c0.x               */
7052         0x0000ffff                                                              /* end                          */
7053     };
7054     DWORD pshader_code[] = {
7055         0xffff0101,                                                             /* ps_1_1                       */
7056         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
7057         0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
7058         0x0000ffff                                                              /* end                          */
7059     };
7060     const float quad[] = {
7061        -1.0,   -1.0,    0.1,
7062         1.0,   -1.0,    0.1,
7063        -1.0,    1.0,    0.1,
7064         1.0,    1.0,    0.1
7065     };
7066     HRESULT hr;
7067     D3DCOLOR color;
7068
7069     IDirect3DDevice9_GetDirect3D(device, &d3d);
7070     /* Ask for srgb writing on D3DRTYPE_TEXTURE. Some Windows drivers do not report it on surfaces.
7071      * For some not entirely understood reasons D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE
7072      * passes on surfaces, while asking for SRGBWRITE alone fails. Textures advertize srgb writing
7073      * alone as well, so use that since it is not the point of this test to show how CheckDeviceFormat
7074      * works
7075      */
7076     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
7077                                     D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
7078                                     D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK) {
7079         skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
7080         IDirect3D9_Release(d3d);
7081         return;
7082     }
7083     IDirect3D9_Release(d3d);
7084
7085     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
7086     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7087
7088     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
7089     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7090     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
7091     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7092     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
7093     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7094     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
7095     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7096     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
7097     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7098
7099     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
7100     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7101     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
7102     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
7103     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7104     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
7105     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
7106     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
7107     hr = IDirect3DDevice9_SetPixelShader(device, pshader);
7108     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7109
7110     hr = IDirect3DDevice9_BeginScene(device);
7111     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
7112     if(SUCCEEDED(hr)) {
7113         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
7114         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7115
7116         hr = IDirect3DDevice9_EndScene(device);
7117         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
7118     }
7119
7120     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7121     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
7122     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7123     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7124     IDirect3DPixelShader9_Release(pshader);
7125     IDirect3DVertexShader9_Release(vshader);
7126
7127     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
7128     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7129     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
7130     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7131
7132     color = getPixelColor(device, 160, 360);
7133     ok(color_match(color, 0x00808080, 1),
7134             "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
7135     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7136     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7137 }
7138
7139 static void alpha_test(IDirect3DDevice9 *device)
7140 {
7141     HRESULT hr;
7142     IDirect3DTexture9 *offscreenTexture;
7143     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
7144     DWORD color;
7145
7146     struct vertex quad1[] =
7147     {
7148         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
7149         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
7150         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
7151         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
7152     };
7153     struct vertex quad2[] =
7154     {
7155         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
7156         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
7157         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
7158         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
7159     };
7160     static const float composite_quad[][5] = {
7161         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
7162         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
7163         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
7164         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
7165     };
7166
7167     /* Clear the render target with alpha = 0.5 */
7168     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7169     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7170
7171     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
7172     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
7173
7174     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7175     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7176     if(!backbuffer) {
7177         goto out;
7178     }
7179
7180     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
7181     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
7182     if(!offscreen) {
7183         goto out;
7184     }
7185
7186     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7187     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7188
7189     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7190     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7191     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7192     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7193     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
7194     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
7195     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
7196     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
7197     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7198     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7199
7200     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
7201     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7202     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
7203
7204         /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
7205         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7206         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7207         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7208         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7209         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7210         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7211
7212         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7213         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7214         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7215         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7216         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7217         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7218
7219         /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
7220          * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
7221          * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
7222         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
7223         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7224         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7225         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7226
7227         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7228         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7229         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7230         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7231         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7232         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7233
7234         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7235         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7236         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7237         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7238         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7239         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7240
7241         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7242         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7243
7244         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
7245          * Disable alpha blending for the final composition
7246          */
7247         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
7248         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7249         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7250         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7251
7252         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
7253         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7254         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
7255         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7256         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7257         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7258
7259         hr = IDirect3DDevice9_EndScene(device);
7260         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
7261     }
7262
7263     color = getPixelColor(device, 160, 360);
7264     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7265        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
7266
7267     color = getPixelColor(device, 160, 120);
7268     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
7269        "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
7270
7271     color = getPixelColor(device, 480, 360);
7272     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7273        "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
7274
7275     color = getPixelColor(device, 480, 120);
7276     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
7277        "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
7278
7279     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7280
7281     out:
7282     /* restore things */
7283     if(backbuffer) {
7284         IDirect3DSurface9_Release(backbuffer);
7285     }
7286     if(offscreenTexture) {
7287         IDirect3DTexture9_Release(offscreenTexture);
7288     }
7289     if(offscreen) {
7290         IDirect3DSurface9_Release(offscreen);
7291     }
7292 }
7293
7294 struct vertex_shortcolor {
7295     float x, y, z;
7296     unsigned short r, g, b, a;
7297 };
7298 struct vertex_floatcolor {
7299     float x, y, z;
7300     float r, g, b, a;
7301 };
7302
7303 static void fixed_function_decl_test(IDirect3DDevice9 *device)
7304 {
7305     HRESULT hr;
7306     BOOL s_ok, ub_ok, f_ok;
7307     DWORD color, size, i;
7308     void *data;
7309     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
7310         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7311         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7312         D3DDECL_END()
7313     };
7314     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
7315         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7316         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7317         D3DDECL_END()
7318     };
7319     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
7320         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7321         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7322         D3DDECL_END()
7323     };
7324     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
7325         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7326         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7327         D3DDECL_END()
7328     };
7329     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
7330         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7331         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7332         D3DDECL_END()
7333     };
7334     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
7335         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7336         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7337         D3DDECL_END()
7338     };
7339     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
7340         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
7341         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7342         D3DDECL_END()
7343     };
7344     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
7345     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
7346     IDirect3DVertexBuffer9 *vb, *vb2;
7347     struct vertex quad1[] =                             /* D3DCOLOR */
7348     {
7349         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
7350         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7351         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
7352         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7353     };
7354     struct vertex quad2[] =                             /* UBYTE4N */
7355     {
7356         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7357         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
7358         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7359         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
7360     };
7361     struct vertex_shortcolor quad3[] =                  /* short */
7362     {
7363         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7364         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7365         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7366         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7367     };
7368     struct vertex_floatcolor quad4[] =
7369     {
7370         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7371         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7372         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7373         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7374     };
7375     DWORD colors[] = {
7376         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7377         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7378         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7379         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7380         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7381         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7382         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7383         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7384         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7385         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7386         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7387         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7388         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7389         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7390         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7391         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7392     };
7393     float quads[] = {
7394         -1.0,   -1.0,     0.1,
7395         -1.0,    0.0,     0.1,
7396          0.0,   -1.0,     0.1,
7397          0.0,    0.0,     0.1,
7398
7399          0.0,   -1.0,     0.1,
7400          0.0,    0.0,     0.1,
7401          1.0,   -1.0,     0.1,
7402          1.0,    0.0,     0.1,
7403
7404          0.0,    0.0,     0.1,
7405          0.0,    1.0,     0.1,
7406          1.0,    0.0,     0.1,
7407          1.0,    1.0,     0.1,
7408
7409         -1.0,    0.0,     0.1,
7410         -1.0,    1.0,     0.1,
7411          0.0,    0.0,     0.1,
7412          0.0,    1.0,     0.1
7413     };
7414     struct tvertex quad_transformed[] = {
7415        {  90,    110,     0.1,      2.0,        0x00ffff00},
7416        { 570,    110,     0.1,      2.0,        0x00ffff00},
7417        {  90,    300,     0.1,      2.0,        0x00ffff00},
7418        { 570,    300,     0.1,      2.0,        0x00ffff00}
7419     };
7420     D3DCAPS9 caps;
7421
7422     memset(&caps, 0, sizeof(caps));
7423     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7424     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7425
7426     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7427     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7428
7429     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7430     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7431     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7432     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7433     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7434     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7435     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7436         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7437         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7438         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7439         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7440     } else {
7441         trace("D3DDTCAPS_UBYTE4N not supported\n");
7442         dcl_ubyte_2 = NULL;
7443         dcl_ubyte = NULL;
7444     }
7445     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7446     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7447     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7448     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7449
7450     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7451     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7452                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
7453     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7454
7455     hr = IDirect3DDevice9_BeginScene(device);
7456     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7457     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7458     if(SUCCEEDED(hr)) {
7459         if(dcl_color) {
7460             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7461             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7462             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7463             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7464         }
7465
7466         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7467          * accepts them, the nvidia driver accepts them all. All those differences even though we're
7468          * using software vertex processing. Doh!
7469          */
7470         if(dcl_ubyte) {
7471             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7472             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7473             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7474             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7475             ub_ok = SUCCEEDED(hr);
7476         }
7477
7478         if(dcl_short) {
7479             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7480             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7481             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7482             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7483             s_ok = SUCCEEDED(hr);
7484         }
7485
7486         if(dcl_float) {
7487             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7488             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7489             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7490             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7491             f_ok = SUCCEEDED(hr);
7492         }
7493
7494         hr = IDirect3DDevice9_EndScene(device);
7495         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7496     }
7497
7498     if(dcl_short) {
7499         color = getPixelColor(device, 480, 360);
7500         ok(color == 0x000000ff || !s_ok,
7501            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7502     }
7503     if(dcl_ubyte) {
7504         color = getPixelColor(device, 160, 120);
7505         ok(color == 0x0000ffff || !ub_ok,
7506            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7507     }
7508     if(dcl_color) {
7509         color = getPixelColor(device, 160, 360);
7510         ok(color == 0x00ffff00,
7511            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7512     }
7513     if(dcl_float) {
7514         color = getPixelColor(device, 480, 120);
7515         ok(color == 0x00ff0000 || !f_ok,
7516            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7517     }
7518     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7519
7520     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7521      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7522      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7523      * whether the immediate mode code works
7524      */
7525     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7526     hr = IDirect3DDevice9_BeginScene(device);
7527     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7528     if(SUCCEEDED(hr)) {
7529         if(dcl_color) {
7530             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7531             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7532             memcpy(data, quad1, sizeof(quad1));
7533             hr = IDirect3DVertexBuffer9_Unlock(vb);
7534             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7535             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7536             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7537             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7538             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7539             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7540             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7541         }
7542
7543         if(dcl_ubyte) {
7544             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7545             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7546             memcpy(data, quad2, sizeof(quad2));
7547             hr = IDirect3DVertexBuffer9_Unlock(vb);
7548             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7549             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7550             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7551             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7552             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7553             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7554             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7555                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7556             ub_ok = SUCCEEDED(hr);
7557         }
7558
7559         if(dcl_short) {
7560             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7561             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7562             memcpy(data, quad3, sizeof(quad3));
7563             hr = IDirect3DVertexBuffer9_Unlock(vb);
7564             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7565             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7566             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7567             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7568             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7569             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7570             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7571                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7572             s_ok = SUCCEEDED(hr);
7573         }
7574
7575         if(dcl_float) {
7576             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7577             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7578             memcpy(data, quad4, sizeof(quad4));
7579             hr = IDirect3DVertexBuffer9_Unlock(vb);
7580             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7581             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7582             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7583             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7584             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7585             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7586             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7587                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7588             f_ok = SUCCEEDED(hr);
7589         }
7590
7591         hr = IDirect3DDevice9_EndScene(device);
7592         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7593     }
7594
7595     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7596     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7597     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7598     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7599
7600     if(dcl_short) {
7601         color = getPixelColor(device, 480, 360);
7602         ok(color == 0x000000ff || !s_ok,
7603            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7604     }
7605     if(dcl_ubyte) {
7606         color = getPixelColor(device, 160, 120);
7607         ok(color == 0x0000ffff || !ub_ok,
7608            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7609     }
7610     if(dcl_color) {
7611         color = getPixelColor(device, 160, 360);
7612         ok(color == 0x00ffff00,
7613            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7614     }
7615     if(dcl_float) {
7616         color = getPixelColor(device, 480, 120);
7617         ok(color == 0x00ff0000 || !f_ok,
7618            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7619     }
7620     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7621
7622     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7623     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7624
7625     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7626     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7627     memcpy(data, quad_transformed, sizeof(quad_transformed));
7628     hr = IDirect3DVertexBuffer9_Unlock(vb);
7629     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7630
7631     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7632     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7633
7634     hr = IDirect3DDevice9_BeginScene(device);
7635     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7636     if(SUCCEEDED(hr)) {
7637         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7638         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7639         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7640         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7641
7642         hr = IDirect3DDevice9_EndScene(device);
7643         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7644     }
7645
7646     color = getPixelColor(device, 88, 108);
7647     ok(color == 0x000000ff,
7648        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7649     color = getPixelColor(device, 92, 108);
7650     ok(color == 0x000000ff,
7651        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7652     color = getPixelColor(device, 88, 112);
7653     ok(color == 0x000000ff,
7654        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7655     color = getPixelColor(device, 92, 112);
7656     ok(color == 0x00ffff00,
7657        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7658
7659     color = getPixelColor(device, 568, 108);
7660     ok(color == 0x000000ff,
7661        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7662     color = getPixelColor(device, 572, 108);
7663     ok(color == 0x000000ff,
7664        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7665     color = getPixelColor(device, 568, 112);
7666     ok(color == 0x00ffff00,
7667        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7668     color = getPixelColor(device, 572, 112);
7669     ok(color == 0x000000ff,
7670        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7671
7672     color = getPixelColor(device, 88, 298);
7673     ok(color == 0x000000ff,
7674        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7675     color = getPixelColor(device, 92, 298);
7676     ok(color == 0x00ffff00,
7677        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7678     color = getPixelColor(device, 88, 302);
7679     ok(color == 0x000000ff,
7680        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7681     color = getPixelColor(device, 92, 302);
7682     ok(color == 0x000000ff,
7683        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7684
7685     color = getPixelColor(device, 568, 298);
7686     ok(color == 0x00ffff00,
7687        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7688     color = getPixelColor(device, 572, 298);
7689     ok(color == 0x000000ff,
7690        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7691     color = getPixelColor(device, 568, 302);
7692     ok(color == 0x000000ff,
7693        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7694     color = getPixelColor(device, 572, 302);
7695     ok(color == 0x000000ff,
7696        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7697
7698     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7699
7700     /* This test is pointless without those two declarations: */
7701     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7702         skip("color-ubyte switching test declarations aren't supported\n");
7703         goto out;
7704     }
7705
7706     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7707     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7708     memcpy(data, quads, sizeof(quads));
7709     hr = IDirect3DVertexBuffer9_Unlock(vb);
7710     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7711     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7712                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7713     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7714     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7715     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7716     memcpy(data, colors, sizeof(colors));
7717     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7718     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7719
7720     for(i = 0; i < 2; i++) {
7721         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7722         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7723
7724         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7725         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7726         if(i == 0) {
7727             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7728         } else {
7729             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7730         }
7731         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7732
7733         hr = IDirect3DDevice9_BeginScene(device);
7734         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7735         ub_ok = FALSE;
7736         if(SUCCEEDED(hr)) {
7737             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7738             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7739             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7740             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7741                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7742             ub_ok = SUCCEEDED(hr);
7743
7744             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7745             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7746             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7747             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7748
7749             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7750             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7751             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7752             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7753                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7754             ub_ok = (SUCCEEDED(hr) && ub_ok);
7755
7756             hr = IDirect3DDevice9_EndScene(device);
7757             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7758         }
7759
7760         if(i == 0) {
7761             color = getPixelColor(device, 480, 360);
7762             ok(color == 0x00ff0000,
7763                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7764             color = getPixelColor(device, 160, 120);
7765             ok(color == 0x00ffffff,
7766                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7767             color = getPixelColor(device, 160, 360);
7768             ok(color == 0x000000ff || !ub_ok,
7769                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7770             color = getPixelColor(device, 480, 120);
7771             ok(color == 0x000000ff || !ub_ok,
7772                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7773         } else {
7774             color = getPixelColor(device, 480, 360);
7775             ok(color == 0x000000ff,
7776                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7777             color = getPixelColor(device, 160, 120);
7778             ok(color == 0x00ffffff,
7779                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7780             color = getPixelColor(device, 160, 360);
7781             ok(color == 0x00ff0000 || !ub_ok,
7782                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7783             color = getPixelColor(device, 480, 120);
7784             ok(color == 0x00ff0000 || !ub_ok,
7785                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7786         }
7787         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7788     }
7789
7790     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7791     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7792     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7793     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7794     IDirect3DVertexBuffer9_Release(vb2);
7795
7796     out:
7797     IDirect3DVertexBuffer9_Release(vb);
7798     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7799     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7800     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7801     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7802     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7803     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7804     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7805 }
7806
7807 struct vertex_float16color {
7808     float x, y, z;
7809     DWORD c1, c2;
7810 };
7811
7812 static void test_vshader_float16(IDirect3DDevice9 *device)
7813 {
7814     HRESULT hr;
7815     DWORD color;
7816     void *data;
7817     static const D3DVERTEXELEMENT9 decl_elements[] = {
7818         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7819         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7820         D3DDECL_END()
7821     };
7822     IDirect3DVertexDeclaration9 *vdecl = NULL;
7823     IDirect3DVertexBuffer9 *buffer = NULL;
7824     IDirect3DVertexShader9 *shader;
7825     DWORD shader_code[] = {
7826         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7827         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7828         0x90e40001, 0x0000ffff
7829     };
7830     struct vertex_float16color quad[] = {
7831         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7832         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7833         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7834         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7835
7836         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7837         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7838         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7839         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7840
7841         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7842         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7843         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7844         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7845
7846         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7847         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7848         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7849         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7850     };
7851
7852     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7853     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7854
7855     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7856     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7857     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7858     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7859     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7860     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7861
7862     hr = IDirect3DDevice9_BeginScene(device);
7863     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7864     if(SUCCEEDED(hr)) {
7865         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7866         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7867         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7868         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7869         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7870         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7871         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7872         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7873         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7874         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7875
7876         hr = IDirect3DDevice9_EndScene(device);
7877         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7878     }
7879     color = getPixelColor(device, 480, 360);
7880     ok(color == 0x00ff0000,
7881        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7882     color = getPixelColor(device, 160, 120);
7883     ok(color == 0x00000000,
7884        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7885     color = getPixelColor(device, 160, 360);
7886     ok(color == 0x0000ff00,
7887        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7888     color = getPixelColor(device, 480, 120);
7889     ok(color == 0x000000ff,
7890        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7891     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7892
7893     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7894     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7895
7896     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7897                                              D3DPOOL_MANAGED, &buffer, NULL);
7898     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7899     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7900     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7901     memcpy(data, quad, sizeof(quad));
7902     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7903     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7904     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7905     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7906
7907     hr = IDirect3DDevice9_BeginScene(device);
7908     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7909     if(SUCCEEDED(hr)) {
7910             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7911             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7912             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7913             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7914             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7915             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7916             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7917             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7918
7919             hr = IDirect3DDevice9_EndScene(device);
7920             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7921     }
7922
7923     color = getPixelColor(device, 480, 360);
7924     ok(color == 0x00ff0000,
7925        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7926     color = getPixelColor(device, 160, 120);
7927     ok(color == 0x00000000,
7928        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7929     color = getPixelColor(device, 160, 360);
7930     ok(color == 0x0000ff00,
7931        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7932     color = getPixelColor(device, 480, 120);
7933     ok(color == 0x000000ff,
7934        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7935     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7936
7937     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7938     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7939     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7940     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7941     IDirect3DDevice9_SetVertexShader(device, NULL);
7942     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7943
7944     IDirect3DVertexDeclaration9_Release(vdecl);
7945     IDirect3DVertexShader9_Release(shader);
7946     IDirect3DVertexBuffer9_Release(buffer);
7947 }
7948
7949 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7950 {
7951     D3DCAPS9 caps;
7952     IDirect3DTexture9 *texture;
7953     HRESULT hr;
7954     D3DLOCKED_RECT rect;
7955     unsigned int x, y;
7956     DWORD *dst, color;
7957     const float quad[] = {
7958         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
7959          1.0,   -1.0,   0.1,    1.2,   -0.2,
7960         -1.0,    1.0,   0.1,   -0.2,    1.2,
7961          1.0,    1.0,   0.1,    1.2,    1.2
7962     };
7963     memset(&caps, 0, sizeof(caps));
7964
7965     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7966     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7967     if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7968         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7969         ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7970            "Card has conditional NP2 support without power of two restriction set\n");
7971         skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7972         return;
7973     } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7974         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7975         return;
7976     }
7977
7978     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7979     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7980
7981     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7982     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7983
7984     memset(&rect, 0, sizeof(rect));
7985     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7986     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7987     for(y = 0; y < 10; y++) {
7988         for(x = 0; x < 10; x++) {
7989             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7990             if(x == 0 || x == 9 || y == 0 || y == 9) {
7991                 *dst = 0x00ff0000;
7992             } else {
7993                 *dst = 0x000000ff;
7994             }
7995         }
7996     }
7997     hr = IDirect3DTexture9_UnlockRect(texture, 0);
7998     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7999
8000     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8001     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8002     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
8003     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
8004     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
8005     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
8006     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8007     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
8008
8009     hr = IDirect3DDevice9_BeginScene(device);
8010     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8011     if(SUCCEEDED(hr)) {
8012         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8013         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8014
8015         hr = IDirect3DDevice9_EndScene(device);
8016         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8017     }
8018
8019     color = getPixelColor(device,    1,  1);
8020     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
8021     color = getPixelColor(device, 639, 479);
8022     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
8023
8024     color = getPixelColor(device, 135, 101);
8025     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
8026     color = getPixelColor(device, 140, 101);
8027     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
8028     color = getPixelColor(device, 135, 105);
8029     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
8030     color = getPixelColor(device, 140, 105);
8031     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
8032
8033     color = getPixelColor(device, 135, 376);
8034     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
8035     color = getPixelColor(device, 140, 376);
8036     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
8037     color = getPixelColor(device, 135, 379);
8038     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
8039     color = getPixelColor(device, 140, 379);
8040     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
8041
8042     color = getPixelColor(device, 500, 101);
8043     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
8044     color = getPixelColor(device, 504, 101);
8045     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
8046     color = getPixelColor(device, 500, 105);
8047     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
8048     color = getPixelColor(device, 504, 105);
8049     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
8050
8051     color = getPixelColor(device, 500, 376);
8052     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
8053     color = getPixelColor(device, 504, 376);
8054     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
8055     color = getPixelColor(device, 500, 380);
8056     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
8057     color = getPixelColor(device, 504, 380);
8058     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
8059
8060     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8061
8062     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8063     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8064     IDirect3DTexture9_Release(texture);
8065 }
8066
8067 static void vFace_register_test(IDirect3DDevice9 *device)
8068 {
8069     HRESULT hr;
8070     DWORD color;
8071     const DWORD shader_code[] = {
8072         0xffff0300,                                                             /* ps_3_0                     */
8073         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8074         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
8075         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
8076         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
8077         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
8078         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8079         0x0000ffff                                                              /* END                        */
8080     };
8081     IDirect3DPixelShader9 *shader;
8082     IDirect3DTexture9 *texture;
8083     IDirect3DSurface9 *surface, *backbuffer;
8084     const float quad[] = {
8085         -1.0,   -1.0,   0.1,
8086          1.0,   -1.0,   0.1,
8087         -1.0,    0.0,   0.1,
8088
8089          1.0,   -1.0,   0.1,
8090          1.0,    0.0,   0.1,
8091         -1.0,    0.0,   0.1,
8092
8093         -1.0,    0.0,   0.1,
8094         -1.0,    1.0,   0.1,
8095          1.0,    0.0,   0.1,
8096
8097          1.0,    0.0,   0.1,
8098         -1.0,    1.0,   0.1,
8099          1.0,    1.0,   0.1,
8100     };
8101     const float blit[] = {
8102          0.0,   -1.0,   0.1,    0.0,    0.0,
8103          1.0,   -1.0,   0.1,    1.0,    0.0,
8104          0.0,    1.0,   0.1,    0.0,    1.0,
8105          1.0,    1.0,   0.1,    1.0,    1.0,
8106     };
8107
8108     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8109     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8110     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
8111     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8112     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8113     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
8114     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8115     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8116     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8117     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8118     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8119     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8120
8121     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8122     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8123
8124     hr = IDirect3DDevice9_BeginScene(device);
8125     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8126     if(SUCCEEDED(hr)) {
8127         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
8128         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8129         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8130         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8131         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8132         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8133         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8134         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8135         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8136         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8137         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8138
8139         /* Blit the texture onto the back buffer to make it visible */
8140         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8141         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8142         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8143         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8144         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8145         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8146         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8147         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8148         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8149         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8150
8151         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
8152         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8153
8154         hr = IDirect3DDevice9_EndScene(device);
8155         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8156     }
8157
8158     color = getPixelColor(device, 160, 360);
8159     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8160     color = getPixelColor(device, 160, 120);
8161     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8162     color = getPixelColor(device, 480, 360);
8163     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8164     color = getPixelColor(device, 480, 120);
8165     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8166     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8167
8168     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8169     IDirect3DDevice9_SetTexture(device, 0, NULL);
8170     IDirect3DPixelShader9_Release(shader);
8171     IDirect3DSurface9_Release(surface);
8172     IDirect3DSurface9_Release(backbuffer);
8173     IDirect3DTexture9_Release(texture);
8174 }
8175
8176 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
8177 {
8178     HRESULT hr;
8179     DWORD color;
8180     int i;
8181     D3DCAPS9 caps;
8182     BOOL L6V5U5_supported = FALSE;
8183     IDirect3DTexture9 *tex1, *tex2;
8184     D3DLOCKED_RECT locked_rect;
8185
8186     static const float quad[][7] = {
8187         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
8188         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
8189         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
8190         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
8191     };
8192
8193     static const D3DVERTEXELEMENT9 decl_elements[] = {
8194         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8195         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8196         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
8197         D3DDECL_END()
8198     };
8199
8200     /* use asymmetric matrix to test loading */
8201     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
8202     float scale, offset;
8203
8204     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
8205     IDirect3DTexture9           *texture            = NULL;
8206
8207     memset(&caps, 0, sizeof(caps));
8208     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8209     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8210     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
8211         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
8212         return;
8213     } else {
8214         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
8215          * They report that it is not supported, but after that bump mapping works properly. So just test
8216          * if the format is generally supported, and check the BUMPENVMAP flag
8217          */
8218         IDirect3D9 *d3d9;
8219
8220         IDirect3DDevice9_GetDirect3D(device, &d3d9);
8221         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8222                                           D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
8223         L6V5U5_supported = SUCCEEDED(hr);
8224         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8225                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
8226         IDirect3D9_Release(d3d9);
8227         if(FAILED(hr)) {
8228             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
8229             return;
8230         }
8231     }
8232
8233     /* Generate the textures */
8234     generate_bumpmap_textures(device);
8235
8236     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
8237     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8238     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
8239     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8240     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
8241     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8242     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
8243     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8244
8245     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
8246     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8247     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
8248     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8249     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
8250     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8251
8252     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8253     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8254     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8255     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8256     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8257     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8258
8259     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8260     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8261
8262     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8263     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
8264
8265     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
8266     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
8267
8268
8269     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
8270     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
8271     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
8272     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
8273
8274     hr = IDirect3DDevice9_BeginScene(device);
8275     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8276
8277     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8278     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8279
8280     hr = IDirect3DDevice9_EndScene(device);
8281     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8282
8283     /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
8284      * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
8285      * But since testing the color match is not the purpose of the test don't be too picky
8286      */
8287     color = getPixelColor(device, 320-32, 240);
8288     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8289     color = getPixelColor(device, 320+32, 240);
8290     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8291     color = getPixelColor(device, 320, 240-32);
8292     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8293     color = getPixelColor(device, 320, 240+32);
8294     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8295     color = getPixelColor(device, 320, 240);
8296     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8297     color = getPixelColor(device, 320+32, 240+32);
8298     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8299     color = getPixelColor(device, 320-32, 240+32);
8300     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8301     color = getPixelColor(device, 320+32, 240-32);
8302     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8303     color = getPixelColor(device, 320-32, 240-32);
8304     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8305     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8306     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8307
8308     for(i = 0; i < 2; i++) {
8309         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
8310         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
8311         IDirect3DTexture9_Release(texture); /* For the GetTexture */
8312         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
8313         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
8314         IDirect3DTexture9_Release(texture); /* To destroy it */
8315     }
8316
8317     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
8318         skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
8319         goto cleanup;
8320     }
8321     if(L6V5U5_supported == FALSE) {
8322         skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
8323         goto cleanup;
8324     }
8325
8326     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
8327     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8328     /* This test only tests the luminance part. The bumpmapping part was already tested above and
8329      * would only make this test more complicated
8330      */
8331     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
8332     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8333     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8334     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8335
8336     memset(&locked_rect, 0, sizeof(locked_rect));
8337     hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
8338     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8339     *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
8340     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8341     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8342
8343     memset(&locked_rect, 0, sizeof(locked_rect));
8344     hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
8345     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8346     *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
8347     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8348     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8349
8350     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8351     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8352     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8353     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8354
8355     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
8356     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8357     scale = 2.0;
8358     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8359     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8360     offset = 0.1;
8361     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8362     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8363
8364     hr = IDirect3DDevice9_BeginScene(device);
8365     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8366     if(SUCCEEDED(hr)) {
8367         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8368         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8369         hr = IDirect3DDevice9_EndScene(device);
8370         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8371     }
8372
8373     color = getPixelColor(device, 320, 240);
8374     /* red:   1.0  * (0.25 * 2.0 + 0.1) = 1.0  * 0.6 = 0.6  = 0x99
8375      * green: 0.5  * (0.25 * 2.0 + 0.1) = 0.5  * 0.6 = 0.3  = 0x4c
8376      * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
8377      */
8378     ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
8379     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8380     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8381
8382     /* Check a result scale factor > 1.0 */
8383     scale = 10;
8384     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8385     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8386     offset = 10;
8387     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8388     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8389
8390     hr = IDirect3DDevice9_BeginScene(device);
8391     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8392     if(SUCCEEDED(hr)) {
8393         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8394         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8395         hr = IDirect3DDevice9_EndScene(device);
8396         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8397     }
8398     color = getPixelColor(device, 320, 240);
8399     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8400     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8401     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8402
8403     /* Check clamping in the scale factor calculation */
8404     scale = 1000;
8405     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8406     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8407     offset = -1;
8408     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8409     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8410
8411     hr = IDirect3DDevice9_BeginScene(device);
8412     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8413     if(SUCCEEDED(hr)) {
8414         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8415         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8416         hr = IDirect3DDevice9_EndScene(device);
8417         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8418     }
8419     color = getPixelColor(device, 320, 240);
8420     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8421     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8422     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8423
8424     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8425     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8426     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8427     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8428
8429     IDirect3DTexture9_Release(tex1);
8430     IDirect3DTexture9_Release(tex2);
8431
8432 cleanup:
8433     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8434     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8435     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8436     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8437
8438     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8439     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8440     IDirect3DVertexDeclaration9_Release(vertex_declaration);
8441 }
8442
8443 static void stencil_cull_test(IDirect3DDevice9 *device) {
8444     HRESULT hr;
8445     IDirect3DSurface9 *depthstencil = NULL;
8446     D3DSURFACE_DESC desc;
8447     float quad1[] = {
8448         -1.0,   -1.0,   0.1,
8449          0.0,   -1.0,   0.1,
8450         -1.0,    0.0,   0.1,
8451          0.0,    0.0,   0.1,
8452     };
8453     float quad2[] = {
8454          0.0,   -1.0,   0.1,
8455          1.0,   -1.0,   0.1,
8456          0.0,    0.0,   0.1,
8457          1.0,    0.0,   0.1,
8458     };
8459     float quad3[] = {
8460         0.0,    0.0,   0.1,
8461         1.0,    0.0,   0.1,
8462         0.0,    1.0,   0.1,
8463         1.0,    1.0,   0.1,
8464     };
8465     float quad4[] = {
8466         -1.0,    0.0,   0.1,
8467          0.0,    0.0,   0.1,
8468         -1.0,    1.0,   0.1,
8469          0.0,    1.0,   0.1,
8470     };
8471     struct vertex painter[] = {
8472        {-1.0,   -1.0,   0.0,    0x00000000},
8473        { 1.0,   -1.0,   0.0,    0x00000000},
8474        {-1.0,    1.0,   0.0,    0x00000000},
8475        { 1.0,    1.0,   0.0,    0x00000000},
8476     };
8477     WORD indices_cw[]  = {0, 1, 3};
8478     WORD indices_ccw[] = {0, 2, 3};
8479     unsigned int i;
8480     DWORD color;
8481
8482     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8483     if(depthstencil == NULL) {
8484         skip("No depth stencil buffer\n");
8485         return;
8486     }
8487     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8488     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8489     IDirect3DSurface9_Release(depthstencil);
8490     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8491         skip("No 4 or 8 bit stencil surface\n");
8492         return;
8493     }
8494
8495     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8496     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8497     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8498
8499     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8500     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8501     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8502     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8503     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8504     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8505     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8506     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8507
8508     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8509     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8510     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8511     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8512     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8513     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8514
8515     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8516     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8517     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8518     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8519
8520     /* First pass: Fill the stencil buffer with some values... */
8521     hr = IDirect3DDevice9_BeginScene(device);
8522     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8523     if(SUCCEEDED(hr))
8524     {
8525         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8526         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8527         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8528                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8529         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8530         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8531                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8532         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8533
8534         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8535         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8536         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8537         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8538         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8539                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8540         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8541         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8542                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8543         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8544
8545         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8546         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8547         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8548                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8549         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8550         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8551                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8552         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8553
8554         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8555         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8556         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8557                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8558         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8559         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8560                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8561         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8562
8563         hr = IDirect3DDevice9_EndScene(device);
8564         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8565     }
8566
8567     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8568     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8569     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8570     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8571     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8572     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8573     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8574     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8575     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8576     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8577     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8578     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8579     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8580
8581     /* 2nd pass: Make the stencil values visible */
8582     hr = IDirect3DDevice9_BeginScene(device);
8583     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8584     if(SUCCEEDED(hr))
8585     {
8586         IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8587         for(i = 0; i < 16; i++) {
8588             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8589             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8590
8591             painter[0].diffuse = (i * 16); /* Creates shades of blue */
8592             painter[1].diffuse = (i * 16);
8593             painter[2].diffuse = (i * 16);
8594             painter[3].diffuse = (i * 16);
8595             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8596             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8597         }
8598         hr = IDirect3DDevice9_EndScene(device);
8599         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8600     }
8601
8602     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8603     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8604
8605     color = getPixelColor(device, 160, 420);
8606     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8607     color = getPixelColor(device, 160, 300);
8608     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8609
8610     color = getPixelColor(device, 480, 420);
8611     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8612     color = getPixelColor(device, 480, 300);
8613     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8614
8615     color = getPixelColor(device, 160, 180);
8616     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8617     color = getPixelColor(device, 160, 60);
8618     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8619
8620     color = getPixelColor(device, 480, 180);
8621     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8622     color = getPixelColor(device, 480, 60);
8623     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8624
8625     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8626     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8627 }
8628
8629 static void vpos_register_test(IDirect3DDevice9 *device)
8630 {
8631     HRESULT hr;
8632     DWORD color;
8633     const DWORD shader_code[] = {
8634     0xffff0300,                                                             /* ps_3_0                     */
8635     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8636     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8637     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8638     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8639     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8640     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8641     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8642     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8643     0x0000ffff                                                              /* end                        */
8644     };
8645     const DWORD shader_frac_code[] = {
8646     0xffff0300,                                                             /* ps_3_0                     */
8647     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8648     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8649     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8650     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8651     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8652     0x0000ffff                                                              /* end                        */
8653     };
8654     IDirect3DPixelShader9 *shader, *shader_frac;
8655     IDirect3DSurface9 *surface = NULL, *backbuffer;
8656     const float quad[] = {
8657         -1.0,   -1.0,   0.1,    0.0,    0.0,
8658          1.0,   -1.0,   0.1,    1.0,    0.0,
8659         -1.0,    1.0,   0.1,    0.0,    1.0,
8660          1.0,    1.0,   0.1,    1.0,    1.0,
8661     };
8662     D3DLOCKED_RECT lr;
8663     float constant[4] = {1.0, 0.0, 320, 240};
8664     DWORD *pos;
8665
8666     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8667     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8668     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8669     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8670     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8671     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8672     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8673     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8674     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8675     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8676     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8677     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8678
8679     hr = IDirect3DDevice9_BeginScene(device);
8680     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8681     if(SUCCEEDED(hr)) {
8682         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8683         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8684         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8685         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8686         hr = IDirect3DDevice9_EndScene(device);
8687         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8688     }
8689
8690     /* This has to be pixel exact */
8691     color = getPixelColor(device, 319, 239);
8692     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8693     color = getPixelColor(device, 320, 239);
8694     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8695     color = getPixelColor(device, 319, 240);
8696     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8697     color = getPixelColor(device, 320, 240);
8698     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8699     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8700
8701     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8702                                              &surface, NULL);
8703     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8704     hr = IDirect3DDevice9_BeginScene(device);
8705     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8706     if(SUCCEEDED(hr)) {
8707         constant[2] = 16; constant[3] = 16;
8708         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8709         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8710         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8711         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8712         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8713         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8714         hr = IDirect3DDevice9_EndScene(device);
8715         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8716     }
8717     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8718     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8719
8720     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8721     color = *pos & 0x00ffffff;
8722     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8723     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8724     color = *pos & 0x00ffffff;
8725     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8726     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8727     color = *pos & 0x00ffffff;
8728     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8729     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8730     color = *pos & 0x00ffffff;
8731     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8732
8733     hr = IDirect3DSurface9_UnlockRect(surface);
8734     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8735
8736     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8737      * have full control over the multisampling setting inside this test
8738      */
8739     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8740     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8741     hr = IDirect3DDevice9_BeginScene(device);
8742     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8743     if(SUCCEEDED(hr)) {
8744         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8745         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8746         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8747         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8748         hr = IDirect3DDevice9_EndScene(device);
8749         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8750     }
8751     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8752     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8753
8754     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8755     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8756
8757     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8758     color = *pos & 0x00ffffff;
8759     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8760
8761     hr = IDirect3DSurface9_UnlockRect(surface);
8762     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8763
8764     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8765     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8766     IDirect3DPixelShader9_Release(shader);
8767     IDirect3DPixelShader9_Release(shader_frac);
8768     if(surface) IDirect3DSurface9_Release(surface);
8769     IDirect3DSurface9_Release(backbuffer);
8770 }
8771
8772 static void pointsize_test(IDirect3DDevice9 *device)
8773 {
8774     HRESULT hr;
8775     D3DCAPS9 caps;
8776     D3DMATRIX matrix;
8777     D3DMATRIX identity;
8778     float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8779     DWORD color;
8780     IDirect3DTexture9 *tex1, *tex2;
8781     D3DLOCKED_RECT lr;
8782     const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8783                                 0x00000000, 0x00000000};
8784     const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8785                                 0x00000000, 0x0000ff00};
8786
8787     const float vertices[] = {
8788         64,     64,     0.1,
8789         128,    64,     0.1,
8790         192,    64,     0.1,
8791         256,    64,     0.1,
8792         320,    64,     0.1,
8793         384,    64,     0.1,
8794         448,    64,     0.1,
8795         512,    64,     0.1,
8796         576,    64,     0.1,
8797     };
8798
8799     /* 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 */
8800     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;
8801     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;
8802     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;
8803     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;
8804
8805     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;
8806     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;
8807     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;
8808     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;
8809
8810     memset(&caps, 0, sizeof(caps));
8811     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8812     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8813     if(caps.MaxPointSize < 32.0) {
8814         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8815         return;
8816     }
8817
8818     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8819     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8820     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8821     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8822     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8823     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8824     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8825     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8826
8827     hr = IDirect3DDevice9_BeginScene(device);
8828     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8829     if(SUCCEEDED(hr)) {
8830         ptsize = 16.0;
8831         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8832         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8833         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8834         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8835
8836         ptsize = 32.0;
8837         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8838         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8839         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8840         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8841
8842         ptsize = 31.5;
8843         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8844         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8845         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8846         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8847
8848         if(caps.MaxPointSize >= 64.0) {
8849             ptsize = 64.0;
8850             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8851             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8852             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8853             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8854
8855             ptsize = 63.75;
8856             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8857             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8858             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8859             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8860         }
8861
8862         ptsize = 1.0;
8863         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8864         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8865         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8866         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8867
8868         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8869         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8870         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8871         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8872
8873         /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8874         ptsize = 16.0;
8875         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8876         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8877         ptsize = 1.0;
8878         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8879         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8880         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8881         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8882
8883         /* What happens if POINTSIZE_MAX < POINTSIZE_MIN?
8884          * ptsize = 4.0, ptsize_max = 1.0, ptsize_min = 16.0
8885          */
8886         ptsize = 4.0;
8887         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8888         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8889         ptsize = 16.0;
8890         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8891         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8892         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8893         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8894
8895         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8896         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8897
8898         /* pointsize < pointsize_min < pointsize_max?
8899          * pointsize = 1.0, pointsize_min = 16.0, pointsize_max = default(usually 64.0)
8900          */
8901         ptsize = 1.0;
8902         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8903         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8904         ptsize = 16.0;
8905         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8906         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8907         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[24], sizeof(float) * 3);
8908         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8909
8910         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8911         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8912
8913         hr = IDirect3DDevice9_EndScene(device);
8914         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8915     }
8916     color = getPixelColor(device, 64-9, 64-9);
8917     ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
8918     color = getPixelColor(device, 64-8, 64-8);
8919     ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
8920     color = getPixelColor(device, 64-7, 64-7);
8921     ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
8922     color = getPixelColor(device, 64+7, 64+7);
8923     ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
8924     color = getPixelColor(device, 64+8, 64+8);
8925     ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
8926     color = getPixelColor(device, 64+9, 64+9);
8927     ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
8928
8929     color = getPixelColor(device, 128-17, 64-17);
8930     ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8931     color = getPixelColor(device, 128-16, 64-16);
8932     ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
8933     color = getPixelColor(device, 128-15, 64-15);
8934     ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8935     color = getPixelColor(device, 128+15, 64+15);
8936     ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8937     color = getPixelColor(device, 128+16, 64+16);
8938     ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8939     color = getPixelColor(device, 128+17, 64+17);
8940     ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8941
8942     color = getPixelColor(device, 192-17, 64-17);
8943     ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8944     color = getPixelColor(device, 192-16, 64-16);
8945     todo_wine ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
8946     color = getPixelColor(device, 192-15, 64-15);
8947     ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8948     color = getPixelColor(device, 192+15, 64+15);
8949     ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8950     color = getPixelColor(device, 192+16, 64+16);
8951     ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8952     color = getPixelColor(device, 192+17, 64+17);
8953     ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8954
8955     if(caps.MaxPointSize >= 64.0) {
8956         color = getPixelColor(device, 256-33, 64-33);
8957         ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8958         color = getPixelColor(device, 256-32, 64-32);
8959         todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
8960         color = getPixelColor(device, 256-31, 64-31);
8961         ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8962         color = getPixelColor(device, 256+31, 64+31);
8963         ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8964         color = getPixelColor(device, 256+32, 64+32);
8965         ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8966         color = getPixelColor(device, 256+33, 64+33);
8967         ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8968
8969         color = getPixelColor(device, 384-33, 64-33);
8970         ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8971         color = getPixelColor(device, 384-32, 64-32);
8972         ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
8973         color = getPixelColor(device, 384-31, 64-31);
8974         ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8975         color = getPixelColor(device, 384+31, 64+31);
8976         ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8977         color = getPixelColor(device, 384+32, 64+32);
8978         ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8979         color = getPixelColor(device, 384+33, 64+33);
8980         ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8981     }
8982
8983     color = getPixelColor(device, 320-1, 64-1);
8984     ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
8985     color = getPixelColor(device, 320-0, 64-0);
8986     ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
8987     color = getPixelColor(device, 320+1, 64+1);
8988     ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
8989
8990     /* ptsize = 16, ptsize_max = 1 --> point has size 1 */
8991     color = getPixelColor(device, 448-4, 64-4);
8992     ok(color == 0x000000ff, "pSize: Pixel (448-4),(64-4) has color 0x%08x, expected 0x000000ff\n", color);
8993     color = getPixelColor(device, 448+4, 64+4);
8994     ok(color == 0x000000ff, "pSize: Pixel (448+4),(64+4) has color 0x%08x, expected 0x000000ff\n", color);
8995
8996     /* ptsize = 4, ptsize_max = 1, ptsize_min = 16 --> point has size 1 */
8997     color = getPixelColor(device, 512-4, 64-4);
8998     ok(color == 0x000000ff, "pSize: Pixel (512-4),(64-4) has color 0x%08x, expected 0x000000ff\n", color);
8999     color = getPixelColor(device, 512+4, 64+4);
9000     ok(color == 0x000000ff, "pSize: Pixel (512+4),(64+4) has color 0x%08x, expected 0x000000ff\n", color);
9001
9002     /* ptsize = 1, ptsize_max = default(64), ptsize_min = 16 --> point has size 16
9003      * Don't be overly picky - just show that the point is bigger than 1 pixel
9004      */
9005     color = getPixelColor(device, 576-4, 64-4);
9006     ok(color == 0x00ffffff, "pSize: Pixel (576-4),(64-4) has color 0x%08x, expected 0x00ffffff\n", color);
9007     color = getPixelColor(device, 576+4, 64+4);
9008     ok(color == 0x00ffffff, "pSize: Pixel (576+4),(64+4) has color 0x%08x, expected 0x00ffffff\n", color);
9009
9010     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9011
9012     /* The following code tests point sprites with two textures, to see if each texture coordinate unit
9013      * generates texture coordinates for the point(result: Yes, it does)
9014      *
9015      * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
9016      * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
9017      * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
9018      */
9019     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
9020     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9021
9022     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
9023     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9024     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
9025     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9026     memset(&lr, 0, sizeof(lr));
9027     hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
9028     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9029     memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
9030     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
9031     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9032     memset(&lr, 0, sizeof(lr));
9033     hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
9034     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9035     memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
9036     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
9037     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9038     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9039     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9040     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
9041     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9042     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9043     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9044     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9045     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9046     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9047     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9048     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9049     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9050     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
9051     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9052
9053     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
9054     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9055     ptsize = 32.0;
9056     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9057     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9058
9059     hr = IDirect3DDevice9_BeginScene(device);
9060     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
9061     if(SUCCEEDED(hr))
9062     {
9063         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9064         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9065         hr = IDirect3DDevice9_EndScene(device);
9066         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9067     }
9068
9069     color = getPixelColor(device, 64-4, 64-4);
9070     ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
9071     color = getPixelColor(device, 64-4, 64+4);
9072     ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
9073     color = getPixelColor(device, 64+4, 64+4);
9074     ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
9075     color = getPixelColor(device, 64+4, 64-4);
9076     ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
9077     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9078
9079     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9080     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9081     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9082     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9083     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9084     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9085     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
9086     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9087     IDirect3DTexture9_Release(tex1);
9088     IDirect3DTexture9_Release(tex2);
9089
9090     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
9091     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9092     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
9093     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9094     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
9095     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
9096 }
9097
9098 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
9099 {
9100     HRESULT hr;
9101     IDirect3DPixelShader9 *ps;
9102     IDirect3DTexture9 *tex1, *tex2;
9103     IDirect3DSurface9 *surf1, *surf2, *backbuf;
9104     D3DCAPS9 caps;
9105     DWORD color;
9106     DWORD shader_code[] = {
9107     0xffff0300,                                                             /* ps_3_0             */
9108     0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
9109     0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
9110     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0        */
9111     0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1        */
9112     0x0000ffff                                                              /* END                */
9113     };
9114     float quad[] = {
9115        -1.0,   -1.0,    0.1,
9116         1.0,   -1.0,    0.1,
9117        -1.0,    1.0,    0.1,
9118         1.0,    1.0,    0.1,
9119     };
9120     float texquad[] = {
9121        -1.0,   -1.0,    0.1,    0.0,    0.0,
9122         0.0,   -1.0,    0.1,    1.0,    0.0,
9123        -1.0,    1.0,    0.1,    0.0,    1.0,
9124         0.0,    1.0,    0.1,    1.0,    1.0,
9125
9126         0.0,   -1.0,    0.1,    0.0,    0.0,
9127         1.0,   -1.0,    0.1,    1.0,    0.0,
9128         0.0,    1.0,    0.1,    0.0,    1.0,
9129         1.0,    1.0,    0.1,    1.0,    1.0,
9130     };
9131
9132     memset(&caps, 0, sizeof(caps));
9133     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9134     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
9135     if(caps.NumSimultaneousRTs < 2) {
9136         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
9137         return;
9138     }
9139
9140     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
9141     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9142
9143     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
9144     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9145     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
9146     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9147     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
9148     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
9149
9150     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
9151     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
9152     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
9153     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9154     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
9155     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9156
9157     hr = IDirect3DDevice9_SetPixelShader(device, ps);
9158     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
9159     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
9160     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9161     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
9162     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9163     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9164     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9165
9166     hr = IDirect3DDevice9_BeginScene(device);
9167     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
9168     if(SUCCEEDED(hr)) {
9169         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
9170         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9171
9172         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9173         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
9174         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
9175         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9176         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
9177         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9178         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9179         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9180
9181         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9182         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9183         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
9184         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9185
9186         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
9187         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9188         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
9189         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9190
9191         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9192         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9193
9194         hr = IDirect3DDevice9_EndScene(device);
9195         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9196     }
9197
9198     color = getPixelColor(device, 160, 240);
9199     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
9200     color = getPixelColor(device, 480, 240);
9201     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
9202     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9203
9204     IDirect3DPixelShader9_Release(ps);
9205     IDirect3DTexture9_Release(tex1);
9206     IDirect3DTexture9_Release(tex2);
9207     IDirect3DSurface9_Release(surf1);
9208     IDirect3DSurface9_Release(surf2);
9209     IDirect3DSurface9_Release(backbuf);
9210 }
9211
9212 struct formats {
9213     const char *fmtName;
9214     D3DFORMAT textureFormat;
9215     DWORD resultColorBlending;
9216     DWORD resultColorNoBlending;
9217 };
9218
9219 const struct formats test_formats[] = {
9220   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
9221   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
9222   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
9223   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
9224   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
9225   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
9226   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
9227   { NULL, 0 }
9228 };
9229
9230 static void pixelshader_blending_test(IDirect3DDevice9 *device)
9231 {
9232     HRESULT hr;
9233     IDirect3DTexture9 *offscreenTexture = NULL;
9234     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
9235     IDirect3D9 *d3d = NULL;
9236     DWORD color;
9237     DWORD r0, g0, b0, r1, g1, b1;
9238     int fmt_index;
9239
9240     static const float quad[][5] = {
9241         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
9242         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
9243         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
9244         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
9245     };
9246
9247     /* Quad with R=0x10, G=0x20 */
9248     static const struct vertex quad1[] = {
9249         {-1.0f, -1.0f, 0.1f, 0x80102000},
9250         {-1.0f,  1.0f, 0.1f, 0x80102000},
9251         { 1.0f, -1.0f, 0.1f, 0x80102000},
9252         { 1.0f,  1.0f, 0.1f, 0x80102000},
9253     };
9254
9255     /* Quad with R=0x20, G=0x10 */
9256     static const struct vertex quad2[] = {
9257         {-1.0f, -1.0f, 0.1f, 0x80201000},
9258         {-1.0f,  1.0f, 0.1f, 0x80201000},
9259         { 1.0f, -1.0f, 0.1f, 0x80201000},
9260         { 1.0f,  1.0f, 0.1f, 0x80201000},
9261     };
9262
9263     IDirect3DDevice9_GetDirect3D(device, &d3d);
9264
9265     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9266     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
9267     if(!backbuffer) {
9268         goto out;
9269     }
9270
9271     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
9272     {
9273         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
9274         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
9275            skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
9276            continue;
9277         }
9278
9279         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9280         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9281
9282         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
9283         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
9284         if(!offscreenTexture) {
9285             continue;
9286         }
9287
9288         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
9289         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
9290         if(!offscreen) {
9291             continue;
9292         }
9293
9294         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9295         ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9296
9297         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9298         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9299         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9300         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9301         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
9302         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
9303         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
9304         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
9305         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9306         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9307
9308         /* Below we will draw two quads with different colors and try to blend them together.
9309          * The result color is compared with the expected outcome.
9310          */
9311         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
9312             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
9313             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9314             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
9315             ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9316
9317             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9318             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9319
9320             /* Draw a quad using color 0x0010200 */
9321             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
9322             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9323             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
9324             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9325             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9326             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9327
9328             /* Draw a quad using color 0x0020100 */
9329             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9330             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9331             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
9332             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9333             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9334             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9335
9336             /* We don't want to blend the result on the backbuffer */
9337             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9338             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9339
9340             /* Prepare rendering the 'blended' texture quad to the backbuffer */
9341             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9342             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9343             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
9344             ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
9345
9346             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9347             ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9348
9349             /* This time with the texture */
9350             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9351             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
9352
9353             IDirect3DDevice9_EndScene(device);
9354         }
9355
9356         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
9357             /* Compare the color of the center quad with our expectation */
9358             color = getPixelColor(device, 320, 240);
9359             r0 = (color & 0x00ff0000) >> 16;
9360             g0 = (color & 0x0000ff00) >>  8;
9361             b0 = (color & 0x000000ff) >>  0;
9362
9363             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
9364             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
9365             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
9366
9367             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9368                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9369                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9370                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9371         } else {
9372             /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9373              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9374              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9375             color = getPixelColor(device, 320, 240);
9376             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);
9377         }
9378         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9379
9380         IDirect3DDevice9_SetTexture(device, 0, NULL);
9381         if(offscreenTexture) {
9382             IDirect3DTexture9_Release(offscreenTexture);
9383         }
9384         if(offscreen) {
9385             IDirect3DSurface9_Release(offscreen);
9386         }
9387     }
9388
9389 out:
9390     /* restore things */
9391     if(backbuffer) {
9392         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9393         IDirect3DSurface9_Release(backbuffer);
9394     }
9395 }
9396
9397 static void tssargtemp_test(IDirect3DDevice9 *device)
9398 {
9399     HRESULT hr;
9400     DWORD color;
9401     static const struct vertex quad[] = {
9402         {-1.0,     -1.0,    0.1,    0x00ff0000},
9403         { 1.0,     -1.0,    0.1,    0x00ff0000},
9404         {-1.0,      1.0,    0.1,    0x00ff0000},
9405         { 1.0,      1.0,    0.1,    0x00ff0000}
9406     };
9407     D3DCAPS9 caps;
9408
9409     memset(&caps, 0, sizeof(caps));
9410     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9411     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9412     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9413         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9414         return;
9415     }
9416
9417     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9418     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9419
9420     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9421     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9422     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9423     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9424
9425     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9426     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9427     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9428     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9429     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9430     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9431
9432     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9433     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9434     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9435     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9436     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9437     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9438
9439     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9440     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9441
9442     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9443     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9444     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9445     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9446
9447     hr = IDirect3DDevice9_BeginScene(device);
9448     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9449     if(SUCCEEDED(hr)) {
9450         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9451         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9452         hr = IDirect3DDevice9_EndScene(device);
9453         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9454     }
9455     color = getPixelColor(device, 320, 240);
9456     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9457     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9458
9459     /* Set stage 1 back to default */
9460     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9461     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9462     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9463     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9464     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9465     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9466     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9467     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9468     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9469     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9470 }
9471
9472 struct testdata
9473 {
9474     DWORD idxVertex; /* number of instances in the first stream */
9475     DWORD idxColor; /* number of instances in the second stream */
9476     DWORD idxInstance; /* should be 1 ?? */
9477     DWORD color1; /* color 1 instance */
9478     DWORD color2; /* color 2 instance */
9479     DWORD color3; /* color 3 instance */
9480     DWORD color4; /* color 4 instance */
9481     WORD strVertex; /* specify which stream to use 0-2*/
9482     WORD strColor;
9483     WORD strInstance;
9484 };
9485
9486 static const struct testdata testcases[]=
9487 {
9488     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
9489     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
9490     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
9491     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
9492     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  4 */
9493     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
9494     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
9495     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
9496     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  8 */
9497     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  9 */
9498     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
9499     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
9500     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
9501     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
9502     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
9503 /*
9504     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
9505     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9506 */
9507 };
9508
9509 /* Drawing Indexed Geometry with instances*/
9510 static void stream_test(IDirect3DDevice9 *device)
9511 {
9512     IDirect3DVertexBuffer9 *vb = NULL;
9513     IDirect3DVertexBuffer9 *vb2 = NULL;
9514     IDirect3DVertexBuffer9 *vb3 = NULL;
9515     IDirect3DIndexBuffer9 *ib = NULL;
9516     IDirect3DVertexDeclaration9 *pDecl = NULL;
9517     IDirect3DVertexShader9 *shader = NULL;
9518     HRESULT hr;
9519     BYTE *data;
9520     DWORD color;
9521     DWORD ind;
9522     unsigned i;
9523
9524     const DWORD shader_code[] =
9525     {
9526         0xfffe0101,                                     /* vs_1_1 */
9527         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
9528         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
9529         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
9530         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
9531         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9532         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
9533         0x0000ffff
9534     };
9535
9536     const float quad[][3] =
9537     {
9538         {-0.5f, -0.5f,  1.1f}, /*0 */
9539         {-0.5f,  0.5f,  1.1f}, /*1 */
9540         { 0.5f, -0.5f,  1.1f}, /*2 */
9541         { 0.5f,  0.5f,  1.1f}, /*3 */
9542     };
9543
9544     const float vertcolor[][4] =
9545     {
9546         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9547         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9548         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9549         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9550     };
9551
9552     /* 4 position for 4 instances */
9553     const float instancepos[][3] =
9554     {
9555         {-0.6f,-0.6f, 0.0f},
9556         { 0.6f,-0.6f, 0.0f},
9557         { 0.6f, 0.6f, 0.0f},
9558         {-0.6f, 0.6f, 0.0f},
9559     };
9560
9561     short indices[] = {0, 1, 2, 1, 2, 3};
9562
9563     D3DVERTEXELEMENT9 decl[] =
9564     {
9565         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9566         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9567         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9568         D3DDECL_END()
9569     };
9570
9571     /* set the default value because it isn't done in wine? */
9572     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9573     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9574
9575     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9576     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9577     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9578
9579     /* check wrong cases */
9580     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9581     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9582     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9583     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9584     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9585     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9586     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9587     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9588     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9589     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9590     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9591     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9592     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9593     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9594     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9595     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9596     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9597     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9598     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9599     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9600
9601     /* set the default value back */
9602     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9603     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9604
9605     /* create all VertexBuffers*/
9606     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9607     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9608     if(!vb) {
9609         skip("Failed to create a vertex buffer\n");
9610         return;
9611     }
9612     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9613     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9614     if(!vb2) {
9615         skip("Failed to create a vertex buffer\n");
9616         goto out;
9617     }
9618     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9619     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9620     if(!vb3) {
9621         skip("Failed to create a vertex buffer\n");
9622         goto out;
9623     }
9624
9625     /* create IndexBuffer*/
9626     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9627     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9628     if(!ib) {
9629         skip("Failed to create a index buffer\n");
9630         goto out;
9631     }
9632
9633     /* copy all Buffers (Vertex + Index)*/
9634     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9635     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9636     memcpy(data, quad, sizeof(quad));
9637     hr = IDirect3DVertexBuffer9_Unlock(vb);
9638     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9639     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9640     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9641     memcpy(data, vertcolor, sizeof(vertcolor));
9642     hr = IDirect3DVertexBuffer9_Unlock(vb2);
9643     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9644     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9645     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9646     memcpy(data, instancepos, sizeof(instancepos));
9647     hr = IDirect3DVertexBuffer9_Unlock(vb3);
9648     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9649     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9650     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9651     memcpy(data, indices, sizeof(indices));
9652     hr = IDirect3DIndexBuffer9_Unlock(ib);
9653     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9654
9655     /* create VertexShader */
9656     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9657     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9658     if(!shader) {
9659         skip("Failed to create a vetex shader\n");
9660         goto out;
9661     }
9662
9663     hr = IDirect3DDevice9_SetVertexShader(device, shader);
9664     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9665
9666     hr = IDirect3DDevice9_SetIndices(device, ib);
9667     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9668
9669     /* run all tests */
9670     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9671     {
9672         struct testdata act = testcases[i];
9673         decl[0].Stream = act.strVertex;
9674         decl[1].Stream = act.strColor;
9675         decl[2].Stream = act.strInstance;
9676         /* create VertexDeclarations */
9677         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9678         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9679
9680         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9681         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9682
9683         hr = IDirect3DDevice9_BeginScene(device);
9684         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9685         if(SUCCEEDED(hr))
9686         {
9687             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9688             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9689
9690             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9691             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9692             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9693             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9694
9695             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9696             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9697             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9698             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9699
9700             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9701             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9702             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9703             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9704
9705             /* don't know if this is right (1*3 and 4*1)*/
9706             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
9707             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9708             hr = IDirect3DDevice9_EndScene(device);
9709             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9710
9711             /* set all StreamSource && StreamSourceFreq back to default */
9712             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9713             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9714             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9715             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9716             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9717             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9718             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9719             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9720             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9721             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9722             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9723             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9724         }
9725
9726         hr = IDirect3DVertexDeclaration9_Release(pDecl);
9727         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9728
9729         color = getPixelColor(device, 160, 360);
9730         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9731         color = getPixelColor(device, 480, 360);
9732         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9733         color = getPixelColor(device, 480, 120);
9734         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9735         color = getPixelColor(device, 160, 120);
9736         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9737
9738         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9739         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9740     }
9741
9742     hr = IDirect3DDevice9_SetIndices(device, NULL);
9743     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9744
9745 out:
9746     if(vb) IDirect3DVertexBuffer9_Release(vb);
9747     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9748     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9749     if(ib)IDirect3DIndexBuffer9_Release(ib);
9750     if(shader)IDirect3DVertexShader9_Release(shader);
9751 }
9752
9753 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9754     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9755     IDirect3DTexture9 *dsttex = NULL;
9756     HRESULT hr;
9757     DWORD color;
9758     D3DRECT r1 = {0,  0,  50,  50 };
9759     D3DRECT r2 = {50, 0,  100, 50 };
9760     D3DRECT r3 = {50, 50, 100, 100};
9761     D3DRECT r4 = {0,  50,  50, 100};
9762     const float quad[] = {
9763         -1.0,   -1.0,   0.1,    0.0,    0.0,
9764          1.0,   -1.0,   0.1,    1.0,    0.0,
9765         -1.0,    1.0,   0.1,    0.0,    1.0,
9766          1.0,    1.0,   0.1,    1.0,    1.0,
9767     };
9768
9769     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9770     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9771
9772     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9773     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9774     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9775     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9776
9777     if(!src || !dsttex) {
9778         skip("One or more test resources could not be created\n");
9779         goto cleanup;
9780     }
9781
9782     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9783     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9784
9785     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9786     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9787
9788     /* Clear the StretchRect destination for debugging */
9789     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9790     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9791     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9792     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9793
9794     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9795     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9796
9797     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9798     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9799     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9800     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9801     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9802     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9803     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9804     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9805
9806     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9807      * the target -> texture GL blit path
9808      */
9809     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9810     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9811     IDirect3DSurface9_Release(dst);
9812
9813     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9814     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9815
9816     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9817     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9818     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9819     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9820     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9821     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9822     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9823     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9824
9825     hr = IDirect3DDevice9_BeginScene(device);
9826     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9827     if(SUCCEEDED(hr)) {
9828         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9829         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9830         hr = IDirect3DDevice9_EndScene(device);
9831         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9832     }
9833
9834     color = getPixelColor(device, 160, 360);
9835     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9836     color = getPixelColor(device, 480, 360);
9837     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9838     color = getPixelColor(device, 480, 120);
9839     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9840     color = getPixelColor(device, 160, 120);
9841     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9842     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9843     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9844
9845     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9846     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9847     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9848     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9849
9850 cleanup:
9851     if(src) IDirect3DSurface9_Release(src);
9852     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9853     if(dsttex) IDirect3DTexture9_Release(dsttex);
9854 }
9855
9856 static void texop_test(IDirect3DDevice9 *device)
9857 {
9858     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9859     IDirect3DTexture9 *texture = NULL;
9860     D3DLOCKED_RECT locked_rect;
9861     D3DCOLOR color;
9862     D3DCAPS9 caps;
9863     HRESULT hr;
9864     unsigned i;
9865
9866     static const struct {
9867         float x, y, z;
9868         float s, t;
9869         D3DCOLOR diffuse;
9870     } quad[] = {
9871         {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9872         {-1.0f,  1.0f, 0.1f, -1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9873         { 1.0f, -1.0f, 0.1f,  1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9874         { 1.0f,  1.0f, 0.1f,  1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9875     };
9876
9877     static const D3DVERTEXELEMENT9 decl_elements[] = {
9878         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9879         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9880         {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9881         D3DDECL_END()
9882     };
9883
9884     static const struct {
9885         D3DTEXTUREOP op;
9886         const char *name;
9887         DWORD caps_flag;
9888         D3DCOLOR result;
9889     } test_data[] = {
9890         {D3DTOP_SELECTARG1,                "SELECTARG1",                D3DTEXOPCAPS_SELECTARG1,                D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9891         {D3DTOP_SELECTARG2,                "SELECTARG2",                D3DTEXOPCAPS_SELECTARG2,                D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9892         {D3DTOP_MODULATE,                  "MODULATE",                  D3DTEXOPCAPS_MODULATE,                  D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9893         {D3DTOP_MODULATE2X,                "MODULATE2X",                D3DTEXOPCAPS_MODULATE2X,                D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9894         {D3DTOP_MODULATE4X,                "MODULATE4X",                D3DTEXOPCAPS_MODULATE4X,                D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9895         {D3DTOP_ADD,                       "ADD",                       D3DTEXOPCAPS_ADD,                       D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9896         {D3DTOP_ADDSIGNED,                 "ADDSIGNED",                 D3DTEXOPCAPS_ADDSIGNED,                 D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9897         {D3DTOP_ADDSIGNED2X,               "ADDSIGNED2X",               D3DTEXOPCAPS_ADDSIGNED2X,               D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9898         {D3DTOP_SUBTRACT,                  "SUBTRACT",                  D3DTEXOPCAPS_SUBTRACT,                  D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9899         {D3DTOP_ADDSMOOTH,                 "ADDSMOOTH",                 D3DTEXOPCAPS_ADDSMOOTH,                 D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9900         {D3DTOP_BLENDDIFFUSEALPHA,         "BLENDDIFFUSEALPHA",         D3DTEXOPCAPS_BLENDDIFFUSEALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9901         {D3DTOP_BLENDTEXTUREALPHA,         "BLENDTEXTUREALPHA",         D3DTEXOPCAPS_BLENDTEXTUREALPHA,         D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9902         {D3DTOP_BLENDFACTORALPHA,          "BLENDFACTORALPHA",          D3DTEXOPCAPS_BLENDFACTORALPHA,          D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9903         {D3DTOP_BLENDTEXTUREALPHAPM,       "BLENDTEXTUREALPHAPM",       D3DTEXOPCAPS_BLENDTEXTUREALPHAPM,       D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9904         {D3DTOP_BLENDCURRENTALPHA,         "BLENDCURRENTALPHA",         D3DTEXOPCAPS_BLENDCURRENTALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9905         {D3DTOP_MODULATEALPHA_ADDCOLOR,    "MODULATEALPHA_ADDCOLOR",    D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR,    D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9906         {D3DTOP_MODULATECOLOR_ADDALPHA,    "MODULATECOLOR_ADDALPHA",    D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA,    D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9907         {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9908         {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9909         /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9910         {D3DTOP_DOTPRODUCT3,               "DOTPRODUCT3",               D3DTEXOPCAPS_DOTPRODUCT3,               D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9911         {D3DTOP_MULTIPLYADD,               "MULTIPLYADD",               D3DTEXOPCAPS_MULTIPLYADD,               D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9912         {D3DTOP_LERP,                      "LERP",                      D3DTEXOPCAPS_LERP,                      D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9913     };
9914
9915     memset(&caps, 0, sizeof(caps));
9916     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9917     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9918
9919     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9920     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9921     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9922     ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9923
9924     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9925     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9926     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9927     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9928     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9929     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9930     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9931     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9932     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9933
9934     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9935     ok(SUCCEEDED(hr), "SetTextureStageState 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
9941     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9942     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9943
9944     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9945     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9946     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9947     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9948     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9949     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9950
9951     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9952     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9953
9954     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9955     {
9956         if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9957         {
9958             skip("tex operation %s not supported\n", test_data[i].name);
9959             continue;
9960         }
9961
9962         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9963         ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9964
9965         hr = IDirect3DDevice9_BeginScene(device);
9966         ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9967
9968         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9969         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9970
9971         hr = IDirect3DDevice9_EndScene(device);
9972         ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9973
9974         color = getPixelColor(device, 320, 240);
9975         ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9976                 test_data[i].name, color, test_data[i].result);
9977
9978         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9979         ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9980     }
9981
9982     if (texture) IDirect3DTexture9_Release(texture);
9983     if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9984 }
9985
9986 static void yuv_color_test(IDirect3DDevice9 *device) {
9987     HRESULT hr;
9988     IDirect3DSurface9 *surface = NULL, *target = NULL;
9989     unsigned int fmt, i;
9990     D3DFORMAT format;
9991     const char *fmt_string;
9992     D3DLOCKED_RECT lr;
9993     IDirect3D9 *d3d;
9994     HRESULT color;
9995     DWORD ref_color_left, ref_color_right;
9996
9997     struct {
9998         DWORD in;           /* The input color */
9999         DWORD uyvy_left;    /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
10000         DWORD uyvy_right;   /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
10001         DWORD yuy2_left;    /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
10002         DWORD yuy2_right;   /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
10003     } test_data[] = {
10004     /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
10005      * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
10006      * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
10007      * that
10008      */
10009       { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
10010       { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
10011       { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
10012       { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
10013       { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
10014       { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
10015       { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
10016       { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
10017       { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
10018       { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
10019       { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
10020       { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
10021       { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
10022       { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
10023
10024       { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
10025       { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
10026       { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
10027       { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
10028     };
10029
10030     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
10031     ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
10032     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
10033     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
10034
10035     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
10036     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
10037
10038     for(fmt = 0; fmt < 2; fmt++) {
10039         if(fmt == 0) {
10040             format = D3DFMT_UYVY;
10041             fmt_string = "D3DFMT_UYVY";
10042         } else {
10043             format = D3DFMT_YUY2;
10044             fmt_string = "D3DFMT_YUY2";
10045         }
10046
10047         /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
10048                        * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
10049                        */
10050         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
10051                                         D3DRTYPE_SURFACE, format) != D3D_OK) {
10052             skip("%s is not supported\n", fmt_string);
10053             continue;
10054         }
10055
10056         /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
10057         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
10058         ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
10059
10060         for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
10061             if(fmt == 0) {
10062                 ref_color_left = test_data[i].uyvy_left;
10063                 ref_color_right = test_data[i].uyvy_right;
10064             } else {
10065                 ref_color_left = test_data[i].yuy2_left;
10066                 ref_color_right = test_data[i].yuy2_right;
10067             }
10068
10069             memset(&lr, 0, sizeof(lr));
10070             hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
10071             ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
10072             *((DWORD *) lr.pBits) = test_data[i].in;
10073             hr = IDirect3DSurface9_UnlockRect(surface);
10074             ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
10075
10076             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10077             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10078             hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
10079             ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
10080
10081             /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
10082              * prevent running into precision problems, read a far left and far right pixel. In the future we may
10083              * want to add tests for the filtered pixels as well.
10084              *
10085              * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
10086              * differently, so we need a max diff of 16
10087              */
10088             color = getPixelColor(device, 40, 240);
10089             ok(color_match(color, ref_color_left, 18),
10090                "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
10091                test_data[i].in, color, ref_color_left, fmt_string);
10092             color = getPixelColor(device, 600, 240);
10093             ok(color_match(color, ref_color_right, 18),
10094                "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
10095                test_data[i].in, color, ref_color_right, fmt_string);
10096             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10097             ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10098         }
10099         IDirect3DSurface9_Release(surface);
10100     }
10101     IDirect3DSurface9_Release(target);
10102     IDirect3D9_Release(d3d);
10103 }
10104
10105 static void texop_range_test(IDirect3DDevice9 *device)
10106 {
10107     static const struct {
10108         float x, y, z;
10109         D3DCOLOR diffuse;
10110     } quad[] = {
10111         {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10112         {-1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10113         { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10114         { 1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
10115     };
10116     HRESULT hr;
10117     IDirect3DTexture9 *texture;
10118     D3DLOCKED_RECT locked_rect;
10119     D3DCAPS9 caps;
10120     DWORD color;
10121
10122     /* We need ADD and SUBTRACT operations */
10123     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10124     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10125     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
10126         skip("D3DTOP_ADD is not supported, skipping value range test\n");
10127         return;
10128     }
10129     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
10130         skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
10131         return;
10132     }
10133
10134     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10135     ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
10136     /* Stage 1: result = diffuse(=1.0) + diffuse
10137      * stage 2: result = result - tfactor(= 0.5)
10138      */
10139     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10140     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10141     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10142     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10143     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10144     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10145     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
10146     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10147     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10148     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10149     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10150     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10151     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10152     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10153
10154     hr = IDirect3DDevice9_BeginScene(device);
10155     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10156     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10157     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10158     hr = IDirect3DDevice9_EndScene(device);
10159     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10160
10161     color = getPixelColor(device, 320, 240);
10162     ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
10163        color);
10164     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10165     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10166
10167     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
10168     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
10169     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
10170     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10171     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
10172     hr = IDirect3DTexture9_UnlockRect(texture, 0);
10173     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10174     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10175     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10176
10177     /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
10178      * stage 2: result = result + diffuse(1.0)
10179      */
10180     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10181     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10182     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10183     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10184     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10185     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10186     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10187     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10188     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10189     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10190     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10191     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10192     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
10193     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10194
10195     hr = IDirect3DDevice9_BeginScene(device);
10196     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10197     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10198     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10199     hr = IDirect3DDevice9_EndScene(device);
10200     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10201
10202     color = getPixelColor(device, 320, 240);
10203     ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
10204        color);
10205     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10206     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10207
10208     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10209     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10210     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10211     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10212     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
10213     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10214     IDirect3DTexture9_Release(texture);
10215 }
10216
10217 static void alphareplicate_test(IDirect3DDevice9 *device) {
10218     struct vertex quad[] = {
10219         { -1.0,    -1.0,    0.1,    0x80ff00ff },
10220         {  1.0,    -1.0,    0.1,    0x80ff00ff },
10221         { -1.0,     1.0,    0.1,    0x80ff00ff },
10222         {  1.0,     1.0,    0.1,    0x80ff00ff },
10223     };
10224     HRESULT hr;
10225     DWORD color;
10226
10227     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10228     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10229
10230     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10231     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10232
10233     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10234     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10235     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
10236     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10237
10238     hr = IDirect3DDevice9_BeginScene(device);
10239     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10240     if(SUCCEEDED(hr)) {
10241         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10242         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10243         hr = IDirect3DDevice9_EndScene(device);
10244         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10245     }
10246
10247     color = getPixelColor(device, 320, 240);
10248     ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
10249        color);
10250     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10251     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10252
10253     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10254     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10255
10256 }
10257
10258 static void dp3_alpha_test(IDirect3DDevice9 *device) {
10259     HRESULT hr;
10260     D3DCAPS9 caps;
10261     DWORD color;
10262     struct vertex quad[] = {
10263         { -1.0,    -1.0,    0.1,    0x408080c0 },
10264         {  1.0,    -1.0,    0.1,    0x408080c0 },
10265         { -1.0,     1.0,    0.1,    0x408080c0 },
10266         {  1.0,     1.0,    0.1,    0x408080c0 },
10267     };
10268
10269     memset(&caps, 0, sizeof(caps));
10270     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10271     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10272     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
10273         skip("D3DTOP_DOTPRODUCT3 not supported\n");
10274         return;
10275     }
10276
10277     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10278     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10279
10280     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10281     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10282
10283     /* dp3_x4 r0, diffuse_bias, tfactor_bias
10284      * mov r0.a, diffuse.a
10285      * mov r0, r0.a
10286      *
10287      * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
10288      * 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
10289      * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
10290      */
10291     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
10292     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10293     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10294     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10295     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10296     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10297     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
10298     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10299     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
10300     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10301     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10302     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10303     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
10304     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10305     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10306     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10307     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
10308     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10309
10310     hr = IDirect3DDevice9_BeginScene(device);
10311     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10312     if(SUCCEEDED(hr)) {
10313         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10314         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10315         hr = IDirect3DDevice9_EndScene(device);
10316         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10317     }
10318
10319     color = getPixelColor(device, 320, 240);
10320     ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
10321        color);
10322     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10323     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10324
10325     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10326     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10327     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10328     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10329     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10330     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10331 }
10332
10333 static void zwriteenable_test(IDirect3DDevice9 *device) {
10334     HRESULT hr;
10335     DWORD color;
10336     struct vertex quad1[] = {
10337         { -1.0,  -1.0,  0.1,    0x00ff0000},
10338         { -1.0,   1.0,  0.1,    0x00ff0000},
10339         {  1.0,  -1.0,  0.1,    0x00ff0000},
10340         {  1.0,   1.0,  0.1,    0x00ff0000},
10341     };
10342     struct vertex quad2[] = {
10343         { -1.0,  -1.0,  0.9,    0x0000ff00},
10344         { -1.0,   1.0,  0.9,    0x0000ff00},
10345         {  1.0,  -1.0,  0.9,    0x0000ff00},
10346         {  1.0,   1.0,  0.9,    0x0000ff00},
10347     };
10348
10349     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
10350     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10351
10352     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10353     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10354     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10355     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10356     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10357     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10358     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10359     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10360
10361     hr = IDirect3DDevice9_BeginScene(device);
10362     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10363     if(SUCCEEDED(hr)) {
10364         /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10365          * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10366          * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10367          * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10368          * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10369          * the screen is green, so zenable = D3DZB_FALSE and zwriteenable  = TRUE does NOT write to the z buffer.
10370          */
10371         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10372         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10373         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10374         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10375         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10376         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10377
10378         hr = IDirect3DDevice9_EndScene(device);
10379         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10380     }
10381
10382     color = getPixelColor(device, 320, 240);
10383     ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10384        color);
10385     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10386     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10387
10388     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10389     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10390 }
10391
10392 static void alphatest_test(IDirect3DDevice9 *device) {
10393 #define ALPHATEST_PASSED 0x0000ff00
10394 #define ALPHATEST_FAILED 0x00ff0000
10395     struct {
10396         D3DCMPFUNC  func;
10397         DWORD       color_less;
10398         DWORD       color_equal;
10399         DWORD       color_greater;
10400     } testdata[] = {
10401         {   D3DCMP_NEVER,           ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10402         {   D3DCMP_LESS,            ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10403         {   D3DCMP_EQUAL,           ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10404         {   D3DCMP_LESSEQUAL,       ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10405         {   D3DCMP_GREATER,         ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10406         {   D3DCMP_NOTEQUAL,        ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10407         {   D3DCMP_GREATEREQUAL,    ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10408         {   D3DCMP_ALWAYS,          ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10409     };
10410     unsigned int i, j;
10411     HRESULT hr;
10412     DWORD color;
10413     struct vertex quad[] = {
10414         {   -1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10415         {    1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10416         {   -1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10417         {    1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10418     };
10419     D3DCAPS9 caps;
10420
10421     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10422     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10423     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10424     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10425
10426     for(j = 0; j < 2; j++) {
10427         if(j == 1) {
10428             /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10429              * the alpha test either for performance reasons(floating point RTs) or to work
10430              * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10431              * codepath for ffp and shader in this case, and the test should cover both
10432              */
10433             IDirect3DPixelShader9 *ps;
10434             DWORD shader_code[] = {
10435                 0xffff0101,                                 /* ps_1_1           */
10436                 0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
10437                 0x0000ffff                                  /* end              */
10438             };
10439             memset(&caps, 0, sizeof(caps));
10440             IDirect3DDevice9_GetDeviceCaps(device, &caps);
10441             ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10442             if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10443                 break;
10444             }
10445
10446             hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10447             ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10448             IDirect3DDevice9_SetPixelShader(device, ps);
10449             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10450             IDirect3DPixelShader9_Release(ps);
10451         }
10452
10453         for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10454             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10455             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10456
10457             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10458             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10459             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10460             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10461             hr = IDirect3DDevice9_BeginScene(device);
10462             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10463             if(SUCCEEDED(hr)) {
10464                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10465                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10466                 hr = IDirect3DDevice9_EndScene(device);
10467                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10468             }
10469             color = getPixelColor(device, 320, 240);
10470             ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10471             color, testdata[i].color_less, testdata[i].func);
10472             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10473             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10474
10475             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10476             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10477             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10478             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10479             hr = IDirect3DDevice9_BeginScene(device);
10480             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10481             if(SUCCEEDED(hr)) {
10482                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10483                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10484                 hr = IDirect3DDevice9_EndScene(device);
10485                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10486             }
10487             color = getPixelColor(device, 320, 240);
10488             ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10489             color, testdata[i].color_equal, testdata[i].func);
10490             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10491             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10492
10493             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10494             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10495             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10496             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10497             hr = IDirect3DDevice9_BeginScene(device);
10498             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10499             if(SUCCEEDED(hr)) {
10500                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10501                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10502                 hr = IDirect3DDevice9_EndScene(device);
10503                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10504             }
10505             color = getPixelColor(device, 320, 240);
10506             ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10507             color, testdata[i].color_greater, testdata[i].func);
10508             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10509             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10510         }
10511     }
10512
10513     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10514     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10515     IDirect3DDevice9_SetPixelShader(device, NULL);
10516     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10517 }
10518
10519 static void sincos_test(IDirect3DDevice9 *device) {
10520     const DWORD sin_shader_code[] = {
10521         0xfffe0200,                                                                 /* vs_2_0                       */
10522         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10523         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10524         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10525         0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.y, r1.x, c0, c1    */
10526         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10527         0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002,                             /* mul oPos.y, r0.y, c2.w       */
10528         0x02000001, 0xd00f0000, 0xa0a60002,                                         /* mov oD0, c2.zyzz             */
10529         0x0000ffff                                                                  /* end                          */
10530     };
10531     const DWORD cos_shader_code[] = {
10532         0xfffe0200,                                                                 /* vs_2_0                       */
10533         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10534         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10535         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10536         0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.x, r1.x, c0, c1    */
10537         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10538         0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002,                             /* mul oPos.y, r0.x, c2.w       */
10539         0x02000001, 0xd00f0000, 0xa0a90002,                                         /* mov oD0, c2.yzzz             */
10540         0x0000ffff                                                                  /* end                          */
10541     };
10542     IDirect3DVertexShader9 *sin_shader, *cos_shader;
10543     HRESULT hr;
10544     struct {
10545         float x, y, z;
10546     } data[1280];
10547     unsigned int i;
10548     float sincosc1[4] = {D3DSINCOSCONST1};
10549     float sincosc2[4] = {D3DSINCOSCONST2};
10550
10551     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10552     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10553
10554     hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10555     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10556     hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10557     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10558     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10559     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10560     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10561     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10562     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10563     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10564
10565     /* Generate a point from -1 to 1 every 0.5 pixels */
10566     for(i = 0; i < 1280; i++) {
10567         data[i].x = (-640.0 + i) / 640.0;
10568         data[i].y = 0.0;
10569         data[i].z = 0.1;
10570     }
10571
10572     hr = IDirect3DDevice9_BeginScene(device);
10573     if(SUCCEEDED(hr)) {
10574         hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10575         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10576         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10577         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10578
10579         hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10580         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10581         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10582         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10583
10584         hr = IDirect3DDevice9_EndScene(device);
10585         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10586     }
10587     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10588     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10589     /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10590
10591     IDirect3DDevice9_SetVertexShader(device, NULL);
10592     IDirect3DVertexShader9_Release(sin_shader);
10593     IDirect3DVertexShader9_Release(cos_shader);
10594 }
10595
10596 static void loop_index_test(IDirect3DDevice9 *device) {
10597     const DWORD shader_code[] = {
10598         0xfffe0200,                                                 /* vs_2_0                   */
10599         0x0200001f, 0x80000000, 0x900f0000,                         /* dcl_position v0          */
10600         0x02000001, 0x800f0000, 0xa0e40000,                         /* mov r0, c0               */
10601         0x0200001b, 0xf0e40800, 0xf0e40000,                         /* loop aL, i0              */
10602         0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1]    */
10603         0x0000001d,                                                 /* endloop                  */
10604         0x02000001, 0xc00f0000, 0x90e40000,                         /* mov oPos, v0             */
10605         0x02000001, 0xd00f0000, 0x80e40000,                         /* mov oD0, r0              */
10606         0x0000ffff                                                  /* END                      */
10607     };
10608     IDirect3DVertexShader9 *shader;
10609     HRESULT hr;
10610     DWORD color;
10611     const float quad[] = {
10612         -1.0,   -1.0,   0.1,
10613          1.0,   -1.0,   0.1,
10614         -1.0,    1.0,   0.1,
10615          1.0,    1.0,   0.1
10616     };
10617     const float zero[4] = {0, 0, 0, 0};
10618     const float one[4] = {1, 1, 1, 1};
10619     int i0[4] = {2, 10, -3, 0};
10620     float values[4];
10621
10622     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10623     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10624     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10625     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10626     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10627     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10628     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10629     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10630
10631     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10632     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10633     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10634     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10635     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10636     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10637     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10638     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10639     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10640     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10641     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10642     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10643     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10644     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10645     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10646     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10647     values[0] = 1.0;
10648     values[1] = 1.0;
10649     values[2] = 0.0;
10650     values[3] = 0.0;
10651     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10652     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10653     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10654     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10655     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10656     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10657     values[0] = -1.0;
10658     values[1] = 0.0;
10659     values[2] = 0.0;
10660     values[3] = 0.0;
10661     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10662     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10663     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10664     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10665     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10666     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10667     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10668     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10669     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10670     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10671
10672     hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10673     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10674
10675     hr = IDirect3DDevice9_BeginScene(device);
10676     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10677     if(SUCCEEDED(hr))
10678     {
10679         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10680         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10681         hr = IDirect3DDevice9_EndScene(device);
10682         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10683     }
10684     color = getPixelColor(device, 320, 240);
10685     ok(color_match(color, 0x0000ff00, 1),
10686        "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10687     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10688     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10689
10690     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10691     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10692     IDirect3DVertexShader9_Release(shader);
10693 }
10694
10695 static void sgn_test(IDirect3DDevice9 *device) {
10696     const DWORD shader_code[] = {
10697         0xfffe0200,                                                             /* vs_2_0                       */
10698         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position o0              */
10699         0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10700         0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0   */
10701         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
10702         0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002,             /* sgn r0, c0, r1, r2           */
10703         0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001,                         /* add oD0, r0, c1              */
10704         0x0000ffff                                                              /* end                          */
10705     };
10706     IDirect3DVertexShader9 *shader;
10707     HRESULT hr;
10708     DWORD color;
10709     const float quad[] = {
10710         -1.0,   -1.0,   0.1,
10711          1.0,   -1.0,   0.1,
10712         -1.0,    1.0,   0.1,
10713          1.0,    1.0,   0.1
10714     };
10715
10716     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10717     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10718     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10719     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10720     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10721     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10722     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10723     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10724
10725     hr = IDirect3DDevice9_BeginScene(device);
10726     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10727     if(SUCCEEDED(hr))
10728     {
10729         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10730         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10731         hr = IDirect3DDevice9_EndScene(device);
10732         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10733     }
10734     color = getPixelColor(device, 320, 240);
10735     ok(color_match(color, 0x008000ff, 1),
10736        "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10737     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10738     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10739
10740     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10741     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10742     IDirect3DVertexShader9_Release(shader);
10743 }
10744
10745 static void viewport_test(IDirect3DDevice9 *device) {
10746     HRESULT hr;
10747     DWORD color;
10748     D3DVIEWPORT9 vp, old_vp;
10749     const float quad[] =
10750     {
10751         -0.5,   -0.5,   0.1,
10752          0.5,   -0.5,   0.1,
10753         -0.5,    0.5,   0.1,
10754          0.5,    0.5,   0.1
10755     };
10756
10757     memset(&old_vp, 0, sizeof(old_vp));
10758     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10759     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10760
10761     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10762     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10763
10764     /* Test a viewport with Width and Height bigger than the surface dimensions
10765      *
10766      * TODO: Test Width < surface.width, but X + Width > surface.width
10767      * TODO: Test Width < surface.width, what happens with the height?
10768      */
10769     memset(&vp, 0, sizeof(vp));
10770     vp.X = 0;
10771     vp.Y = 0;
10772     vp.Width = 10000;
10773     vp.Height = 10000;
10774     vp.MinZ = 0.0;
10775     vp.MaxZ = 0.0;
10776     hr = IDirect3DDevice9_SetViewport(device, &vp);
10777     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10778
10779     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10780     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10781     hr = IDirect3DDevice9_BeginScene(device);
10782     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10783     if(SUCCEEDED(hr))
10784     {
10785         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10786         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10787         hr = IDirect3DDevice9_EndScene(device);
10788         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10789     }
10790
10791     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10792     color = getPixelColor(device, 158, 118);
10793     ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10794     color = getPixelColor(device, 162, 118);
10795     ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10796     color = getPixelColor(device, 158, 122);
10797     ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10798     color = getPixelColor(device, 162, 122);
10799     ok(color == 0x00ffffff, "viewport test: (162,122) has color %08x\n", color);
10800
10801     color = getPixelColor(device, 478, 358);
10802     ok(color == 0x00ffffff, "viewport test: (478,358 has color %08x\n", color);
10803     color = getPixelColor(device, 482, 358);
10804     ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10805     color = getPixelColor(device, 478, 362);
10806     ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10807     color = getPixelColor(device, 482, 362);
10808     ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10809
10810     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10811     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10812
10813     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10814     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10815 }
10816
10817 /* This test tests depth clamping / clipping behaviour:
10818  *   - When D3DRS_CLIPPING is disabled depth values are *clamped* to the
10819  *   minimum/maximum z value.
10820  *   - The viewport's MinZ/MaxZ is irrelevant for this.
10821  *   - When D3DRS_CLIPPING is enabled depth values are clipped.
10822  *   - Pretransformed vertices behave the same as regular vertices.
10823  */
10824 static void depth_clamp_test(IDirect3DDevice9 *device)
10825 {
10826     const struct tvertex quad1[] =
10827     {
10828         {    0,    0,  5.0f, 1.0, 0xff002b7f},
10829         {  640,    0,  5.0f, 1.0, 0xff002b7f},
10830         {    0,  480,  5.0f, 1.0, 0xff002b7f},
10831         {  640,  480,  5.0f, 1.0, 0xff002b7f},
10832     };
10833     const struct tvertex quad2[] =
10834     {
10835         {    0,  300, 10.0f, 1.0, 0xfff9e814},
10836         {  640,  300, 10.0f, 1.0, 0xfff9e814},
10837         {    0,  360, 10.0f, 1.0, 0xfff9e814},
10838         {  640,  360, 10.0f, 1.0, 0xfff9e814},
10839     };
10840     const struct vertex quad3[] =
10841     {
10842         {-0.65, 0.55,  5.0f,      0xffffffff},
10843         {-0.35, 0.55,  5.0f,      0xffffffff},
10844         {-0.65, 0.15,  5.0f,      0xffffffff},
10845         {-0.35, 0.15,  5.0f,      0xffffffff},
10846     };
10847     const struct vertex quad4[] =
10848     {
10849         {-0.87, 0.83, 10.0f,      0xffffffff},
10850         {-0.65, 0.83, 10.0f,      0xffffffff},
10851         {-0.87, 0.55, 10.0f,      0xffffffff},
10852         {-0.65, 0.55, 10.0f,      0xffffffff},
10853     };
10854     const struct vertex quad5[] =
10855     {
10856         { -0.5,  0.5, 10.0f,      0xff14f914},
10857         {  0.5,  0.5, 10.0f,      0xff14f914},
10858         { -0.5, -0.5, 10.0f,      0xff14f914},
10859         {  0.5, -0.5, 10.0f,      0xff14f914},
10860     };
10861     const struct tvertex quad6[] =
10862     {
10863         {    0,  120, 10.0f, 1.0, 0xfff91414},
10864         {  640,  120, 10.0f, 1.0, 0xfff91414},
10865         {    0,  180, 10.0f, 1.0, 0xfff91414},
10866         {  640,  180, 10.0f, 1.0, 0xfff91414},
10867     };
10868
10869     D3DVIEWPORT9 vp;
10870     D3DCOLOR color;
10871     HRESULT hr;
10872
10873     vp.X = 0;
10874     vp.Y = 0;
10875     vp.Width = 640;
10876     vp.Height = 480;
10877     vp.MinZ = 0.0;
10878     vp.MaxZ = 7.5;
10879
10880     hr = IDirect3DDevice9_SetViewport(device, &vp);
10881     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10882
10883     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
10884     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10885
10886     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10887     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10888     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10889     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10890     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10891     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10892     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10893     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10894
10895     hr = IDirect3DDevice9_BeginScene(device);
10896     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10897
10898     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10899     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10900
10901     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10902     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10903     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10904     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10905
10906     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10907     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10908
10909     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10910     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10911     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
10912     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10913
10914     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10915     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10916
10917     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
10918     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10919
10920     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10921     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10922
10923     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
10924     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10925
10926     hr = IDirect3DDevice9_EndScene(device);
10927     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10928
10929     color = getPixelColor(device, 75, 75);
10930     ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10931     color = getPixelColor(device, 150, 150);
10932     ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10933     color = getPixelColor(device, 320, 240);
10934     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10935     color = getPixelColor(device, 320, 330);
10936     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10937     color = getPixelColor(device, 320, 330);
10938     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10939
10940     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10941     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10942
10943     vp.MinZ = 0.0;
10944     vp.MaxZ = 1.0;
10945     hr = IDirect3DDevice9_SetViewport(device, &vp);
10946     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10947 }
10948
10949 static void depth_buffer_test(IDirect3DDevice9 *device)
10950 {
10951     static const struct vertex quad1[] =
10952     {
10953         { -1.0,  1.0, 0.33f, 0xff00ff00},
10954         {  1.0,  1.0, 0.33f, 0xff00ff00},
10955         { -1.0, -1.0, 0.33f, 0xff00ff00},
10956         {  1.0, -1.0, 0.33f, 0xff00ff00},
10957     };
10958     static const struct vertex quad2[] =
10959     {
10960         { -1.0,  1.0, 0.50f, 0xffff00ff},
10961         {  1.0,  1.0, 0.50f, 0xffff00ff},
10962         { -1.0, -1.0, 0.50f, 0xffff00ff},
10963         {  1.0, -1.0, 0.50f, 0xffff00ff},
10964     };
10965     static const struct vertex quad3[] =
10966     {
10967         { -1.0,  1.0, 0.66f, 0xffff0000},
10968         {  1.0,  1.0, 0.66f, 0xffff0000},
10969         { -1.0, -1.0, 0.66f, 0xffff0000},
10970         {  1.0, -1.0, 0.66f, 0xffff0000},
10971     };
10972     static const DWORD expected_colors[4][4] =
10973     {
10974         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10975         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10976         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
10977         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
10978     };
10979
10980     IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
10981     unsigned int i, j;
10982     D3DVIEWPORT9 vp;
10983     D3DCOLOR color;
10984     HRESULT hr;
10985
10986     vp.X = 0;
10987     vp.Y = 0;
10988     vp.Width = 640;
10989     vp.Height = 480;
10990     vp.MinZ = 0.0;
10991     vp.MaxZ = 1.0;
10992
10993     hr = IDirect3DDevice9_SetViewport(device, &vp);
10994     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10995
10996     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10997     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10998     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10999     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11000     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11001     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11002     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11003     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11004     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11005     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11006
11007     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11008     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11009     hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
11010             D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
11011     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11012     hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
11013             D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
11014     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11015     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11016             D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
11017     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11018
11019     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
11020     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11021     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
11022     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11023
11024     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11025     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11026     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11027     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11028
11029     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11030     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11031     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11032     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11033
11034     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11035     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11036     hr = IDirect3DDevice9_BeginScene(device);
11037     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11038     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11039     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11040     hr = IDirect3DDevice9_EndScene(device);
11041     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11042
11043     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11044     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11045     IDirect3DSurface9_Release(backbuffer);
11046     IDirect3DSurface9_Release(rt3);
11047     IDirect3DSurface9_Release(rt2);
11048     IDirect3DSurface9_Release(rt1);
11049
11050     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11051     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11052
11053     hr = IDirect3DDevice9_BeginScene(device);
11054     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11055     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11056     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11057     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11058     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11059     hr = IDirect3DDevice9_EndScene(device);
11060     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11061
11062     for (i = 0; i < 4; ++i)
11063     {
11064         for (j = 0; j < 4; ++j)
11065         {
11066             unsigned int x = 80 * ((2 * j) + 1);
11067             unsigned int y = 60 * ((2 * i) + 1);
11068             color = getPixelColor(device, x, y);
11069             ok(color_match(color, expected_colors[i][j], 0),
11070                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11071         }
11072     }
11073
11074     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11075     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11076 }
11077
11078 static void shadow_test(IDirect3DDevice9 *device)
11079 {
11080     static const DWORD ps_code[] =
11081     {
11082         0xffff0200,                                                             /* ps_2_0                       */
11083         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
11084         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
11085         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
11086         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
11087         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
11088         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
11089         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
11090         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
11091         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov 0C0, r1                  */
11092         0x0000ffff,                                                             /* end                          */
11093     };
11094     struct
11095     {
11096         D3DFORMAT format;
11097         const char *name;
11098     }
11099     formats[] =
11100     {
11101         {D3DFMT_D16_LOCKABLE,   "D3DFMT_D16_LOCKABLE"},
11102         {D3DFMT_D32,            "D3DFMT_D32"},
11103         {D3DFMT_D15S1,          "D3DFMT_D15S1"},
11104         {D3DFMT_D24S8,          "D3DFMT_D24S8"},
11105         {D3DFMT_D24X8,          "D3DFMT_D24X8"},
11106         {D3DFMT_D24X4S4,        "D3DFMT_D24X4S4"},
11107         {D3DFMT_D16,            "D3DFMT_D16"},
11108         {D3DFMT_D32F_LOCKABLE,  "D3DFMT_D32F_LOCKABLE"},
11109         {D3DFMT_D24FS8,         "D3DFMT_D24FS8"},
11110     };
11111     struct
11112     {
11113         float x, y, z;
11114         float s, t, p, q;
11115     }
11116     quad[] =
11117     {
11118         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
11119         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
11120         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
11121         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
11122     };
11123     struct
11124     {
11125         UINT x, y;
11126         D3DCOLOR color;
11127     }
11128     expected_colors[] =
11129     {
11130         {400,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11131         {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11132         {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11133         {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11134         {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11135         { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11136         { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11137         {240,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11138     };
11139
11140     IDirect3DSurface9 *original_ds, *original_rt, *rt;
11141     IDirect3DPixelShader9 *ps;
11142     IDirect3D9 *d3d9;
11143     D3DCAPS9 caps;
11144     HRESULT hr;
11145     UINT i;
11146
11147     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11148     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11149     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11150     {
11151         skip("No pixel shader 2.0 support, skipping shadow test.\n");
11152         return;
11153     }
11154
11155     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11156     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11157     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11158     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11159     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11160     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11161
11162     hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
11163             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11164     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11165     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11166     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11167
11168     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11169     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11170     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11171     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11172     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11173     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11174     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11175     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11176     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11177     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11178
11179     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11180     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11181     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11182     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11183     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11184     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11185     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11186     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11187     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11188     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11189
11190     for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
11191     {
11192         D3DFORMAT format = formats[i].format;
11193         IDirect3DTexture9 *texture;
11194         IDirect3DSurface9 *ds;
11195         unsigned int j;
11196
11197         hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11198                 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
11199         if (FAILED(hr)) continue;
11200
11201         hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
11202                 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
11203         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11204
11205         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11206         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11207
11208         hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11209         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11210
11211         hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11212         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11213
11214         IDirect3DDevice9_SetPixelShader(device, NULL);
11215         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11216
11217         /* Setup the depth/stencil surface. */
11218         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11219         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11220
11221         hr = IDirect3DDevice9_BeginScene(device);
11222         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11223         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11224         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11225         hr = IDirect3DDevice9_EndScene(device);
11226         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11227
11228         hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11229         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11230         IDirect3DSurface9_Release(ds);
11231
11232         hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11233         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11234
11235         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11236         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11237
11238         hr = IDirect3DDevice9_SetPixelShader(device, ps);
11239         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11240
11241         /* Do the actual shadow mapping. */
11242         hr = IDirect3DDevice9_BeginScene(device);
11243         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11244         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11245         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11246         hr = IDirect3DDevice9_EndScene(device);
11247         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11248
11249         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11250         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11251         IDirect3DTexture9_Release(texture);
11252
11253         for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
11254         {
11255             D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
11256             ok(color_match(color, expected_colors[j].color, 0),
11257                     "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
11258                     expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
11259                     formats[i].name, color);
11260         }
11261
11262         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11263         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11264     }
11265
11266     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11267     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11268     IDirect3DPixelShader9_Release(ps);
11269
11270     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11271     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11272     IDirect3DSurface9_Release(original_ds);
11273
11274     IDirect3DSurface9_Release(original_rt);
11275     IDirect3DSurface9_Release(rt);
11276
11277     IDirect3D9_Release(d3d9);
11278 }
11279
11280 START_TEST(visual)
11281 {
11282     IDirect3DDevice9 *device_ptr;
11283     D3DCAPS9 caps;
11284     HRESULT hr;
11285     DWORD color;
11286
11287     d3d9_handle = LoadLibraryA("d3d9.dll");
11288     if (!d3d9_handle)
11289     {
11290         skip("Could not load d3d9.dll\n");
11291         return;
11292     }
11293
11294     device_ptr = init_d3d9();
11295     if (!device_ptr)
11296     {
11297         skip("Creating the device failed\n");
11298         return;
11299     }
11300
11301     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
11302
11303     /* Check for the reliability of the returned data */
11304     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
11305     if(FAILED(hr))
11306     {
11307         skip("Clear failed, can't assure correctness of the test results, skipping\n");
11308         goto cleanup;
11309     }
11310
11311     color = getPixelColor(device_ptr, 1, 1);
11312     if(color !=0x00ff0000)
11313     {
11314         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
11315         goto cleanup;
11316     }
11317     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
11318
11319     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
11320     if(FAILED(hr))
11321     {
11322         skip("Clear failed, can't assure correctness of the test results, skipping\n");
11323         goto cleanup;
11324     }
11325
11326     color = getPixelColor(device_ptr, 639, 479);
11327     if(color != 0x0000ddee)
11328     {
11329         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
11330         goto cleanup;
11331     }
11332     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
11333
11334     /* Now execute the real tests */
11335     depth_clamp_test(device_ptr);
11336     stretchrect_test(device_ptr);
11337     lighting_test(device_ptr);
11338     clear_test(device_ptr);
11339     color_fill_test(device_ptr);
11340     fog_test(device_ptr);
11341     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
11342     {
11343         test_cube_wrap(device_ptr);
11344     } else {
11345         skip("No cube texture support\n");
11346     }
11347     z_range_test(device_ptr);
11348     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
11349     {
11350         maxmip_test(device_ptr);
11351     }
11352     else
11353     {
11354         skip("No mipmap support\n");
11355     }
11356     offscreen_test(device_ptr);
11357     alpha_test(device_ptr);
11358     shademode_test(device_ptr);
11359     srgbtexture_test(device_ptr);
11360     release_buffer_test(device_ptr);
11361     float_texture_test(device_ptr);
11362     g16r16_texture_test(device_ptr);
11363     pixelshader_blending_test(device_ptr);
11364     texture_transform_flags_test(device_ptr);
11365     autogen_mipmap_test(device_ptr);
11366     fixed_function_decl_test(device_ptr);
11367     conditional_np2_repeat_test(device_ptr);
11368     fixed_function_bumpmap_test(device_ptr);
11369     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
11370         stencil_cull_test(device_ptr);
11371     } else {
11372         skip("No two sided stencil support\n");
11373     }
11374     pointsize_test(device_ptr);
11375     tssargtemp_test(device_ptr);
11376     np2_stretch_rect_test(device_ptr);
11377     yuv_color_test(device_ptr);
11378     zwriteenable_test(device_ptr);
11379     alphatest_test(device_ptr);
11380     viewport_test(device_ptr);
11381
11382     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
11383     {
11384         test_constant_clamp_vs(device_ptr);
11385         test_compare_instructions(device_ptr);
11386     }
11387     else skip("No vs_1_1 support\n");
11388
11389     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
11390     {
11391         test_mova(device_ptr);
11392         loop_index_test(device_ptr);
11393         sincos_test(device_ptr);
11394         sgn_test(device_ptr);
11395         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
11396             test_vshader_input(device_ptr);
11397             test_vshader_float16(device_ptr);
11398             stream_test(device_ptr);
11399         } else {
11400             skip("No vs_3_0 support\n");
11401         }
11402     }
11403     else skip("No vs_2_0 support\n");
11404
11405     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
11406     {
11407         fog_with_shader_test(device_ptr);
11408         fog_srgbwrite_test(device_ptr);
11409     }
11410     else skip("No vs_1_1 and ps_1_1 support\n");
11411
11412     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
11413     {
11414         texbem_test(device_ptr);
11415         texdepth_test(device_ptr);
11416         texkill_test(device_ptr);
11417         x8l8v8u8_test(device_ptr);
11418         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
11419             constant_clamp_ps_test(device_ptr);
11420             cnd_test(device_ptr);
11421             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
11422                 dp2add_ps_test(device_ptr);
11423                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
11424                     nested_loop_test(device_ptr);
11425                     fixed_function_varying_test(device_ptr);
11426                     vFace_register_test(device_ptr);
11427                     vpos_register_test(device_ptr);
11428                     multiple_rendertargets_test(device_ptr);
11429                     if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
11430                         vshader_version_varying_test(device_ptr);
11431                         pshader_version_varying_test(device_ptr);
11432                     } else {
11433                         skip("No vs_3_0 support\n");
11434                     }
11435                 } else {
11436                     skip("No ps_3_0 support\n");
11437                 }
11438             } else {
11439                 skip("No ps_2_0 support\n");
11440             }
11441         }
11442     }
11443     else skip("No ps_1_1 support\n");
11444
11445     texop_test(device_ptr);
11446     texop_range_test(device_ptr);
11447     alphareplicate_test(device_ptr);
11448     dp3_alpha_test(device_ptr);
11449     depth_buffer_test(device_ptr);
11450     shadow_test(device_ptr);
11451
11452 cleanup:
11453     if(device_ptr) {
11454         D3DPRESENT_PARAMETERS present_parameters;
11455         IDirect3DSwapChain9 *swapchain;
11456         ULONG ref;
11457
11458         IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
11459         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
11460         IDirect3DSwapChain9_Release(swapchain);
11461         ref = IDirect3DDevice9_Release(device_ptr);
11462         ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
11463         DestroyWindow(present_parameters.hDeviceWindow);
11464     }
11465 }