user32/tests: Fix some window test failures on various Windows platforms.
[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_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
47     return ret;
48 }
49
50 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
51 {
52     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
53     c1 >>= 8; c2 >>= 8;
54     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
55     c1 >>= 8; c2 >>= 8;
56     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
57     c1 >>= 8; c2 >>= 8;
58     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
59     return TRUE;
60 }
61
62 /* Locks a given surface and returns the color at (x,y).  It's the caller's
63  * responsibility to only pass in lockable surfaces and valid x,y coordinates */
64 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
65 {
66     DWORD color;
67     HRESULT hr;
68     D3DSURFACE_DESC desc;
69     RECT rectToLock = {x, y, x+1, y+1};
70     D3DLOCKED_RECT lockedRect;
71
72     hr = IDirect3DSurface9_GetDesc(surface, &desc);
73     if(FAILED(hr))  /* This is not a test */
74     {
75         trace("Can't get the surface description, hr=%08x\n", hr);
76         return 0xdeadbeef;
77     }
78
79     hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
80     if(FAILED(hr))  /* This is not a test */
81     {
82         trace("Can't lock the surface, hr=%08x\n", hr);
83         return 0xdeadbeef;
84     }
85     switch(desc.Format) {
86         case D3DFMT_A8R8G8B8:
87         {
88             color = ((DWORD *) lockedRect.pBits)[0] & 0xffffffff;
89             break;
90         }
91         default:
92             trace("Error: unknown surface format: %d\n", desc.Format);
93             color = 0xdeadbeef;
94             break;
95     }
96     hr = IDirect3DSurface9_UnlockRect(surface);
97     if(FAILED(hr))
98     {
99         trace("Can't unlock the surface, hr=%08x\n", hr);
100     }
101     return color;
102 }
103
104 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
105 {
106     DWORD ret;
107     IDirect3DSurface9 *surf;
108     HRESULT hr;
109     D3DLOCKED_RECT lockedRect;
110     RECT rectToLock = {x, y, x+1, y+1};
111
112     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
113     if(FAILED(hr) || !surf )  /* This is not a test */
114     {
115         trace("Can't create an offscreen plain surface to read the render target data, hr=%08x\n", hr);
116         return 0xdeadbeef;
117     }
118
119     hr = IDirect3DDevice9_GetFrontBufferData(device, 0, surf);
120     if(FAILED(hr))
121     {
122         trace("Can't read the front buffer data, hr=%08x\n", hr);
123         ret = 0xdeadbeed;
124         goto out;
125     }
126
127     hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
128     if(FAILED(hr))
129     {
130         trace("Can't lock the offscreen surface, hr=%08x\n", hr);
131         ret = 0xdeadbeec;
132         goto out;
133     }
134
135     /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
136      * really important for these tests
137      */
138     ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
139     hr = IDirect3DSurface9_UnlockRect(surf);
140     if(FAILED(hr))
141     {
142         trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
143     }
144
145 out:
146     if(surf) IDirect3DSurface9_Release(surf);
147     return ret;
148 }
149
150 static IDirect3DDevice9 *init_d3d9(void)
151 {
152     IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
153     IDirect3D9 *d3d9_ptr = 0;
154     IDirect3DDevice9 *device_ptr = 0;
155     D3DPRESENT_PARAMETERS present_parameters;
156     HRESULT hr;
157     D3DADAPTER_IDENTIFIER9 identifier;
158
159     d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
160     ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
161     if (!d3d9_create) return NULL;
162
163     d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
164     if (!d3d9_ptr)
165     {
166         skip("could not create D3D9\n");
167         return NULL;
168     }
169
170     ZeroMemory(&present_parameters, sizeof(present_parameters));
171     present_parameters.Windowed = FALSE;
172     present_parameters.hDeviceWindow = create_window();
173     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
174     present_parameters.BackBufferWidth = 640;
175     present_parameters.BackBufferHeight = 480;
176     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
177     present_parameters.EnableAutoDepthStencil = TRUE;
178     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
179
180     memset(&identifier, 0, sizeof(identifier));
181     hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
182     ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
183     trace("Driver string: \"%s\"\n", identifier.Driver);
184     trace("Description string: \"%s\"\n", identifier.Description);
185     trace("Device name string: \"%s\"\n", identifier.DeviceName);
186     trace("Driver version %d.%d.%d.%d\n",
187           HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
188           HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
189
190     hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
191     if(FAILED(hr)) {
192         present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
193         hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
194         if(FAILED(hr)) {
195             hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
196         }
197     }
198     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %08x\n", hr);
199
200     return device_ptr;
201 }
202
203 struct vertex
204 {
205     float x, y, z;
206     DWORD diffuse;
207 };
208
209 struct tvertex
210 {
211     float x, y, z, rhw;
212     DWORD diffuse;
213 };
214
215 struct nvertex
216 {
217     float x, y, z;
218     float nx, ny, nz;
219     DWORD diffuse;
220 };
221
222 static void lighting_test(IDirect3DDevice9 *device)
223 {
224     HRESULT hr;
225     DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
226     DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
227     DWORD color;
228     D3DMATERIAL9 material, old_material;
229     DWORD cop, carg;
230
231     float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
232                       0.0f, 1.0f, 0.0f, 0.0f,
233                       0.0f, 0.0f, 1.0f, 0.0f,
234                       0.0f, 0.0f, 0.0f, 1.0f };
235
236     struct vertex unlitquad[] =
237     {
238         {-1.0f, -1.0f,   0.1f,                          0xffff0000},
239         {-1.0f,  0.0f,   0.1f,                          0xffff0000},
240         { 0.0f,  0.0f,   0.1f,                          0xffff0000},
241         { 0.0f, -1.0f,   0.1f,                          0xffff0000},
242     };
243     struct vertex litquad[] =
244     {
245         {-1.0f,  0.0f,   0.1f,                          0xff00ff00},
246         {-1.0f,  1.0f,   0.1f,                          0xff00ff00},
247         { 0.0f,  1.0f,   0.1f,                          0xff00ff00},
248         { 0.0f,  0.0f,   0.1f,                          0xff00ff00},
249     };
250     struct nvertex unlitnquad[] =
251     {
252         { 0.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
253         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
254         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
255         { 1.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
256     };
257     struct nvertex litnquad[] =
258     {
259         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
260         { 0.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
261         { 1.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
262         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
263     };
264     WORD Indices[] = {0, 1, 2, 2, 3, 0};
265
266     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
267     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
268
269     /* Setup some states that may cause issues */
270     hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
271     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
272     hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
273     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
274     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
275     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
276     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
277     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
278     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
279     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
280     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
281     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
282     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
283     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
284     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
285     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
286     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
287     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
288     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
289     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
290     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
291     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
292     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
293     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
294
295     hr = IDirect3DDevice9_SetFVF(device, 0);
296     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
297
298     hr = IDirect3DDevice9_SetFVF(device, fvf);
299     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
300
301     hr = IDirect3DDevice9_BeginScene(device);
302     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
303     if(hr == D3D_OK)
304     {
305         /* No lights are defined... That means, lit vertices should be entirely black */
306         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
307         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
308         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
309                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
310         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
311
312         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
313         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
314         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
315                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
316         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
317
318         hr = IDirect3DDevice9_SetFVF(device, nfvf);
319         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
320
321         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
322         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
323         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
324                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
325         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
326
327         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
328         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
329         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
330                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
331         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
332
333         IDirect3DDevice9_EndScene(device);
334         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
335     }
336
337     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
338
339     color = getPixelColor(device, 160, 360); /* lower left quad - unlit without normals */
340     ok(color == 0x00ff0000, "Unlit quad without normals has color %08x\n", color);
341     color = getPixelColor(device, 160, 120); /* upper left quad - lit without normals */
342     ok(color == 0x00000000, "Lit quad without normals has color %08x\n", color);
343     color = getPixelColor(device, 480, 360); /* lower left quad - unlit with normals */
344     ok(color == 0x000000ff, "Unlit quad with normals has color %08x\n", color);
345     color = getPixelColor(device, 480, 120); /* upper left quad - lit with normals */
346     ok(color == 0x00000000, "Lit quad with normals has color %08x\n", color);
347
348     hr = IDirect3DDevice9_GetMaterial(device, &old_material);
349     ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
350     memset(&material, 0, sizeof(material));
351     material.Diffuse.r = 0.0;
352     material.Diffuse.g = 0.0;
353     material.Diffuse.b = 0.0;
354     material.Diffuse.a = 1.0;
355     material.Ambient.r = 0.0;
356     material.Ambient.g = 0.0;
357     material.Ambient.b = 0.0;
358     material.Ambient.a = 0.0;
359     material.Specular.r = 0.0;
360     material.Specular.g = 0.0;
361     material.Specular.b = 0.0;
362     material.Specular.a = 0.0;
363     material.Emissive.r = 0.0;
364     material.Emissive.g = 0.0;
365     material.Emissive.b = 0.0;
366     material.Emissive.a = 0.0;
367     material.Power = 0.0;
368     IDirect3DDevice9_SetMaterial(device, &material);
369     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
370
371     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
372     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
373     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
374     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
375
376     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
377     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
378     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
379     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
380     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
381     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
382     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
383     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
384
385     hr = IDirect3DDevice9_BeginScene(device);
386     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
387     if(SUCCEEDED(hr)) {
388         struct vertex lighting_test[] = {
389             {-1.0,   -1.0,   0.1,    0x8000ff00},
390             { 1.0,   -1.0,   0.1,    0x80000000},
391             {-1.0,    1.0,   0.1,    0x8000ff00},
392             { 1.0,    1.0,   0.1,    0x80000000}
393         };
394         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
395         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
396         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
397         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
398
399         hr = IDirect3DDevice9_EndScene(device);
400         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
401     }
402
403     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
404     color = getPixelColor(device, 320, 240);
405     ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
406
407     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
408     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
409     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
410     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
411     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
412     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
413     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
414     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
415     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
416     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
417     hr = IDirect3DDevice9_SetMaterial(device, &old_material);
418     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
419 }
420
421 static void clear_test(IDirect3DDevice9 *device)
422 {
423     /* Tests the correctness of clearing parameters */
424     HRESULT hr;
425     D3DRECT rect[2];
426     D3DRECT rect_negneg;
427     DWORD color;
428     D3DVIEWPORT9 old_vp, vp;
429     RECT scissor;
430     DWORD oldColorWrite;
431     BOOL invalid_clear_failed = FALSE;
432
433     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
434     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
435
436     /* Positive x, negative y */
437     rect[0].x1 = 0;
438     rect[0].y1 = 480;
439     rect[0].x2 = 320;
440     rect[0].y2 = 240;
441
442     /* Positive x, positive y */
443     rect[1].x1 = 0;
444     rect[1].y1 = 0;
445     rect[1].x2 = 320;
446     rect[1].y2 = 240;
447     /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
448      * returns D3D_OK, but ignores the rectangle silently
449      */
450     hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
451     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
452     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
453
454     /* negative x, negative y */
455     rect_negneg.x1 = 640;
456     rect_negneg.y1 = 240;
457     rect_negneg.x2 = 320;
458     rect_negneg.y2 = 0;
459     hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
460     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
461     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
462
463     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
464
465     color = getPixelColor(device, 160, 360); /* lower left quad */
466     ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
467     color = getPixelColor(device, 160, 120); /* upper left quad */
468     if(invalid_clear_failed) {
469         /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
470         ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
471     } else {
472         /* If the negative rectangle was dropped silently, the correct ones are cleared */
473         ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
474     }
475     color = getPixelColor(device, 480, 360); /* lower right quad  */
476     ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
477     color = getPixelColor(device, 480, 120); /* upper right quad */
478     ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
479
480     /* Test how the viewport affects clears */
481     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
482     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
483     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
484     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
485
486     vp.X = 160;
487     vp.Y = 120;
488     vp.Width = 160;
489     vp.Height = 120;
490     vp.MinZ = 0.0;
491     vp.MaxZ = 1.0;
492     hr = IDirect3DDevice9_SetViewport(device, &vp);
493     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
494     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
495     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
496
497     vp.X = 320;
498     vp.Y = 240;
499     vp.Width = 320;
500     vp.Height = 240;
501     vp.MinZ = 0.0;
502     vp.MaxZ = 1.0;
503     hr = IDirect3DDevice9_SetViewport(device, &vp);
504     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
505     rect[0].x1 = 160;
506     rect[0].y1 = 120;
507     rect[0].x2 = 480;
508     rect[0].y2 = 360;
509     hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
510     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
511
512     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
513     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
514
515     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
516     color = getPixelColor(device, 158, 118);
517     ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
518     color = getPixelColor(device, 162, 118);
519     ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
520     color = getPixelColor(device, 158, 122);
521     ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
522     color = getPixelColor(device, 162, 122);
523     ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
524
525     color = getPixelColor(device, 318, 238);
526     ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
527     color = getPixelColor(device, 322, 238);
528     ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
529     color = getPixelColor(device, 318, 242);
530     ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
531     color = getPixelColor(device, 322, 242);
532     ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
533
534     color = getPixelColor(device, 478, 358);
535     ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
536     color = getPixelColor(device, 482, 358);
537     ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
538     color = getPixelColor(device, 478, 362);
539     ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
540     color = getPixelColor(device, 482, 362);
541     ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
542
543     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
544     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
545
546     scissor.left = 160;
547     scissor.right = 480;
548     scissor.top = 120;
549     scissor.bottom = 360;
550     hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
551     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
552     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
553     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
554
555     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
556     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
557     hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
558     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
559
560     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
561     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
562
563     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
564     color = getPixelColor(device, 158, 118);
565     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
566     color = getPixelColor(device, 162, 118);
567     ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
568     color = getPixelColor(device, 158, 122);
569     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
570     color = getPixelColor(device, 162, 122);
571     ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
572
573     color = getPixelColor(device, 158, 358);
574     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
575     color = getPixelColor(device, 162, 358);
576     ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
577     color = getPixelColor(device, 158, 358);
578     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
579     color = getPixelColor(device, 162, 362);
580     ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
581
582     color = getPixelColor(device, 478, 118);
583     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
584     color = getPixelColor(device, 478, 122);
585     ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
586     color = getPixelColor(device, 482, 122);
587     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
588     color = getPixelColor(device, 482, 358);
589     ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
590
591     color = getPixelColor(device, 478, 358);
592     ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
593     color = getPixelColor(device, 478, 362);
594     ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
595     color = getPixelColor(device, 482, 358);
596     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
597     color = getPixelColor(device, 482, 362);
598     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
599
600     color = getPixelColor(device, 318, 238);
601     ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
602     color = getPixelColor(device, 318, 242);
603     ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
604     color = getPixelColor(device, 322, 238);
605     ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
606     color = getPixelColor(device, 322, 242);
607     ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
608
609     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
610     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
611     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
612     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
613
614     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
615     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
616
617     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
618     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
619
620     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
621
622     /* Colorwriteenable does not affect the clear */
623     color = getPixelColor(device, 320, 240);
624     ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
625 }
626
627 typedef struct {
628     float in[4];
629     DWORD out;
630 } test_data_t;
631
632 /*
633  *  c7      mova    ARGB            mov     ARGB
634  * -2.4     -2      0x00ffff00      -3      0x00ff0000
635  * -1.6     -2      0x00ffff00      -2      0x00ffff00
636  * -0.4      0      0x0000ffff      -1      0x0000ff00
637  *  0.4      0      0x0000ffff       0      0x0000ffff
638  *  1.6      2      0x00ff00ff       1      0x000000ff
639  *  2.4      2      0x00ff00ff       2      0x00ff00ff
640  */
641 static void test_mova(IDirect3DDevice9 *device)
642 {
643     static const DWORD mova_test[] = {
644         0xfffe0200,                                                             /* vs_2_0                       */
645         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
646         0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
647         0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
648         0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
649         0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
650         0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
651         0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
652         0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
653         0x0200002e, 0xb0010000, 0xa0000007,                                     /* mova a0.x, c7.x              */
654         0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000,                         /* mov oD0, c[a0.x + 3]         */
655         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
656         0x0000ffff                                                              /* END                          */
657     };
658     static const DWORD mov_test[] = {
659         0xfffe0101,                                                             /* vs_1_1                       */
660         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
661         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
662         0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
663         0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
664         0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
665         0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
666         0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
667         0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
668         0x00000001, 0xb0010000, 0xa0000007,                                     /* mov a0.x, c7.x               */
669         0x00000001, 0xd00f0000, 0xa0e42003,                                     /* mov oD0, c[a0.x + 3]         */
670         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
671         0x0000ffff                                                              /* END                          */
672     };
673
674     static const test_data_t test_data[2][6] = {
675         {
676             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
677             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
678             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
679             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
680             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
681             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
682         },
683         {
684             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
685             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
686             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
687             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
688             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
689             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
690         }
691     };
692
693     static const float quad[][3] = {
694         {-1.0f, -1.0f, 0.0f},
695         {-1.0f,  1.0f, 0.0f},
696         { 1.0f, -1.0f, 0.0f},
697         { 1.0f,  1.0f, 0.0f},
698     };
699
700     static const D3DVERTEXELEMENT9 decl_elements[] = {
701         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
702         D3DDECL_END()
703     };
704
705     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
706     IDirect3DVertexShader9 *mova_shader = NULL;
707     IDirect3DVertexShader9 *mov_shader = NULL;
708     HRESULT hr;
709     UINT i, j;
710
711     hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
712     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
713     hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
714     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
715     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
716     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
717     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
718     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
719
720     hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
721     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
722     for(j = 0; j < 2; ++j)
723     {
724         for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
725         {
726             DWORD color;
727
728             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
729             ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
730
731             hr = IDirect3DDevice9_BeginScene(device);
732             ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
733
734             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
735             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
736
737             hr = IDirect3DDevice9_EndScene(device);
738             ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
739
740             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
741             ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
742
743             color = getPixelColor(device, 320, 240);
744             ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
745                test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
746
747             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
748             ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
749         }
750         hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
751         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
752     }
753
754     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
755     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
756
757     IDirect3DVertexDeclaration9_Release(vertex_declaration);
758     IDirect3DVertexShader9_Release(mova_shader);
759     IDirect3DVertexShader9_Release(mov_shader);
760 }
761
762 struct sVertex {
763     float x, y, z;
764     DWORD diffuse;
765     DWORD specular;
766 };
767
768 struct sVertexT {
769     float x, y, z, rhw;
770     DWORD diffuse;
771     DWORD specular;
772 };
773
774 static void fog_test(IDirect3DDevice9 *device)
775 {
776     HRESULT hr;
777     DWORD color;
778     BYTE r, g, b;
779     float start = 0.0f, end = 1.0f;
780     D3DCAPS9 caps;
781     int i;
782
783     /* Gets full z based fog with linear fog, no fog with specular color */
784     struct sVertex unstransformed_1[] = {
785         {-1,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
786         {-1,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
787         { 0,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
788         { 0,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
789     };
790     /* Ok, I am too lazy to deal with transform matrices */
791     struct sVertex unstransformed_2[] = {
792         {-1,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
793         {-1,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
794         { 0,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
795         { 0,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
796     };
797     /* Untransformed ones. Give them a different diffuse color to make the test look
798      * nicer. It also makes making sure that they are drawn correctly easier.
799      */
800     struct sVertexT transformed_1[] = {
801         {320,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
802         {640,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
803         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
804         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
805     };
806     struct sVertexT transformed_2[] = {
807         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
808         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
809         {640,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
810         {320,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
811     };
812     struct vertex rev_fog_quads[] = {
813        {-1.0,   -1.0,   0.1,    0x000000ff},
814        {-1.0,    0.0,   0.1,    0x000000ff},
815        { 0.0,    0.0,   0.1,    0x000000ff},
816        { 0.0,   -1.0,   0.1,    0x000000ff},
817
818        { 0.0,   -1.0,   0.9,    0x000000ff},
819        { 0.0,    0.0,   0.9,    0x000000ff},
820        { 1.0,    0.0,   0.9,    0x000000ff},
821        { 1.0,   -1.0,   0.9,    0x000000ff},
822
823        { 0.0,    0.0,   0.4,    0x000000ff},
824        { 0.0,    1.0,   0.4,    0x000000ff},
825        { 1.0,    1.0,   0.4,    0x000000ff},
826        { 1.0,    0.0,   0.4,    0x000000ff},
827
828        {-1.0,    0.0,   0.7,    0x000000ff},
829        {-1.0,    1.0,   0.7,    0x000000ff},
830        { 0.0,    1.0,   0.7,    0x000000ff},
831        { 0.0,    0.0,   0.7,    0x000000ff},
832     };
833     WORD Indices[] = {0, 1, 2, 2, 3, 0};
834
835     memset(&caps, 0, sizeof(caps));
836     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
837     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
838     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
839     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
840
841     /* Setup initial states: No lighting, fog on, fog color */
842     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
843     ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
844     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
845     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
846     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
847     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
848
849     /* First test: Both table fog and vertex fog off */
850     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
851     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
852     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
853     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
854
855     /* Start = 0, end = 1. Should be default, but set them */
856     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
857     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
858     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
859     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
860
861     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
862     {
863         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
864         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
865         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
866         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
867                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
868                                                      sizeof(unstransformed_1[0]));
869         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
870
871         /* That makes it use the Z value */
872         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
873         ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
874         /* Untransformed, vertex fog != none (or table fog != none):
875          * Use the Z value as input into the equation
876          */
877         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
878                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
879                                                      sizeof(unstransformed_1[0]));
880         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
881
882         /* transformed verts */
883         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
884         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
885         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
886         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
887                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
888                                                      sizeof(transformed_1[0]));
889         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
890
891         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
892         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
893         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
894          * equation
895          */
896         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
897                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
898                                                      sizeof(transformed_2[0]));
899
900         hr = IDirect3DDevice9_EndScene(device);
901         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
902     }
903     else
904     {
905         ok(FALSE, "BeginScene failed\n");
906     }
907
908     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
909     color = getPixelColor(device, 160, 360);
910     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
911     color = getPixelColor(device, 160, 120);
912     ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with linear vertex fog has color %08x\n", color);
913     color = getPixelColor(device, 480, 120);
914     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
915     if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
916     {
917         color = getPixelColor(device, 480, 360);
918         ok(color == 0x0000FF00 || color == 0x0000FE00, "Transformed vertex with linear table fog has color %08x\n", color);
919     }
920     else
921     {
922         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
923          * The settings above result in no fogging with vertex fog
924          */
925         color = getPixelColor(device, 480, 120);
926         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
927         trace("Info: Table fog not supported by this device\n");
928     }
929
930     /* Now test the special case fogstart == fogend */
931     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
932     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
933
934     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
935     {
936         start = 512;
937         end = 512;
938         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
939         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
940         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
941         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
942
943         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
944         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
945         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
946         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
947         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
948         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
949
950         /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
951          * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
952          * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
953          * The third transformed quad remains unfogged because the fogcoords are read from the specular
954          * color and has fixed fogstart and fogend.
955          */
956         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
957                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
958                 sizeof(unstransformed_1[0]));
959         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
960         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
961                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
962                 sizeof(unstransformed_1[0]));
963         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
964
965         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
966         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
967         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
968         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
969                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
970                 sizeof(transformed_1[0]));
971         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
972
973         hr = IDirect3DDevice9_EndScene(device);
974         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
975     }
976     else
977     {
978         ok(FALSE, "BeginScene failed\n");
979     }
980     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
981     color = getPixelColor(device, 160, 360);
982     ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
983     color = getPixelColor(device, 160, 120);
984     ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
985     color = getPixelColor(device, 480, 120);
986     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
987
988     /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
989      * but without shaders it seems to work everywhere
990      */
991     end = 0.2;
992     start = 0.8;
993     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
994     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
995     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
996     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
997     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
998     ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
999
1000     /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1001      * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1002      * so skip this for now
1003      */
1004     for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1005         const char *mode = (i ? "table" : "vertex");
1006         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1007         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1008         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1009         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1010         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1011         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1012         hr = IDirect3DDevice9_BeginScene(device);
1013         ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1014         if(SUCCEEDED(hr)) {
1015             WORD Indices2[] = { 0,  1,  2,  2,  3, 0,
1016                                 4,  5,  6,  6,  7, 4,
1017                                 8,  9, 10, 10, 11, 8,
1018                             12, 13, 14, 14, 15, 12};
1019
1020             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1021                     16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1022                     sizeof(rev_fog_quads[0]));
1023
1024             hr = IDirect3DDevice9_EndScene(device);
1025             ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1026         }
1027         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1028         color = getPixelColor(device, 160, 360);
1029         ok(color == 0x0000FF00 || color == 0x0000FE00, "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00\n", mode, color);
1030
1031         color = getPixelColor(device, 160, 120);
1032         r = (color & 0x00ff0000) >> 16;
1033         g = (color & 0x0000ff00) >>  8;
1034         b = (color & 0x000000ff);
1035         ok(r == 0x00 && g >= 0x29 && g <= 0x2d && b >= 0xd2 && b <= 0xd6,
1036            "Reversed %s fog: z=0.7 has color 0x%08x, expected\n", mode, color);
1037
1038         color = getPixelColor(device, 480, 120);
1039         r = (color & 0x00ff0000) >> 16;
1040         g = (color & 0x0000ff00) >>  8;
1041         b = (color & 0x000000ff);
1042         ok(r == 0x00 && g >= 0xa8 && g <= 0xac && b >= 0x53 && b <= 0x57,
1043            "Reversed %s fog: z=0.4 has color 0x%08x, expected\n", mode, color);
1044
1045         color = getPixelColor(device, 480, 360);
1046         ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1047
1048         if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1049             skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1050             break;
1051         }
1052     }
1053     /* Turn off the fog master switch to avoid confusing other tests */
1054     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1055     ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1056     start = 0.0;
1057     end = 1.0;
1058     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1059     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1060     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1061     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1062     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1063     ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1064     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1065     ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1066 }
1067
1068 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1069  * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1070  * regardless of the actual addressing mode set. */
1071 static void test_cube_wrap(IDirect3DDevice9 *device)
1072 {
1073     static const float quad[][6] = {
1074         {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1075         {-1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1076         { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1077         { 1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1078     };
1079
1080     static const D3DVERTEXELEMENT9 decl_elements[] = {
1081         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1082         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1083         D3DDECL_END()
1084     };
1085
1086     static const struct {
1087         D3DTEXTUREADDRESS mode;
1088         const char *name;
1089     } address_modes[] = {
1090         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1091         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1092         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1093         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1094         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1095     };
1096
1097     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1098     IDirect3DCubeTexture9 *texture = NULL;
1099     IDirect3DSurface9 *surface = NULL;
1100     D3DLOCKED_RECT locked_rect;
1101     HRESULT hr;
1102     UINT x;
1103     INT y, face;
1104
1105     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1106     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1107     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1108     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1109
1110     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1111             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1112     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1113
1114     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1115     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1116
1117     for (y = 0; y < 128; ++y)
1118     {
1119         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1120         for (x = 0; x < 64; ++x)
1121         {
1122             *ptr++ = 0xffff0000;
1123         }
1124         for (x = 64; x < 128; ++x)
1125         {
1126             *ptr++ = 0xff0000ff;
1127         }
1128     }
1129
1130     hr = IDirect3DSurface9_UnlockRect(surface);
1131     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1132
1133     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1134             D3DPOOL_DEFAULT, &texture, NULL);
1135     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1136
1137     /* Create cube faces */
1138     for (face = 0; face < 6; ++face)
1139     {
1140         IDirect3DSurface9 *face_surface = NULL;
1141
1142         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1143         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1144
1145         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1146         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1147
1148         IDirect3DSurface9_Release(face_surface);
1149     }
1150
1151     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1152     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1153
1154     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1155     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1156     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1157     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1158     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1159     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1160
1161     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1162     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1163
1164     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1165     {
1166         DWORD color;
1167
1168         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1169         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1170         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1171         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1172
1173         hr = IDirect3DDevice9_BeginScene(device);
1174         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1175
1176         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1177         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1178
1179         hr = IDirect3DDevice9_EndScene(device);
1180         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1181
1182         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1183         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1184
1185         /* Due to the nature of this test, we sample essentially at the edge
1186          * between two faces. Because of this it's undefined from which face
1187          * the driver will sample. Fortunately that's not important for this
1188          * test, since all we care about is that it doesn't sample from the
1189          * other side of the surface or from the border. */
1190         color = getPixelColor(device, 320, 240);
1191         ok(color == 0x00ff0000 || color == 0x000000ff,
1192                 "Got color 0x%08x for addressing mode %s, expected 0x00ff0000 or 0x000000ff.\n",
1193                 color, address_modes[x].name);
1194
1195         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1196         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1197     }
1198
1199     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1200     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1201
1202     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1203     IDirect3DCubeTexture9_Release(texture);
1204     IDirect3DSurface9_Release(surface);
1205 }
1206
1207 static void offscreen_test(IDirect3DDevice9 *device)
1208 {
1209     HRESULT hr;
1210     IDirect3DTexture9 *offscreenTexture = NULL;
1211     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1212     DWORD color;
1213
1214     static const float quad[][5] = {
1215         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1216         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1217         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1218         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1219     };
1220
1221     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1222     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1223
1224     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1225     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1226     if(!offscreenTexture) {
1227         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1228         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1229         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1230         if(!offscreenTexture) {
1231             skip("Cannot create an offscreen render target\n");
1232             goto out;
1233         }
1234     }
1235
1236     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1237     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1238     if(!backbuffer) {
1239         goto out;
1240     }
1241
1242     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1243     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1244     if(!offscreen) {
1245         goto out;
1246     }
1247
1248     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1249     ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1250
1251     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1252     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1253     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1254     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1255     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1256     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1257     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1258     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1259     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1260     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1261
1262     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1263         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1264         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1265         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1266         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1267
1268         /* Draw without textures - Should result in a white quad */
1269         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1270         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1271
1272         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1273         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1274         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1275         ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1276
1277         /* This time with the texture */
1278         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1279         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1280
1281         IDirect3DDevice9_EndScene(device);
1282     }
1283
1284     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1285
1286     /* Center quad - should be white */
1287     color = getPixelColor(device, 320, 240);
1288     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1289     /* Some quad in the cleared part of the texture */
1290     color = getPixelColor(device, 170, 240);
1291     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1292     /* Part of the originally cleared back buffer */
1293     color = getPixelColor(device, 10, 10);
1294     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1295     if(0) {
1296         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1297          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1298          * the offscreen rendering mode this test would succeed or fail
1299          */
1300         color = getPixelColor(device, 10, 470);
1301         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1302     }
1303
1304 out:
1305     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1306
1307     /* restore things */
1308     if(backbuffer) {
1309         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1310         IDirect3DSurface9_Release(backbuffer);
1311     }
1312     if(offscreenTexture) {
1313         IDirect3DTexture9_Release(offscreenTexture);
1314     }
1315     if(offscreen) {
1316         IDirect3DSurface9_Release(offscreen);
1317     }
1318 }
1319
1320 /* This test tests fog in combination with shaders.
1321  * What's tested: linear fog (vertex and table) with pixel shader
1322  *                linear table fog with non foggy vertex shader
1323  *                vertex fog with foggy vertex shader
1324  * What's not tested: non linear fog with shader
1325  *                    table fog with foggy vertex shader
1326  */
1327 static void fog_with_shader_test(IDirect3DDevice9 *device)
1328 {
1329     HRESULT hr;
1330     DWORD color;
1331     union {
1332         float f;
1333         DWORD i;
1334     } start, end;
1335     unsigned int i, j;
1336
1337     /* basic vertex shader without fog computation ("non foggy") */
1338     static const DWORD vertex_shader_code1[] = {
1339         0xfffe0101,                                                             /* vs_1_1                       */
1340         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1341         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1342         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1343         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1344         0x0000ffff
1345     };
1346     /* basic vertex shader with reversed fog computation ("foggy") */
1347     static const DWORD vertex_shader_code2[] = {
1348         0xfffe0101,                                                             /* vs_1_1                        */
1349         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1350         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1351         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1352         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1353         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1354         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1355         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1356         0x0000ffff
1357     };
1358     /* basic pixel shader */
1359     static const DWORD pixel_shader_code[] = {
1360         0xffff0101,                                                             /* ps_1_1     */
1361         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, vo */
1362         0x0000ffff
1363     };
1364
1365     static struct vertex quad[] = {
1366         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1367         {-1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1368         { 1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1369         { 1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1370     };
1371
1372     static const D3DVERTEXELEMENT9 decl_elements[] = {
1373         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1374         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1375         D3DDECL_END()
1376     };
1377
1378     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1379     IDirect3DVertexShader9      *vertex_shader[3]   = {NULL, NULL, NULL};
1380     IDirect3DPixelShader9       *pixel_shader[2]    = {NULL, NULL};
1381
1382     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1383     static const struct test_data_t {
1384         int vshader;
1385         int pshader;
1386         D3DFOGMODE vfog;
1387         D3DFOGMODE tfog;
1388         unsigned int color[11];
1389     } test_data[] = {
1390         /* only pixel shader: */
1391         {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1392         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1393         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1394         {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1395         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1396         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1397         {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1398         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1399         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1400         {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1401         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1402         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1403         {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1404         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1405         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1406
1407         /* vertex shader */
1408         {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1409         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1410          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1411         {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1412         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1413         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1414         {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1415         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1416         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1417
1418         {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1419         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1420         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1421         {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1422         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1423         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1424
1425         /* vertex shader and pixel shader */
1426         {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1427         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1428         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1429         {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1430         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1431         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1432         {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1433         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1434         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1435
1436         {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1437         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1438         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1439
1440
1441 #if 0  /* FIXME: these fail on GeForce 8500 */
1442         /* foggy vertex shader */
1443         {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1444         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1445          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1446         {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1447         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1448          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1449         {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1450         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1451          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1452         {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1453         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1454          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1455 #endif
1456
1457         /* foggy vertex shader and pixel shader */
1458         {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1459         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1460          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1461         {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1462         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1463          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1464         {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1465         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1466          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1467         {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1468         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1469          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1470
1471     };
1472
1473     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1474     start.f=0.1f;
1475     end.f=0.9f;
1476
1477     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1478     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1479     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1480     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1481     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1482     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1483     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1484     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1485
1486     /* Setup initial states: No lighting, fog on, fog color */
1487     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1488     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1489     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1490     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1491     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1492     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1493     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1494     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1495
1496     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1497     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1498     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1499     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1500
1501     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1502     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1503     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1504     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1505     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1506
1507     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1508     {
1509         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1510         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1511         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1512         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1513         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1514         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1515         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1516         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1517
1518         for(j=0; j < 11; j++)
1519         {
1520             /* Don't use the whole zrange to prevent rounding errors */
1521             quad[0].z = 0.001f + (float)j / 10.02f;
1522             quad[1].z = 0.001f + (float)j / 10.02f;
1523             quad[2].z = 0.001f + (float)j / 10.02f;
1524             quad[3].z = 0.001f + (float)j / 10.02f;
1525
1526             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1527             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1528
1529             hr = IDirect3DDevice9_BeginScene(device);
1530             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1531
1532             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1533             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1534
1535             hr = IDirect3DDevice9_EndScene(device);
1536             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1537
1538             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1539
1540             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1541             color = getPixelColor(device, 128, 240);
1542             if(test_data[i].vshader == 1 && test_data[i].tfog == 0 && color != test_data[i].color[j]) {
1543                 todo_wine ok(color_match(color, test_data[i].color[j], 13),
1544                              "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%(todo)\n",
1545                              test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1546             } else {
1547                 ok(color_match(color, test_data[i].color[j], 13),
1548                    "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1549                    test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1550             }
1551         }
1552     }
1553
1554     /* reset states */
1555     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1556     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1557     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1558     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1559     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1560     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1561     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1562     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1563
1564     IDirect3DVertexShader9_Release(vertex_shader[1]);
1565     IDirect3DVertexShader9_Release(vertex_shader[2]);
1566     IDirect3DPixelShader9_Release(pixel_shader[1]);
1567     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1568 }
1569
1570 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1571     unsigned int i, x, y;
1572     HRESULT hr;
1573     IDirect3DTexture9 *texture[2] = {NULL, NULL};
1574     D3DLOCKED_RECT locked_rect;
1575
1576     /* Generate the textures */
1577     for(i=0; i<2; i++)
1578     {
1579         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1580                                             D3DPOOL_MANAGED, &texture[i], NULL);
1581         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1582
1583         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1584         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1585         for (y = 0; y < 128; ++y)
1586         {
1587             if(i)
1588             { /* Set up black texture with 2x2 texel white spot in the middle */
1589                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1590                 for (x = 0; x < 128; ++x)
1591                 {
1592                     if(y>62 && y<66 && x>62 && x<66)
1593                         *ptr++ = 0xffffffff;
1594                     else
1595                         *ptr++ = 0xff000000;
1596                 }
1597             }
1598             else
1599             { /* Set up a displacement map which points away from the center parallel to the closest axis.
1600                * (if multiplied with bumpenvmat)
1601               */
1602                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1603                 for (x = 0; x < 128; ++x)
1604                 {
1605                     if(abs(x-64)>abs(y-64))
1606                     {
1607                         if(x < 64)
1608                             *ptr++ = 0xc000;
1609                         else
1610                             *ptr++ = 0x4000;
1611                     }
1612                     else
1613                     {
1614                         if(y < 64)
1615                             *ptr++ = 0x0040;
1616                         else
1617                             *ptr++ = 0x00c0;
1618                     }
1619                 }
1620             }
1621         }
1622         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1623         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1624
1625         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1626         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1627
1628         /* Disable texture filtering */
1629         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1630         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1631         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1632         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1633
1634         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1635         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1636         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1637         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1638     }
1639 }
1640
1641 /* test the behavior of the texbem instruction
1642  * with normal 2D and projective 2D textures
1643  */
1644 static void texbem_test(IDirect3DDevice9 *device)
1645 {
1646     HRESULT hr;
1647     DWORD color;
1648     int i;
1649
1650     static const DWORD pixel_shader_code[] = {
1651         0xffff0101,                         /* ps_1_1*/
1652         0x00000042, 0xb00f0000,             /* tex t0*/
1653         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1654         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1655         0x0000ffff
1656     };
1657     static const DWORD double_texbem_code[] =  {
1658         0xffff0103,                                         /* ps_1_3           */
1659         0x00000042, 0xb00f0000,                             /* tex t0           */
1660         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
1661         0x00000042, 0xb00f0002,                             /* tex t2           */
1662         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
1663         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
1664         0x0000ffff                                          /* end              */
1665     };
1666
1667
1668     static const float quad[][7] = {
1669         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1670         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1671         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1672         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1673     };
1674     static const float quad_proj[][9] = {
1675         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
1676         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
1677         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
1678         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1679     };
1680
1681     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1682         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1683         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1684         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1685         D3DDECL_END()
1686     },{
1687         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1688         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1689         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1690         D3DDECL_END()
1691     } };
1692
1693     /* use asymmetric matrix to test loading */
1694     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1695
1696     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1697     IDirect3DPixelShader9       *pixel_shader       = NULL;
1698     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
1699     D3DLOCKED_RECT locked_rect;
1700
1701     generate_bumpmap_textures(device);
1702
1703     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1704     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1705     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1706     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1707     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1708
1709     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1710     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1711
1712     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1713     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1714
1715     for(i=0; i<2; i++)
1716     {
1717         if(i)
1718         {
1719             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1720             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1721         }
1722
1723         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1724         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1725         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1726         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1727
1728         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1729         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1730         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1731         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1732
1733         hr = IDirect3DDevice9_BeginScene(device);
1734         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1735
1736         if(!i)
1737             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1738         else
1739             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1740         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1741
1742         hr = IDirect3DDevice9_EndScene(device);
1743         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1744
1745         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1746         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1747
1748         color = getPixelColor(device, 320-32, 240);
1749         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1750         color = getPixelColor(device, 320+32, 240);
1751         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1752         color = getPixelColor(device, 320, 240-32);
1753         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1754         color = getPixelColor(device, 320, 240+32);
1755         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1756
1757         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1758         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1759         IDirect3DPixelShader9_Release(pixel_shader);
1760
1761         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1762         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1763         IDirect3DVertexDeclaration9_Release(vertex_declaration);
1764     }
1765
1766     /* clean up */
1767     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1768     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1769
1770     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1771     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1772
1773     for(i=0; i<2; i++)
1774     {
1775         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1776         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1777         IDirect3DTexture9_Release(texture); /* For the GetTexture */
1778         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1779         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1780         IDirect3DTexture9_Release(texture);
1781     }
1782
1783     /* Test double texbem */
1784     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1785     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1786     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1787     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1788     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1789     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1790     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1791     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1792
1793     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1794     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1795     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1796     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1797
1798     hr = IDirect3DTexture9_UnlockRect(texture, 0);
1799     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1800
1801     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1802     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1803     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1804     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1805     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1806     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1807
1808     {
1809         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1810 #define tex  0x00ff0000
1811 #define tex1 0x0000ff00
1812 #define origin 0x000000ff
1813         static const DWORD pixel_data[] = {
1814             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1815             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1816             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1817             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1818             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
1819             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1820             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1821             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1822         };
1823 #undef tex1
1824 #undef tex2
1825 #undef origin
1826
1827         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1828         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1829         for(i = 0; i < 8; i++) {
1830             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1831         }
1832         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1833         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1834     }
1835
1836     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1837     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1838     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1839     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1840     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1841     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1842     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1843     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1844     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1845     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1846     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1847     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1848
1849     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
1850     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
1851     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1852     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1853     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1854     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1855
1856     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
1857     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
1858     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1859     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1860     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1861     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1862
1863     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1864     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1865     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1866     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1867     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1868     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1869     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1870     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1871
1872     hr = IDirect3DDevice9_BeginScene(device);
1873     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1874     if(SUCCEEDED(hr)) {
1875         static const float double_quad[] = {
1876             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1877              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1878             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1879              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1880         };
1881
1882         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
1883         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1884         hr = IDirect3DDevice9_EndScene(device);
1885         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1886     }
1887     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1888     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1889     color = getPixelColor(device, 320, 240);
1890     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1891
1892     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1893     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1894     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
1895     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1896     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
1897     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1898     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
1899     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1900     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1901     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1902
1903     IDirect3DPixelShader9_Release(pixel_shader);
1904     IDirect3DTexture9_Release(texture);
1905     IDirect3DTexture9_Release(texture1);
1906     IDirect3DTexture9_Release(texture2);
1907 }
1908
1909 static void z_range_test(IDirect3DDevice9 *device)
1910 {
1911     const struct vertex quad[] =
1912     {
1913         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
1914         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
1915         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
1916         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
1917     };
1918     const struct vertex quad2[] =
1919     {
1920         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
1921         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
1922         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
1923         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
1924     };
1925
1926     const struct tvertex quad3[] =
1927     {
1928         {    0,   240,   1.1f,  1.0,                    0xffffff00},
1929         {    0,   480,   1.1f,  1.0,                    0xffffff00},
1930         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
1931         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
1932     };
1933     const struct tvertex quad4[] =
1934     {
1935         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
1936         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
1937         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
1938         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
1939     };
1940     HRESULT hr;
1941     DWORD color;
1942     IDirect3DVertexShader9 *shader;
1943     IDirect3DVertexDeclaration9 *decl;
1944     D3DCAPS9 caps;
1945     const DWORD shader_code[] = {
1946         0xfffe0101,                                     /* vs_1_1           */
1947         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
1948         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
1949         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
1950         0x0000ffff                                      /* end              */
1951     };
1952     static const D3DVERTEXELEMENT9 decl_elements[] = {
1953         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1954         D3DDECL_END()
1955     };
1956     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
1957      * then call Present. Then clear the color buffer to make sure it has some defined content
1958      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
1959      * by the depth value.
1960      */
1961     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
1962     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1963     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1964     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1965
1966     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1967     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1968     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1969     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1970     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
1971     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1972     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1973     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1974     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1975     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1976
1977     hr = IDirect3DDevice9_BeginScene(device);
1978     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
1979     if(hr == D3D_OK)
1980     {
1981         /* Test the untransformed vertex path */
1982         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
1983         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
1984         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
1985         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1986         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
1987         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
1988
1989         /* Test the transformed vertex path */
1990         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
1991         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1992
1993         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
1994         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
1995         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1996         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1997         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
1998         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
1999
2000         hr = IDirect3DDevice9_EndScene(device);
2001         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2002     }
2003
2004     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2005     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2006
2007     /* Do not test the exact corner pixels, but go pretty close to them */
2008
2009     /* Clipped because z > 1.0 */
2010     color = getPixelColor(device, 28, 238);
2011     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2012     color = getPixelColor(device, 28, 241);
2013     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2014
2015     /* Not clipped, > z buffer clear value(0.75) */
2016     color = getPixelColor(device, 31, 238);
2017     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2018     color = getPixelColor(device, 31, 241);
2019     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2020     color = getPixelColor(device, 100, 238);
2021     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2022     color = getPixelColor(device, 100, 241);
2023     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2024
2025     /* Not clipped, < z buffer clear value */
2026     color = getPixelColor(device, 104, 238);
2027     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2028     color = getPixelColor(device, 104, 241);
2029     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2030     color = getPixelColor(device, 318, 238);
2031     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2032     color = getPixelColor(device, 318, 241);
2033     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2034
2035     /* Clipped because z < 0.0 */
2036     color = getPixelColor(device, 321, 238);
2037     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2038     color = getPixelColor(device, 321, 241);
2039     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2040
2041     /* Test the shader path */
2042     IDirect3DDevice9_GetDeviceCaps(device, &caps);
2043     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2044         skip("Vertex shaders not supported\n");
2045         goto out;
2046     }
2047     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2048     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2049     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2050     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2051
2052     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2053
2054     IDirect3DDevice9_SetVertexDeclaration(device, decl);
2055     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2056     IDirect3DDevice9_SetVertexShader(device, shader);
2057     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2058
2059     hr = IDirect3DDevice9_BeginScene(device);
2060     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2061     if(hr == D3D_OK)
2062     {
2063         float colorf[] = {1.0, 0.0, 0.0, 1.0};
2064         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2065         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2066         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2067         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2068         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2069         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2070         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2071         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2072         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2073
2074         hr = IDirect3DDevice9_EndScene(device);
2075         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2076     }
2077
2078     IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2079     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2080     IDirect3DDevice9_SetVertexShader(device, NULL);
2081     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2082
2083     IDirect3DVertexDeclaration9_Release(decl);
2084     IDirect3DVertexShader9_Release(shader);
2085
2086     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2087     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2088     /* Z < 1.0 */
2089     color = getPixelColor(device, 28, 238);
2090     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2091
2092     /* 1.0 < z < 0.75 */
2093     color = getPixelColor(device, 31, 238);
2094     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2095     color = getPixelColor(device, 100, 238);
2096     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2097
2098     /* 0.75 < z < 0.0 */
2099     color = getPixelColor(device, 104, 238);
2100     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2101     color = getPixelColor(device, 318, 238);
2102     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2103
2104     /* 0.0 < z */
2105     color = getPixelColor(device, 321, 238);
2106     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2107
2108     out:
2109     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2110     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2111     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2112     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2113     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2114     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2115 }
2116
2117 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2118 {
2119     D3DSURFACE_DESC desc;
2120     D3DLOCKED_RECT l;
2121     HRESULT hr;
2122     unsigned int x, y;
2123     DWORD *mem;
2124
2125     memset(&desc, 0, sizeof(desc));
2126     memset(&l, 0, sizeof(l));
2127     hr = IDirect3DSurface9_GetDesc(surface, &desc);
2128     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2129     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2130     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2131     if(FAILED(hr)) return;
2132
2133     for(y = 0; y < desc.Height; y++)
2134     {
2135         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2136         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2137         {
2138             mem[x] = color;
2139         }
2140     }
2141     hr = IDirect3DSurface9_UnlockRect(surface);
2142     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2143 }
2144
2145 /* This tests a variety of possible StretchRect() situations */
2146 static void stretchrect_test(IDirect3DDevice9 *device)
2147 {
2148     HRESULT hr;
2149     IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL;
2150     IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL;
2151     IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2152     IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2153     IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2154     IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2155     IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2156     IDirect3DSurface9 *orig_rt = NULL;
2157     DWORD color;
2158
2159     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2160     ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2161     if(!orig_rt) {
2162         goto out;
2163     }
2164
2165     /* Create our temporary surfaces in system memory */
2166     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2167     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2168     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2169     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2170
2171     /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2172     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2173     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2174     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2175     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2176     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2177     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2178
2179     /* Create render target surfaces */
2180     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2181     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2182     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2183     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2184     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2185     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2186
2187     /* Create render target textures */
2188     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2189     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2190     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2191     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2192     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2193     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2194     if (tex_rt32) {
2195         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2196         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2197     }
2198     if (tex_rt64) {
2199         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2200         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2201     }
2202     if (tex_rt_dest64) {
2203         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2204         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2205     }
2206
2207     /* Create regular textures in D3DPOOL_DEFAULT */
2208     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2209     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2210     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2211     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2212     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2213     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2214     if (tex32) {
2215         hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2216         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2217     }
2218     if (tex64) {
2219         hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2220         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2221     }
2222     if (tex_dest64) {
2223         hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2224         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2225     }
2226
2227     /*********************************************************************
2228      * Tests for when the source parameter is an offscreen plain surface *
2229      *********************************************************************/
2230
2231     /* Fill the offscreen 64x64 surface with green */
2232     if (surf_offscreen64)
2233         fill_surface(surf_offscreen64, 0xff00ff00);
2234
2235     /* offscreenplain ==> offscreenplain, same size */
2236     if(surf_offscreen64 && surf_offscreen_dest64) {
2237         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2238         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2239
2240         if (hr == D3D_OK) {
2241             color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2242             ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2243         }
2244     }
2245
2246     /* offscreenplain ==> rendertarget texture, same size */
2247     if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2248         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2249         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2250
2251         /* We can't lock rendertarget textures, so copy to our temp surface first */
2252         if (hr == D3D_OK) {
2253             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2254             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2255         }
2256
2257         if (hr == D3D_OK) {
2258             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2259             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2260         }
2261     }
2262
2263     /* offscreenplain ==> rendertarget surface, same size */
2264     if(surf_offscreen64 && surf_rt_dest64) {
2265         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2266         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2267
2268         if (hr == D3D_OK) {
2269             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2270             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2271         }
2272     }
2273
2274     /* offscreenplain ==> texture, same size (should fail) */
2275     if(surf_offscreen64 && surf_tex_dest64) {
2276         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2277         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2278     }
2279
2280     /* Fill the smaller offscreen surface with red */
2281     fill_surface(surf_offscreen32, 0xffff0000);
2282
2283     /* offscreenplain ==> offscreenplain, scaling (should fail) */
2284     if(surf_offscreen32 && surf_offscreen64) {
2285         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2286         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2287     }
2288
2289     /* offscreenplain ==> rendertarget texture, scaling */
2290     if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2291         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2292         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2293
2294         /* We can't lock rendertarget textures, so copy to our temp surface first */
2295         if (hr == D3D_OK) {
2296             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2297             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2298         }
2299
2300         if (hr == D3D_OK) {
2301             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2302             ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2303         }
2304     }
2305
2306     /* offscreenplain ==> rendertarget surface, scaling */
2307     if(surf_offscreen32 && surf_rt_dest64) {
2308         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2309         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2310
2311         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2312         ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2313     }
2314
2315     /* offscreenplain ==> texture, scaling (should fail) */
2316     if(surf_offscreen32 && surf_tex_dest64) {
2317         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2318         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2319     }
2320
2321     /************************************************************
2322      * Tests for when the source parameter is a regular texture *
2323      ************************************************************/
2324
2325     /* Fill the surface of the regular texture with blue */
2326     if (surf_tex64 && surf_temp64) {
2327         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2328         fill_surface(surf_temp64, 0xff0000ff);
2329         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2330         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2331     }
2332
2333     /* texture ==> offscreenplain, same size */
2334     if(surf_tex64 && surf_offscreen64) {
2335         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2336         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2337     }
2338
2339     /* texture ==> rendertarget texture, same size */
2340     if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2341         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2342         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2343
2344         /* We can't lock rendertarget textures, so copy to our temp surface first */
2345         if (hr == D3D_OK) {
2346             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2347             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2348         }
2349
2350         if (hr == D3D_OK) {
2351             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2352             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2353         }
2354     }
2355
2356     /* texture ==> rendertarget surface, same size */
2357     if(surf_tex64 && surf_rt_dest64) {
2358         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2359         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2360
2361         if (hr == D3D_OK) {
2362             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2363             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2364         }
2365     }
2366
2367     /* texture ==> texture, same size (should fail) */
2368     if(surf_tex64 && surf_tex_dest64) {
2369         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2370         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2371     }
2372
2373     /* Fill the surface of the smaller regular texture with red */
2374     if (surf_tex32 && surf_temp32) {
2375         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2376         fill_surface(surf_temp32, 0xffff0000);
2377         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2378         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2379     }
2380
2381     /* texture ==> offscreenplain, scaling (should fail) */
2382     if(surf_tex32 && surf_offscreen64) {
2383         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2384         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2385     }
2386
2387     /* texture ==> rendertarget texture, scaling */
2388     if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2389         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2390         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2391
2392         /* We can't lock rendertarget textures, so copy to our temp surface first */
2393         if (hr == D3D_OK) {
2394             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2395             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2396         }
2397
2398         if (hr == D3D_OK) {
2399             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2400             ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2401         }
2402     }
2403
2404     /* texture ==> rendertarget surface, scaling */
2405     if(surf_tex32 && surf_rt_dest64) {
2406         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2407         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2408
2409         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2410         ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2411     }
2412
2413     /* texture ==> texture, scaling (should fail) */
2414     if(surf_tex32 && surf_tex_dest64) {
2415         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2416         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2417     }
2418
2419     /*****************************************************************
2420      * Tests for when the source parameter is a rendertarget texture *
2421      *****************************************************************/
2422
2423     /* Fill the surface of the rendertarget texture with white */
2424     if (surf_tex_rt64 && surf_temp64) {
2425         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2426         fill_surface(surf_temp64, 0xffffffff);
2427         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2428         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2429     }
2430
2431     /* rendertarget texture ==> offscreenplain, same size */
2432     if(surf_tex_rt64 && surf_offscreen64) {
2433         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2434         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2435     }
2436
2437     /* rendertarget texture ==> rendertarget texture, same size */
2438     if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2439         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2440         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2441
2442         /* We can't lock rendertarget textures, so copy to our temp surface first */
2443         if (hr == D3D_OK) {
2444             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2445             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2446         }
2447
2448         if (hr == D3D_OK) {
2449             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2450             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2451         }
2452     }
2453
2454     /* rendertarget texture ==> rendertarget surface, same size */
2455     if(surf_tex_rt64 && surf_rt_dest64) {
2456         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2457         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2458
2459         if (hr == D3D_OK) {
2460             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2461             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2462         }
2463     }
2464
2465     /* rendertarget texture ==> texture, same size (should fail) */
2466     if(surf_tex_rt64 && surf_tex_dest64) {
2467         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2468         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2469     }
2470
2471     /* Fill the surface of the smaller rendertarget texture with red */
2472     if (surf_tex_rt32 && surf_temp32) {
2473         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2474         fill_surface(surf_temp32, 0xffff0000);
2475         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2476         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2477     }
2478
2479     /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2480     if(surf_tex_rt32 && surf_offscreen64) {
2481         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2482         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2483     }
2484
2485     /* rendertarget texture ==> rendertarget texture, scaling */
2486     if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2487         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2488         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2489
2490         /* We can't lock rendertarget textures, so copy to our temp surface first */
2491         if (hr == D3D_OK) {
2492             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2493             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2494         }
2495
2496         if (hr == D3D_OK) {
2497             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2498             ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2499         }
2500     }
2501
2502     /* rendertarget texture ==> rendertarget surface, scaling */
2503     if(surf_tex_rt32 && surf_rt_dest64) {
2504         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2505         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2506
2507         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2508         ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2509     }
2510
2511     /* rendertarget texture ==> texture, scaling (should fail) */
2512     if(surf_tex_rt32 && surf_tex_dest64) {
2513         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2514         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2515     }
2516
2517     /*****************************************************************
2518      * Tests for when the source parameter is a rendertarget surface *
2519      *****************************************************************/
2520
2521     /* Fill the surface of the rendertarget surface with black */
2522     if (surf_rt64)
2523         fill_surface(surf_rt64, 0xff000000);
2524
2525     /* rendertarget texture ==> offscreenplain, same size */
2526     if(surf_rt64 && surf_offscreen64) {
2527         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2528         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2529     }
2530
2531     /* rendertarget surface ==> rendertarget texture, same size */
2532     if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2533         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2534         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2535
2536         /* We can't lock rendertarget textures, so copy to our temp surface first */
2537         if (hr == D3D_OK) {
2538             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2539             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2540         }
2541
2542         if (hr == D3D_OK) {
2543             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2544             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2545         }
2546     }
2547
2548     /* rendertarget surface ==> rendertarget surface, same size */
2549     if(surf_rt64 && surf_rt_dest64) {
2550         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2551         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2552
2553         if (hr == D3D_OK) {
2554             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2555             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2556         }
2557     }
2558
2559     /* rendertarget surface ==> texture, same size (should fail) */
2560     if(surf_rt64 && surf_tex_dest64) {
2561         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2562         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2563     }
2564
2565     /* Fill the surface of the smaller rendertarget texture with red */
2566     if (surf_rt32)
2567         fill_surface(surf_rt32, 0xffff0000);
2568
2569     /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2570     if(surf_rt32 && surf_offscreen64) {
2571         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2572         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2573     }
2574
2575     /* rendertarget surface ==> rendertarget texture, scaling */
2576     if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2577         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2578         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2579
2580         /* We can't lock rendertarget textures, so copy to our temp surface first */
2581         if (hr == D3D_OK) {
2582             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2583             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2584         }
2585
2586         if (hr == D3D_OK) {
2587             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2588             ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2589         }
2590     }
2591
2592     /* rendertarget surface ==> rendertarget surface, scaling */
2593     if(surf_rt32 && surf_rt_dest64) {
2594         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2595         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2596
2597         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2598         ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2599     }
2600
2601     /* rendertarget surface ==> texture, scaling (should fail) */
2602     if(surf_rt32 && surf_tex_dest64) {
2603         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2604         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2605     }
2606
2607     /* TODO: Test when source and destination RECT parameters are given... */
2608     /* TODO: Test format conversions */
2609
2610
2611 out:
2612     /* Clean up */
2613     if (surf_rt32)
2614         IDirect3DSurface9_Release(surf_rt32);
2615     if (surf_rt64)
2616         IDirect3DSurface9_Release(surf_rt64);
2617     if (surf_rt_dest64)
2618         IDirect3DSurface9_Release(surf_rt_dest64);
2619     if (surf_temp32)
2620         IDirect3DSurface9_Release(surf_temp32);
2621     if (surf_temp64)
2622         IDirect3DSurface9_Release(surf_temp64);
2623     if (surf_offscreen32)
2624         IDirect3DSurface9_Release(surf_offscreen32);
2625     if (surf_offscreen64)
2626         IDirect3DSurface9_Release(surf_offscreen64);
2627     if (surf_offscreen_dest64)
2628         IDirect3DSurface9_Release(surf_offscreen_dest64);
2629
2630     if (tex_rt32) {
2631         if (surf_tex_rt32)
2632             IDirect3DSurface9_Release(surf_tex_rt32);
2633         IDirect3DTexture9_Release(tex_rt32);
2634     }
2635     if (tex_rt64) {
2636         if (surf_tex_rt64)
2637             IDirect3DSurface9_Release(surf_tex_rt64);
2638         IDirect3DTexture9_Release(tex_rt64);
2639     }
2640     if (tex_rt_dest64) {
2641         if (surf_tex_rt_dest64)
2642             IDirect3DSurface9_Release(surf_tex_rt_dest64);
2643         IDirect3DTexture9_Release(tex_rt_dest64);
2644     }
2645     if (tex32) {
2646         if (surf_tex32)
2647             IDirect3DSurface9_Release(surf_tex32);
2648         IDirect3DTexture9_Release(tex32);
2649     }
2650     if (tex64) {
2651         if (surf_tex64)
2652             IDirect3DSurface9_Release(surf_tex64);
2653         IDirect3DTexture9_Release(tex64);
2654     }
2655     if (tex_dest64) {
2656         if (surf_tex_dest64)
2657             IDirect3DSurface9_Release(surf_tex_dest64);
2658         IDirect3DTexture9_Release(tex_dest64);
2659     }
2660
2661     if (orig_rt) {
2662         hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2663         ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
2664         IDirect3DSurface9_Release(orig_rt);
2665     }
2666 }
2667
2668 static void maxmip_test(IDirect3DDevice9 *device)
2669 {
2670     IDirect3DTexture9 *texture = NULL;
2671     IDirect3DSurface9 *surface = NULL;
2672     HRESULT hr;
2673     DWORD color;
2674     const float quads[] = {
2675         -1.0,   -1.0,   0.0,    0.0,    0.0,
2676         -1.0,    0.0,   0.0,    0.0,    1.0,
2677          0.0,   -1.0,   0.0,    1.0,    0.0,
2678          0.0,    0.0,   0.0,    1.0,    1.0,
2679
2680          0.0,   -1.0,   0.0,    0.0,    0.0,
2681          0.0,    0.0,   0.0,    0.0,    1.0,
2682          1.0,   -1.0,   0.0,    1.0,    0.0,
2683          1.0,    0.0,   0.0,    1.0,    1.0,
2684
2685          0.0,    0.0,   0.0,    0.0,    0.0,
2686          0.0,    1.0,   0.0,    0.0,    1.0,
2687          1.0,    0.0,   0.0,    1.0,    0.0,
2688          1.0,    1.0,   0.0,    1.0,    1.0,
2689
2690         -1.0,    0.0,   0.0,    0.0,    0.0,
2691         -1.0,    1.0,   0.0,    0.0,    1.0,
2692          0.0,    0.0,   0.0,    1.0,    0.0,
2693          0.0,    1.0,   0.0,    1.0,    1.0,
2694     };
2695
2696     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2697     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2698
2699     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2700                                         &texture, NULL);
2701     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2702     if(!texture)
2703     {
2704         skip("Failed to create test texture\n");
2705         return;
2706     }
2707
2708     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
2709     fill_surface(surface, 0xffff0000);
2710     IDirect3DSurface9_Release(surface);
2711     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
2712     fill_surface(surface, 0xff00ff00);
2713     IDirect3DSurface9_Release(surface);
2714     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
2715     fill_surface(surface, 0xff0000ff);
2716     IDirect3DSurface9_Release(surface);
2717
2718     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2719     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2720     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2721     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2722
2723     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2724     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2725
2726     hr = IDirect3DDevice9_BeginScene(device);
2727     if(SUCCEEDED(hr))
2728     {
2729         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2730         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2731         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2732         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2733
2734         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2735         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2736         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2737         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2738
2739         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2740         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2741         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2742         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2743
2744         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2745         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2746         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2747         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2748         hr = IDirect3DDevice9_EndScene(device);
2749     }
2750
2751     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2752     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2753     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
2754     color = getPixelColor(device, 160, 360);
2755     ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
2756     color = getPixelColor(device, 160, 120);
2757     ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
2758     color = getPixelColor(device, 480, 120);
2759     ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
2760     color = getPixelColor(device, 480, 360);
2761     ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
2762
2763     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2764     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2765
2766     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2767     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2768
2769     hr = IDirect3DDevice9_BeginScene(device);
2770     if(SUCCEEDED(hr))
2771     {
2772         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2773         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2774         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2775         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2776
2777         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2778         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2779         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2780         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2781
2782         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2783         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2784         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2785         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2786
2787         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2788         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2789         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2790         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2791         hr = IDirect3DDevice9_EndScene(device);
2792     }
2793
2794     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2795     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2796     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2797     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2798
2799     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2800     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2801     /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2802      * samples from the highest level in the texture(level 2)
2803      */
2804     color = getPixelColor(device, 160, 360);
2805     ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
2806     color = getPixelColor(device, 160, 120);
2807     ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
2808     color = getPixelColor(device, 480, 120);
2809     ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
2810     color = getPixelColor(device, 480, 360);
2811     ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
2812
2813     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2814     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2815     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2816     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2817     IDirect3DTexture9_Release(texture);
2818 }
2819
2820 static void release_buffer_test(IDirect3DDevice9 *device)
2821 {
2822     IDirect3DVertexBuffer9 *vb = NULL;
2823     IDirect3DIndexBuffer9 *ib = NULL;
2824     HRESULT hr;
2825     BYTE *data;
2826     long ref;
2827
2828     static const struct vertex quad[] = {
2829         {-1.0,      -1.0,       0.1,        0xffff0000},
2830         {-1.0,       1.0,       0.1,        0xffff0000},
2831         { 1.0,       1.0,       0.1,        0xffff0000},
2832
2833         {-1.0,      -1.0,       0.1,        0xff00ff00},
2834         {-1.0,       1.0,       0.1,        0xff00ff00},
2835         { 1.0,       1.0,       0.1,        0xff00ff00}
2836     };
2837     short indices[] = {3, 4, 5};
2838
2839     /* Index and vertex buffers should always be creatable */
2840     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
2841                                               D3DPOOL_MANAGED, &vb, NULL);
2842     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
2843     if(!vb) {
2844         skip("Failed to create a vertex buffer\n");
2845         return;
2846     }
2847     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
2848     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
2849     if(!ib) {
2850         skip("Failed to create an index buffer\n");
2851         return;
2852     }
2853
2854     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
2855     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
2856     memcpy(data, quad, sizeof(quad));
2857     hr = IDirect3DVertexBuffer9_Unlock(vb);
2858     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
2859
2860     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
2861     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
2862     memcpy(data, indices, sizeof(indices));
2863     hr = IDirect3DIndexBuffer9_Unlock(ib);
2864     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2865
2866     hr = IDirect3DDevice9_SetIndices(device, ib);
2867     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
2868     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
2869     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
2870     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2871     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2872
2873     /* Now destroy the bound index buffer and draw again */
2874     ref = IDirect3DIndexBuffer9_Release(ib);
2875     ok(ref == 0, "Index Buffer reference count is %08ld\n", ref);
2876
2877     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2878     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2879
2880     hr = IDirect3DDevice9_BeginScene(device);
2881     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2882     if(SUCCEEDED(hr))
2883     {
2884         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
2885          * making assumptions about the indices or vertices
2886          */
2887         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
2888         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
2889         hr = IDirect3DDevice9_EndScene(device);
2890         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2891     }
2892
2893     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2894     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2895
2896     hr = IDirect3DDevice9_SetIndices(device, NULL);
2897     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2898     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2899     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2900
2901     /* Index buffer was already destroyed as part of the test */
2902     IDirect3DVertexBuffer9_Release(vb);
2903 }
2904
2905 static void float_texture_test(IDirect3DDevice9 *device)
2906 {
2907     IDirect3D9 *d3d = NULL;
2908     HRESULT hr;
2909     IDirect3DTexture9 *texture = NULL;
2910     D3DLOCKED_RECT lr;
2911     float *data;
2912     DWORD color;
2913     float quad[] = {
2914         -1.0,      -1.0,       0.1,     0.0,    0.0,
2915         -1.0,       1.0,       0.1,     0.0,    1.0,
2916          1.0,      -1.0,       0.1,     1.0,    0.0,
2917          1.0,       1.0,       0.1,     1.0,    1.0,
2918     };
2919
2920     memset(&lr, 0, sizeof(lr));
2921     IDirect3DDevice9_GetDirect3D(device, &d3d);
2922     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2923                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
2924         skip("D3DFMT_R32F textures not supported\n");
2925         goto out;
2926     }
2927
2928     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
2929                                         D3DPOOL_MANAGED, &texture, NULL);
2930     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2931     if(!texture) {
2932         skip("Failed to create R32F texture\n");
2933         goto out;
2934     }
2935
2936     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2937     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
2938     data = lr.pBits;
2939     *data = 0.0;
2940     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2941     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
2942
2943     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2944     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2945
2946     hr = IDirect3DDevice9_BeginScene(device);
2947     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2948     if(SUCCEEDED(hr))
2949     {
2950         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2951         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2952
2953         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2954         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2955
2956         hr = IDirect3DDevice9_EndScene(device);
2957         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2958     }
2959     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2960     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2961
2962     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2963     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2964
2965     color = getPixelColor(device, 240, 320);
2966     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
2967
2968 out:
2969     if(texture) IDirect3DTexture9_Release(texture);
2970     IDirect3D9_Release(d3d);
2971 }
2972
2973 static void g16r16_texture_test(IDirect3DDevice9 *device)
2974 {
2975     IDirect3D9 *d3d = NULL;
2976     HRESULT hr;
2977     IDirect3DTexture9 *texture = NULL;
2978     D3DLOCKED_RECT lr;
2979     DWORD *data;
2980     DWORD color, red, green, blue;
2981     float quad[] = {
2982        -1.0,      -1.0,       0.1,     0.0,    0.0,
2983        -1.0,       1.0,       0.1,     0.0,    1.0,
2984         1.0,      -1.0,       0.1,     1.0,    0.0,
2985         1.0,       1.0,       0.1,     1.0,    1.0,
2986     };
2987
2988     memset(&lr, 0, sizeof(lr));
2989     IDirect3DDevice9_GetDirect3D(device, &d3d);
2990     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2991        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
2992            skip("D3DFMT_G16R16 textures not supported\n");
2993            goto out;
2994     }
2995
2996     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
2997                                         D3DPOOL_MANAGED, &texture, NULL);
2998     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2999     if(!texture) {
3000         skip("Failed to create D3DFMT_G16R16 texture\n");
3001         goto out;
3002     }
3003
3004     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3005     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3006     data = lr.pBits;
3007     *data = 0x0f00f000;
3008     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3009     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3010
3011     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3012     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3013
3014     hr = IDirect3DDevice9_BeginScene(device);
3015     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3016     if(SUCCEEDED(hr))
3017     {
3018         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3019         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3020
3021         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3022         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3023
3024         hr = IDirect3DDevice9_EndScene(device);
3025         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3026     }
3027     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3028     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3029
3030     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3031     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3032
3033     color = getPixelColor(device, 240, 320);
3034     red   = (color & 0x00ff0000) >> 16;
3035     green = (color & 0x0000ff00) >>  8;
3036     blue  = (color & 0x000000ff) >>  0;
3037     ok(blue == 0xff && red >= 0xef && red <= 0xf1 && green >= 0x0e && green <= 0x10,
3038        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00F00FFF\n", color);
3039
3040 out:
3041     if(texture) IDirect3DTexture9_Release(texture);
3042     IDirect3D9_Release(d3d);
3043 }
3044
3045 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3046 {
3047     HRESULT hr;
3048     IDirect3D9 *d3d;
3049     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3050     D3DCAPS9 caps;
3051     IDirect3DTexture9 *texture = NULL;
3052     IDirect3DVolumeTexture9 *volume = NULL;
3053     unsigned int x, y, z;
3054     D3DLOCKED_RECT lr;
3055     D3DLOCKED_BOX lb;
3056     DWORD color;
3057     UINT w, h;
3058     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3059     float identity[16] = {1.0, 0.0, 0.0, 0.0,
3060                            0.0, 1.0, 0.0, 0.0,
3061                            0.0, 0.0, 1.0, 0.0,
3062                            0.0, 0.0, 0.0, 1.0};
3063     static const D3DVERTEXELEMENT9 decl_elements[] = {
3064         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3065         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3066         D3DDECL_END()
3067     };
3068     static const D3DVERTEXELEMENT9 decl_elements2[] = {
3069         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3070         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3071         D3DDECL_END()
3072     };
3073     static const D3DVERTEXELEMENT9 decl_elements3[] = {
3074         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3075         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3076         D3DDECL_END()
3077     };
3078     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3079                                                  0x00, 0xff, 0x00, 0x00,
3080                                                  0x00, 0x00, 0x00, 0x00,
3081                                                  0x00, 0x00, 0x00, 0x00};
3082
3083     memset(&lr, 0, sizeof(lr));
3084     memset(&lb, 0, sizeof(lb));
3085     IDirect3DDevice9_GetDirect3D(device, &d3d);
3086     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3087                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3088         fmt = D3DFMT_A16B16G16R16;
3089     }
3090     IDirect3D9_Release(d3d);
3091
3092     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3093     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3094     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3095     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3096     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3097     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3098     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3099     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3100     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3101     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3102     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3103     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3104     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3105     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3106     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3107     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3108     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3109     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3110     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3111     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3112     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3113     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3114     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3115     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3116
3117     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3118     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3119     w = min(1024, caps.MaxTextureWidth);
3120     h = min(1024, caps.MaxTextureHeight);
3121     hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3122                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3123     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3124     if(!texture) {
3125         skip("Failed to create the test texture\n");
3126         return;
3127     }
3128
3129     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3130      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3131      * 1.0 in red and green for the x and y coords
3132      */
3133     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3134     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3135     for(y = 0; y < h; y++) {
3136         for(x = 0; x < w; x++) {
3137             double r_f = (double) y / (double) h;
3138             double g_f = (double) x / (double) w;
3139             if(fmt == D3DFMT_A16B16G16R16) {
3140                 unsigned short r, g;
3141                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3142                 r = (unsigned short) (r_f * 65536.0);
3143                 g = (unsigned short) (g_f * 65536.0);
3144                 dst[0] = r;
3145                 dst[1] = g;
3146                 dst[2] = 0;
3147                 dst[3] = 65535;
3148             } else {
3149                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3150                 unsigned char r = (unsigned char) (r_f * 255.0);
3151                 unsigned char g = (unsigned char) (g_f * 255.0);
3152                 dst[0] = 0;
3153                 dst[1] = g;
3154                 dst[2] = r;
3155                 dst[3] = 255;
3156             }
3157         }
3158     }
3159     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3160     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3161     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3162     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3163
3164     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3165     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3166     hr = IDirect3DDevice9_BeginScene(device);
3167     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3168     if(SUCCEEDED(hr))
3169     {
3170         float quad1[] = {
3171             -1.0,      -1.0,       0.1,     1.0,    1.0,
3172             -1.0,       0.0,       0.1,     1.0,    1.0,
3173              0.0,      -1.0,       0.1,     1.0,    1.0,
3174              0.0,       0.0,       0.1,     1.0,    1.0,
3175         };
3176         float quad2[] = {
3177             -1.0,       0.0,       0.1,     1.0,    1.0,
3178             -1.0,       1.0,       0.1,     1.0,    1.0,
3179              0.0,       0.0,       0.1,     1.0,    1.0,
3180              0.0,       1.0,       0.1,     1.0,    1.0,
3181         };
3182         float quad3[] = {
3183              0.0,       0.0,       0.1,     0.5,    0.5,
3184              0.0,       1.0,       0.1,     0.5,    0.5,
3185              1.0,       0.0,       0.1,     0.5,    0.5,
3186              1.0,       1.0,       0.1,     0.5,    0.5,
3187         };
3188         float quad4[] = {
3189              320,       480,       0.1,     1.0,    0.0,    1.0,
3190              320,       240,       0.1,     1.0,    0.0,    1.0,
3191              640,       480,       0.1,     1.0,    0.0,    1.0,
3192              640,       240,       0.1,     1.0,    0.0,    1.0,
3193         };
3194         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3195                           0.0, 0.0, 0.0, 0.0,
3196                           0.0, 0.0, 0.0, 0.0,
3197                           0.0, 0.0, 0.0, 0.0};
3198
3199         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3200         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3201         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3202         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3203         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3204
3205         /* What happens with transforms enabled? */
3206         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3207         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3208         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3209         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3210
3211         /* What happens if 4 coords are used, but only 2 given ?*/
3212         mat[8] = 1.0;
3213         mat[13] = 1.0;
3214         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3215         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3216         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3217         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3218         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3219         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3220
3221         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3222          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3223          * due to the coords in the vertices. (turns out red, indeed)
3224          */
3225         memset(mat, 0, sizeof(mat));
3226         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3227         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3228         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3229         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3230         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3231         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3232         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3233         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3234
3235         hr = IDirect3DDevice9_EndScene(device);
3236         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3237     }
3238     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3239     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3240     color = getPixelColor(device, 160, 360);
3241     ok(color == 0x00FFFF00 || color == 0x00FEFE00, "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3242     color = getPixelColor(device, 160, 120);
3243     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3244     color = getPixelColor(device, 480, 120);
3245     ok(color == 0x0000FF00 || color == 0x0000FE00, "quad 3 has color %08x, expected 0x0000FF00\n", color);
3246     color = getPixelColor(device, 480, 360);
3247     ok(color == 0x00FF0000 || 0x00FE0000, "quad 4 has color %08x, expected 0x00FF0000\n", color);
3248
3249     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3250     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3251
3252     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3253     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3254     hr = IDirect3DDevice9_BeginScene(device);
3255     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3256     if(SUCCEEDED(hr))
3257     {
3258         float quad1[] = {
3259             -1.0,      -1.0,       0.1,     0.8,    0.2,
3260             -1.0,       0.0,       0.1,     0.8,    0.2,
3261              0.0,      -1.0,       0.1,     0.8,    0.2,
3262              0.0,       0.0,       0.1,     0.8,    0.2,
3263         };
3264         float quad2[] = {
3265             -1.0,       0.0,       0.1,     0.5,    1.0,
3266             -1.0,       1.0,       0.1,     0.5,    1.0,
3267              0.0,       0.0,       0.1,     0.5,    1.0,
3268              0.0,       1.0,       0.1,     0.5,    1.0,
3269         };
3270         float quad3[] = {
3271              0.0,       0.0,       0.1,     0.5,    1.0,
3272              0.0,       1.0,       0.1,     0.5,    1.0,
3273              1.0,       0.0,       0.1,     0.5,    1.0,
3274              1.0,       1.0,       0.1,     0.5,    1.0,
3275         };
3276         float quad4[] = {
3277              0.0,      -1.0,       0.1,     0.8,    0.2,
3278              0.0,       0.0,       0.1,     0.8,    0.2,
3279              1.0,      -1.0,       0.1,     0.8,    0.2,
3280              1.0,       0.0,       0.1,     0.8,    0.2,
3281         };
3282         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3283                           0.0, 0.0, 0.0, 0.0,
3284                           0.0, 1.0, 0.0, 0.0,
3285                           0.0, 0.0, 0.0, 0.0};
3286
3287         /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3288          */
3289         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3290         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3291         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3292         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3293
3294         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3295         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3296
3297         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3298          * it behaves like COUNT2 because normal textures require 2 coords
3299          */
3300         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3301         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3302         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3303         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3304
3305         /* Just to be sure, the same as quad2 above */
3306         memset(mat, 0, sizeof(mat));
3307         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3308         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3309         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3310         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3311         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3312         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3313
3314         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3315          * used? And what happens to the first?
3316          */
3317         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3318         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3319         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3320         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3321
3322         hr = IDirect3DDevice9_EndScene(device);
3323         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3324     }
3325     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3326     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3327     color = getPixelColor(device, 160, 360);
3328     ok(color == 0x00FF0000 || color == 0x00FE0000, "quad 1 has color %08x, expected 0x00FF0000\n", color);
3329     color = getPixelColor(device, 160, 120);
3330     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3331     color = getPixelColor(device, 480, 120);
3332     ok(color == 0x00ff8000 || color == 0x00fe7f00 || color == 0x00000000,
3333        "quad 3 has color %08x, expected 0x00ff8000\n", color);
3334     color = getPixelColor(device, 480, 360);
3335     ok(color == 0x0033cc00 || color == 0x0032cb00 || color == 0x00FF0000 || color == 0x00FE0000,
3336        "quad 4 has color %08x, expected 0x0033cc00\n", color);
3337
3338     IDirect3DTexture9_Release(texture);
3339
3340     /* Test projected textures, without any fancy matrices */
3341     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3342     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3343     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3344     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3345     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3346     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3347     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3348     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3349
3350     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3351     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3352     for(x = 0; x < 4; x++) {
3353         memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3354     }
3355     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3356     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3357     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3358     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3359
3360     hr = IDirect3DDevice9_BeginScene(device);
3361     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3362     if(SUCCEEDED(hr))
3363     {
3364         const float proj_quads[] = {
3365            -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3366             1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3367            -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3368             1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3369            -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3370             1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3371            -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3372             1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3373         };
3374
3375         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3376         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3377         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3378         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3379
3380         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3381         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3382         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3383         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3384
3385         hr = IDirect3DDevice9_EndScene(device);
3386         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3387     }
3388
3389     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3390     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3391     IDirect3DTexture9_Release(texture);
3392
3393     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3394     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3395     color = getPixelColor(device, 158, 118);
3396     ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3397     color = getPixelColor(device, 162, 118);
3398     ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3399     color = getPixelColor(device, 158, 122);
3400     ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3401     color = getPixelColor(device, 162, 122);
3402     ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3403
3404     color = getPixelColor(device, 158, 178);
3405     ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3406     color = getPixelColor(device, 162, 178);
3407     ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3408     color = getPixelColor(device, 158, 182);
3409     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3410     color = getPixelColor(device, 162, 182);
3411     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3412
3413     color = getPixelColor(device, 318, 118);
3414     ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3415     color = getPixelColor(device, 322, 118);
3416     ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3417     color = getPixelColor(device, 318, 122);
3418     ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3419     color = getPixelColor(device, 322, 122);
3420     ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3421
3422     color = getPixelColor(device, 318, 178);
3423     ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3424     color = getPixelColor(device, 322, 178);
3425     ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3426     color = getPixelColor(device, 318, 182);
3427     ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3428     color = getPixelColor(device, 322, 182);
3429     ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3430
3431     color = getPixelColor(device, 238, 298);
3432     ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3433     color = getPixelColor(device, 242, 298);
3434     ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3435     color = getPixelColor(device, 238, 302);
3436     ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3437     color = getPixelColor(device, 242, 302);
3438     ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3439
3440     color = getPixelColor(device, 238, 388);
3441     ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3442     color = getPixelColor(device, 242, 388);
3443     ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3444     color = getPixelColor(device, 238, 392);
3445     ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3446     color = getPixelColor(device, 242, 392);
3447     ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3448
3449     color = getPixelColor(device, 478, 298);
3450     ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3451     color = getPixelColor(device, 482, 298);
3452     ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3453     color = getPixelColor(device, 478, 302);
3454     ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3455     color = getPixelColor(device, 482, 302);
3456     ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3457
3458     color = getPixelColor(device, 478, 388);
3459     ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3460     color = getPixelColor(device, 482, 388);
3461     ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3462     color = getPixelColor(device, 478, 392);
3463     ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3464     color = getPixelColor(device, 482, 392);
3465     ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3466
3467     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3468     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3469     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3470      * Thus watch out if sampling from texels between 0 and 1.
3471      */
3472     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3473     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3474        "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3475     if(!volume) {
3476         skip("Failed to create a volume texture\n");
3477         goto out;
3478     }
3479
3480     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3481     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3482     for(z = 0; z < 32; z++) {
3483         for(y = 0; y < 32; y++) {
3484             for(x = 0; x < 32; x++) {
3485                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3486                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3487                 float r_f = (float) x / 31.0;
3488                 float g_f = (float) y / 31.0;
3489                 float b_f = (float) z / 31.0;
3490
3491                 if(fmt == D3DFMT_A16B16G16R16) {
3492                     unsigned short *mem_s = mem;
3493                     mem_s[0]  = r_f * 65535.0;
3494                     mem_s[1]  = g_f * 65535.0;
3495                     mem_s[2]  = b_f * 65535.0;
3496                     mem_s[3]  = 65535;
3497                 } else {
3498                     unsigned char *mem_c = mem;
3499                     mem_c[0]  = b_f * 255.0;
3500                     mem_c[1]  = g_f * 255.0;
3501                     mem_c[2]  = r_f * 255.0;
3502                     mem_c[3]  = 255;
3503                 }
3504             }
3505         }
3506     }
3507     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3508     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3509
3510     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3511     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3512
3513     hr = IDirect3DDevice9_BeginScene(device);
3514     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3515     if(SUCCEEDED(hr))
3516     {
3517         float quad1[] = {
3518             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3519             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3520              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3521              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3522         };
3523         float quad2[] = {
3524             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3525             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
3526              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3527              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
3528         };
3529         float quad3[] = {
3530              0.0,       0.0,       0.1,     0.0,    0.0,
3531              0.0,       1.0,       0.1,     0.0,    0.0,
3532              1.0,       0.0,       0.1,     0.0,    0.0,
3533              1.0,       1.0,       0.1,     0.0,    0.0
3534         };
3535         float quad4[] = {
3536              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3537              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3538              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3539              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
3540         };
3541         float mat[16] = {1.0, 0.0, 0.0, 0.0,
3542                          0.0, 0.0, 1.0, 0.0,
3543                          0.0, 1.0, 0.0, 0.0,
3544                          0.0, 0.0, 0.0, 1.0};
3545         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3546         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3547
3548         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3549          * values
3550          */
3551         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3552         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3553         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3554         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3555         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3556         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3557
3558         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3559          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3560          * otherwise the w will be missing(blue).
3561          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3562          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3563          */
3564         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3565         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3566         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3567         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3568
3569         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
3570         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3571         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3572         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3573         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3574         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3575         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3576         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3577         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3578
3579         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3580          * disable. ATI extends it up to the amount of values needed for the volume texture
3581          */
3582         memset(mat, 0, sizeof(mat));
3583         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3584         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3585         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3586         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3587         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3588         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3589         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3590         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3591
3592         hr = IDirect3DDevice9_EndScene(device);
3593         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3594     }
3595     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3596     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3597
3598     color = getPixelColor(device, 160, 360);
3599     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3600     color = getPixelColor(device, 160, 120);
3601     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3602        "quad 2 has color %08x, expected 0x00ffff00\n", color);
3603     color = getPixelColor(device, 480, 120);
3604     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3605     color = getPixelColor(device, 480, 360);
3606     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3607
3608     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3609     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3610     hr = IDirect3DDevice9_BeginScene(device);
3611     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3612     if(SUCCEEDED(hr))
3613     {
3614         float quad1[] = {
3615             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3616             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3617              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3618              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3619         };
3620         float quad2[] = {
3621             -1.0,       0.0,       0.1,
3622             -1.0,       1.0,       0.1,
3623              0.0,       0.0,       0.1,
3624              0.0,       1.0,       0.1,
3625         };
3626         float quad3[] = {
3627              0.0,       0.0,       0.1,     1.0,
3628              0.0,       1.0,       0.1,     1.0,
3629              1.0,       0.0,       0.1,     1.0,
3630              1.0,       1.0,       0.1,     1.0
3631         };
3632         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
3633                            0.0, 0.0, 0.0, 0.0,
3634                            0.0, 0.0, 0.0, 0.0,
3635                            0.0, 1.0, 0.0, 0.0};
3636         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
3637                            1.0, 0.0, 0.0, 0.0,
3638                            0.0, 1.0, 0.0, 0.0,
3639                            0.0, 0.0, 1.0, 0.0};
3640         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3641         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3642
3643         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
3644          */
3645         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3646         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3647         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3648         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3649         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3650         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3651
3652         /* None passed */
3653         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3654         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3655         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3656         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3657         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3658         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3659
3660         /* 4 used, 1 passed */
3661         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
3662         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3663         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
3664         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3665         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
3666         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3667
3668         hr = IDirect3DDevice9_EndScene(device);
3669         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3670     }
3671     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3672     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3673     color = getPixelColor(device, 160, 360);
3674     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
3675     color = getPixelColor(device, 160, 120);
3676     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
3677     color = getPixelColor(device, 480, 120);
3678     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
3679     /* Quad4: unused */
3680
3681     IDirect3DVolumeTexture9_Release(volume);
3682
3683     out:
3684     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3685     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3686     IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
3687     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3688     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3689     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3690     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3691     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3692     IDirect3DVertexDeclaration9_Release(decl);
3693     IDirect3DVertexDeclaration9_Release(decl2);
3694     IDirect3DVertexDeclaration9_Release(decl3);
3695 }
3696
3697 static void texdepth_test(IDirect3DDevice9 *device)
3698 {
3699     IDirect3DPixelShader9 *shader;
3700     HRESULT hr;
3701     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
3702     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
3703     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
3704     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
3705     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
3706     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
3707     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
3708     DWORD shader_code[] = {
3709         0xffff0104,                                                                 /* ps_1_4               */
3710         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
3711         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
3712         0x0000fffd,                                                                 /* phase                */
3713         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
3714         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
3715         0x0000ffff                                                                  /* end                  */
3716     };
3717     DWORD color;
3718     float vertex[] = {
3719        -1.0,   -1.0,    0.0,
3720         1.0,   -1.0,    1.0,
3721        -1.0,    1.0,    0.0,
3722         1.0,    1.0,    1.0
3723     };
3724
3725     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3726     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3727
3728     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
3729     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3730     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3731     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3732     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3733     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3734     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3735     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3736     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3737
3738     /* Fill the depth buffer with a gradient */
3739     hr = IDirect3DDevice9_BeginScene(device);
3740     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3741     if(SUCCEEDED(hr))
3742     {
3743         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3744         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3745         hr = IDirect3DDevice9_EndScene(device);
3746         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3747     }
3748
3749     /* Now perform the actual tests. Same geometry, but with the shader */
3750     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3751     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3752     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3753     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3754     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3755     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3756
3757     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
3758     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3759     hr = IDirect3DDevice9_BeginScene(device);
3760     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3761     if(SUCCEEDED(hr))
3762     {
3763         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3764         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3765
3766         hr = IDirect3DDevice9_EndScene(device);
3767         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3768     }
3769
3770     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3771     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3772     color = getPixelColor(device, 158, 240);
3773     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3774     color = getPixelColor(device, 162, 240);
3775     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
3776
3777     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3778
3779     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
3780     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3781     hr = IDirect3DDevice9_BeginScene(device);
3782     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3783     if(SUCCEEDED(hr))
3784     {
3785         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3786         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3787
3788         hr = IDirect3DDevice9_EndScene(device);
3789         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3790     }
3791
3792     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3793     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3794     color = getPixelColor(device, 318, 240);
3795     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3796     color = getPixelColor(device, 322, 240);
3797     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3798
3799     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3800
3801     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
3802     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3803     hr = IDirect3DDevice9_BeginScene(device);
3804     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3805     if(SUCCEEDED(hr))
3806     {
3807         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3808         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3809
3810         hr = IDirect3DDevice9_EndScene(device);
3811         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3812     }
3813     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3814     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3815
3816     color = getPixelColor(device, 1, 240);
3817     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
3818
3819     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3820
3821     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
3822     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3823     hr = IDirect3DDevice9_BeginScene(device);
3824     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3825     if(SUCCEEDED(hr))
3826     {
3827         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3828         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3829
3830         hr = IDirect3DDevice9_EndScene(device);
3831         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3832     }
3833     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3834     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3835     color = getPixelColor(device, 318, 240);
3836     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3837     color = getPixelColor(device, 322, 240);
3838     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
3839
3840     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3841
3842     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
3843     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3844     hr = IDirect3DDevice9_BeginScene(device);
3845     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3846     if(SUCCEEDED(hr))
3847     {
3848         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3849         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3850
3851         hr = IDirect3DDevice9_EndScene(device);
3852         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3853     }
3854     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3855     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3856
3857     color = getPixelColor(device, 1, 240);
3858     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3859
3860     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3861
3862     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
3863     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3864     hr = IDirect3DDevice9_BeginScene(device);
3865     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3866     if(SUCCEEDED(hr))
3867     {
3868         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3869         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3870
3871         hr = IDirect3DDevice9_EndScene(device);
3872         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3873     }
3874     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3875     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3876
3877     color = getPixelColor(device, 638, 240);
3878     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3879
3880     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3881
3882     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
3883     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3884     hr = IDirect3DDevice9_BeginScene(device);
3885     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3886     if(SUCCEEDED(hr))
3887     {
3888         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3889         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3890
3891         hr = IDirect3DDevice9_EndScene(device);
3892         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3893     }
3894     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3895     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3896
3897     color = getPixelColor(device, 638, 240);
3898     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3899
3900     /* Cleanup */
3901     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3902     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3903     IDirect3DPixelShader9_Release(shader);
3904
3905     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
3906     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3907     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3908     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3909 }
3910
3911 static void texkill_test(IDirect3DDevice9 *device)
3912 {
3913     IDirect3DPixelShader9 *shader;
3914     HRESULT hr;
3915     DWORD color;
3916
3917     const float vertex[] = {
3918     /*                          bottom  top    right    left */
3919         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
3920          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
3921         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
3922          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
3923     };
3924
3925     DWORD shader_code_11[] = {
3926     0xffff0101,                                                             /* ps_1_1                     */
3927     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
3928     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
3929     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
3930     0x0000ffff                                                              /* end                        */
3931     };
3932     DWORD shader_code_20[] = {
3933     0xffff0200,                                                             /* ps_2_0                     */
3934     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
3935     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
3936     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
3937     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
3938     0x0000ffff                                                              /* end                        */
3939     };
3940
3941     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3942     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3943     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
3944     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3945
3946     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3947     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
3948     hr = IDirect3DDevice9_BeginScene(device);
3949     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3950     if(SUCCEEDED(hr))
3951     {
3952         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
3953         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
3954         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3955         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3956         hr = IDirect3DDevice9_EndScene(device);
3957         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3958     }
3959     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3960     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3961     color = getPixelColor(device, 63, 46);
3962     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
3963     color = getPixelColor(device, 66, 46);
3964     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
3965     color = getPixelColor(device, 63, 49);
3966     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
3967     color = getPixelColor(device, 66, 49);
3968     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
3969
3970     color = getPixelColor(device, 578, 46);
3971     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3972     color = getPixelColor(device, 575, 46);
3973     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3974     color = getPixelColor(device, 578, 49);
3975     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
3976     color = getPixelColor(device, 575, 49);
3977     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3978
3979     color = getPixelColor(device, 63, 430);
3980     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3981     color = getPixelColor(device, 63, 433);
3982     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3983     color = getPixelColor(device, 66, 433);
3984     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3985     color = getPixelColor(device, 66, 430);
3986     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3987
3988     color = getPixelColor(device, 578, 430);
3989     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3990     color = getPixelColor(device, 578, 433);
3991     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3992     color = getPixelColor(device, 575, 433);
3993     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3994     color = getPixelColor(device, 575, 430);
3995     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3996
3997     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3998     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
3999     IDirect3DPixelShader9_Release(shader);
4000
4001     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4002     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4003     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4004     if(FAILED(hr)) {
4005         skip("Failed to create 2.0 test shader, most likely not supported\n");
4006         return;
4007     }
4008
4009     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4010     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4011     hr = IDirect3DDevice9_BeginScene(device);
4012     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4013     if(SUCCEEDED(hr))
4014     {
4015         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4016         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4017         hr = IDirect3DDevice9_EndScene(device);
4018         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4019     }
4020     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4021
4022     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4023     color = getPixelColor(device, 63, 46);
4024     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4025     color = getPixelColor(device, 66, 46);
4026     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4027     color = getPixelColor(device, 63, 49);
4028     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4029     color = getPixelColor(device, 66, 49);
4030     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4031
4032     color = getPixelColor(device, 578, 46);
4033     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4034     color = getPixelColor(device, 575, 46);
4035     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4036     color = getPixelColor(device, 578, 49);
4037     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4038     color = getPixelColor(device, 575, 49);
4039     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4040
4041     color = getPixelColor(device, 63, 430);
4042     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4043     color = getPixelColor(device, 63, 433);
4044     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4045     color = getPixelColor(device, 66, 433);
4046     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4047     color = getPixelColor(device, 66, 430);
4048     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4049
4050     color = getPixelColor(device, 578, 430);
4051     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4052     color = getPixelColor(device, 578, 433);
4053     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4054     color = getPixelColor(device, 575, 433);
4055     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4056     color = getPixelColor(device, 575, 430);
4057     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4058
4059     /* Cleanup */
4060     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4061     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4062     IDirect3DPixelShader9_Release(shader);
4063 }
4064
4065 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4066 {
4067     IDirect3D9 *d3d9;
4068     HRESULT hr;
4069     IDirect3DTexture9 *texture;
4070     IDirect3DPixelShader9 *shader;
4071     IDirect3DPixelShader9 *shader2;
4072     D3DLOCKED_RECT lr;
4073     DWORD color;
4074     DWORD shader_code[] = {
4075         0xffff0101,                             /* ps_1_1       */
4076         0x00000042, 0xb00f0000,                 /* tex t0       */
4077         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
4078         0x0000ffff                              /* end          */
4079     };
4080     DWORD shader_code2[] = {
4081         0xffff0101,                             /* ps_1_1       */
4082         0x00000042, 0xb00f0000,                 /* tex t0       */
4083         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
4084         0x0000ffff                              /* end          */
4085     };
4086
4087     float quad[] = {
4088        -1.0,   -1.0,   0.1,     0.5,    0.5,
4089         1.0,   -1.0,   0.1,     0.5,    0.5,
4090        -1.0,    1.0,   0.1,     0.5,    0.5,
4091         1.0,    1.0,   0.1,     0.5,    0.5,
4092     };
4093
4094     memset(&lr, 0, sizeof(lr));
4095     IDirect3DDevice9_GetDirect3D(device, &d3d9);
4096     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4097                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4098     IDirect3D9_Release(d3d9);
4099     if(FAILED(hr)) {
4100         skip("No D3DFMT_X8L8V8U8 support\n");
4101     };
4102
4103     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4104     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4105
4106     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4107     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4108     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4109     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4110     *((DWORD *) lr.pBits) = 0x11ca3141;
4111     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4112     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4113
4114     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4115     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4116     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4117     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4118
4119     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4120     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4121     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4122     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4123     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4124     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4125
4126     hr = IDirect3DDevice9_BeginScene(device);
4127     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4128     if(SUCCEEDED(hr))
4129     {
4130         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4131         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4132
4133         hr = IDirect3DDevice9_EndScene(device);
4134         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4135     }
4136     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4137     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4138     color = getPixelColor(device, 578, 430);
4139     ok(color == 0x008262ca || color == 0x008363ca || color == 0x008362ca,
4140        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4141
4142     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4143     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4144     hr = IDirect3DDevice9_BeginScene(device);
4145     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4146     if(SUCCEEDED(hr))
4147     {
4148         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4149         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4150
4151         hr = IDirect3DDevice9_EndScene(device);
4152         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4153     }
4154     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4155     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4156     color = getPixelColor(device, 578, 430);
4157     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4158
4159     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4160     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4161     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4162     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4163     IDirect3DPixelShader9_Release(shader);
4164     IDirect3DPixelShader9_Release(shader2);
4165     IDirect3DTexture9_Release(texture);
4166 }
4167
4168 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4169 {
4170     HRESULT hr;
4171     IDirect3D9 *d3d;
4172     IDirect3DTexture9 *texture = NULL;
4173     IDirect3DSurface9 *surface;
4174     DWORD color;
4175     const RECT r1 = {256, 256, 512, 512};
4176     const RECT r2 = {512, 256, 768, 512};
4177     const RECT r3 = {256, 512, 512, 768};
4178     const RECT r4 = {512, 512, 768, 768};
4179     unsigned int x, y;
4180     D3DLOCKED_RECT lr;
4181     memset(&lr, 0, sizeof(lr));
4182
4183     IDirect3DDevice9_GetDirect3D(device, &d3d);
4184     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4185        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4186         skip("No autogenmipmap support\n");
4187         IDirect3D9_Release(d3d);
4188         return;
4189     }
4190     IDirect3D9_Release(d3d);
4191
4192     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4193     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4194
4195     /* Make the mipmap big, so that a smaller mipmap is used
4196      */
4197     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4198                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4199     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4200
4201     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4202     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4203     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4204     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4205     for(y = 0; y < 1024; y++) {
4206         for(x = 0; x < 1024; x++) {
4207             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4208             POINT pt;
4209
4210             pt.x = x;
4211             pt.y = y;
4212             if(PtInRect(&r1, pt)) {
4213                 *dst = 0xffff0000;
4214             } else if(PtInRect(&r2, pt)) {
4215                 *dst = 0xff00ff00;
4216             } else if(PtInRect(&r3, pt)) {
4217                 *dst = 0xff0000ff;
4218             } else if(PtInRect(&r4, pt)) {
4219                 *dst = 0xff000000;
4220             } else {
4221                 *dst = 0xffffffff;
4222             }
4223         }
4224     }
4225     hr = IDirect3DSurface9_UnlockRect(surface);
4226     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4227     IDirect3DSurface9_Release(surface);
4228
4229     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4230     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4231     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4232     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4233
4234     hr = IDirect3DDevice9_BeginScene(device);
4235     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4236     if(SUCCEEDED(hr)) {
4237         const float quad[] =  {
4238            -0.5,   -0.5,    0.1,    0.0,    0.0,
4239            -0.5,    0.5,    0.1,    0.0,    1.0,
4240             0.5,   -0.5,    0.1,    1.0,    0.0,
4241             0.5,    0.5,    0.1,    1.0,    1.0
4242         };
4243
4244         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4245         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4246         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4247         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4248         hr = IDirect3DDevice9_EndScene(device);
4249         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4250     }
4251     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4252     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4253     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4254     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4255     IDirect3DTexture9_Release(texture);
4256
4257     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4258     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4259     color = getPixelColor(device, 200, 200);
4260     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4261     color = getPixelColor(device, 280, 200);
4262     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4263     color = getPixelColor(device, 360, 200);
4264     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4265     color = getPixelColor(device, 440, 200);
4266     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4267     color = getPixelColor(device, 200, 270);
4268     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4269     color = getPixelColor(device, 280, 270);
4270     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4271     color = getPixelColor(device, 360, 270);
4272     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4273     color = getPixelColor(device, 440, 270);
4274     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4275 }
4276
4277 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4278 {
4279     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4280     IDirect3DVertexDeclaration9 *decl;
4281     HRESULT hr;
4282     DWORD color;
4283     DWORD shader_code_11[] =  {
4284         0xfffe0101,                                         /* vs_1_1           */
4285         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4286         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4287         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4288         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4289         0x0000ffff                                          /* end              */
4290     };
4291     DWORD shader_code_11_2[] =  {
4292         0xfffe0101,                                         /* vs_1_1           */
4293         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4294         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4295         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4296         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4297         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4298         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4299         0x0000ffff                                          /* end              */
4300     };
4301     DWORD shader_code_20[] =  {
4302         0xfffe0200,                                         /* vs_2_0           */
4303         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4304         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4305         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4306         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4307         0x0000ffff                                          /* end              */
4308     };
4309     DWORD shader_code_20_2[] =  {
4310         0xfffe0200,                                         /* vs_2_0           */
4311         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4312         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4313         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4314         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4315         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4316         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4317         0x0000ffff                                          /* end              */
4318     };
4319     static const D3DVERTEXELEMENT9 decl_elements[] = {
4320         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4321         D3DDECL_END()
4322     };
4323     float quad1[] = {
4324         -1.0,   -1.0,   0.1,
4325          0.0,   -1.0,   0.1,
4326         -1.0,    0.0,   0.1,
4327          0.0,    0.0,   0.1
4328     };
4329     float quad2[] = {
4330          0.0,   -1.0,   0.1,
4331          1.0,   -1.0,   0.1,
4332          0.0,    0.0,   0.1,
4333          1.0,    0.0,   0.1
4334     };
4335     float quad3[] = {
4336          0.0,    0.0,   0.1,
4337          1.0,    0.0,   0.1,
4338          0.0,    1.0,   0.1,
4339          1.0,    1.0,   0.1
4340     };
4341     float quad4[] = {
4342         -1.0,    0.0,   0.1,
4343          0.0,    0.0,   0.1,
4344         -1.0,    1.0,   0.1,
4345          0.0,    1.0,   0.1
4346     };
4347     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4348     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4349
4350     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4351     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4352
4353     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4354     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4355     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4356     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4357     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4358     if(FAILED(hr)) shader_20 = NULL;
4359     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4360     if(FAILED(hr)) shader_20_2 = NULL;
4361     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4362     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4363
4364     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4365     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4366     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4367     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4368     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4369     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4370
4371     hr = IDirect3DDevice9_BeginScene(device);
4372     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4373     if(SUCCEEDED(hr))
4374     {
4375         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4376         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4377         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4378         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4379
4380         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4381         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4382         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4383         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4384
4385         if(shader_20) {
4386             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4387             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4388             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4389             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4390         }
4391
4392         if(shader_20_2) {
4393             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4394             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4395             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4396             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4397         }
4398
4399         hr = IDirect3DDevice9_EndScene(device);
4400         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4401     }
4402     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4403     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4404
4405     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4406     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4407     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4408     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4409
4410     color = getPixelColor(device, 160, 360);
4411     ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4412        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4413     color = getPixelColor(device, 480, 360);
4414     ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4415        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4416     if(shader_20) {
4417         color = getPixelColor(device, 160, 120);
4418         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4419            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4420     }
4421     if(shader_20_2) {
4422         color = getPixelColor(device, 480, 120);
4423         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4424            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4425     }
4426
4427     IDirect3DVertexDeclaration9_Release(decl);
4428     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4429     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4430     IDirect3DVertexShader9_Release(shader_11_2);
4431     IDirect3DVertexShader9_Release(shader_11);
4432 }
4433
4434 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4435 {
4436     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4437     HRESULT hr;
4438     DWORD color;
4439     DWORD shader_code_11[] =  {
4440         0xffff0101,                                         /* ps_1_1           */
4441         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4442         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4443         0x0000ffff                                          /* end              */
4444     };
4445     DWORD shader_code_12[] =  {
4446         0xffff0102,                                         /* ps_1_2           */
4447         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4448         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4449         0x0000ffff                                          /* end              */
4450     };
4451     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4452      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4453      * During development of this test, 1.3 shaders were verified too
4454      */
4455     DWORD shader_code_14[] =  {
4456         0xffff0104,                                         /* ps_1_4           */
4457         /* Try to make one constant local. It gets clamped too, although the binary contains
4458          * the bigger numbers
4459          */
4460         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4461         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4462         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4463         0x0000ffff                                          /* end              */
4464     };
4465     DWORD shader_code_20[] =  {
4466         0xffff0200,                                         /* ps_2_0           */
4467         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4468         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4469         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
4470         0x0000ffff                                          /* end              */
4471     };
4472     float quad1[] = {
4473         -1.0,   -1.0,   0.1,
4474          0.0,   -1.0,   0.1,
4475         -1.0,    0.0,   0.1,
4476          0.0,    0.0,   0.1
4477     };
4478     float quad2[] = {
4479          0.0,   -1.0,   0.1,
4480          1.0,   -1.0,   0.1,
4481          0.0,    0.0,   0.1,
4482          1.0,    0.0,   0.1
4483     };
4484     float quad3[] = {
4485          0.0,    0.0,   0.1,
4486          1.0,    0.0,   0.1,
4487          0.0,    1.0,   0.1,
4488          1.0,    1.0,   0.1
4489     };
4490     float quad4[] = {
4491         -1.0,    0.0,   0.1,
4492          0.0,    0.0,   0.1,
4493         -1.0,    1.0,   0.1,
4494          0.0,    1.0,   0.1
4495     };
4496     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4497     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4498
4499     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4500     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4501
4502     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4503     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4504     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4505     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4506     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4507     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4508     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4509     if(FAILED(hr)) shader_20 = NULL;
4510
4511     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4512     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4513     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4514     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4515     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4516     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4517
4518     hr = IDirect3DDevice9_BeginScene(device);
4519     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4520     if(SUCCEEDED(hr))
4521     {
4522         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4523         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4524         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4525         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4526
4527         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4528         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4529         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4530         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4531
4532         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4533         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4534         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4535         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4536
4537         if(shader_20) {
4538             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4539             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4540             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4541             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4542         }
4543
4544         hr = IDirect3DDevice9_EndScene(device);
4545         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4546     }
4547     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4548     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4549
4550     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4551     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4552
4553     color = getPixelColor(device, 160, 360);
4554     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4555        "quad 1 has color %08x, expected 0x00808000\n", color);
4556     color = getPixelColor(device, 480, 360);
4557     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4558        "quad 2 has color %08x, expected 0x00808000\n", color);
4559     color = getPixelColor(device, 480, 120);
4560     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4561        "quad 3 has color %08x, expected 0x00808000\n", color);
4562     if(shader_20) {
4563         color = getPixelColor(device, 160, 120);
4564         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4565            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4566     }
4567
4568     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4569     IDirect3DPixelShader9_Release(shader_14);
4570     IDirect3DPixelShader9_Release(shader_12);
4571     IDirect3DPixelShader9_Release(shader_11);
4572 }
4573
4574 static void dp2add_ps_test(IDirect3DDevice9 *device)
4575 {
4576     IDirect3DPixelShader9 *shader_dp2add = NULL;
4577     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4578     HRESULT hr;
4579     DWORD color;
4580
4581     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
4582      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4583      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
4584      * r0 first.
4585      * The result here for the r,g,b components should be roughly 0.5:
4586      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4587     static const DWORD shader_code_dp2add[] =  {
4588         0xffff0200,                                                             /* ps_2_0                       */
4589         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
4590
4591         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
4592         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
4593
4594         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
4595         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
4596         0x0000ffff                                                              /* end                          */
4597     };
4598
4599     /* Test the _sat modifier, too.  Result here should be:
4600      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4601      *      _SAT: ==> 1.0
4602      *   ADD: (1.0 + -0.5) = 0.5
4603      */
4604     static const DWORD shader_code_dp2add_sat[] =  {
4605         0xffff0200,                                                             /* ps_2_0                           */
4606         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
4607
4608         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
4609         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
4610         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
4611
4612         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
4613         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
4614         0x0000ffff                                                              /* end                              */
4615     };
4616
4617     const float quad[] = {
4618         -1.0,   -1.0,   0.1,
4619          1.0,   -1.0,   0.1,
4620         -1.0,    1.0,   0.1,
4621          1.0,    1.0,   0.1
4622     };
4623
4624
4625     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
4626     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4627
4628     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
4629     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4630
4631     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
4632     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4633
4634     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4635     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4636
4637     if (shader_dp2add) {
4638
4639         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
4640         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4641
4642         hr = IDirect3DDevice9_BeginScene(device);
4643         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4644         if(SUCCEEDED(hr))
4645         {
4646             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4647             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4648
4649             hr = IDirect3DDevice9_EndScene(device);
4650             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4651         }
4652         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4653         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4654
4655         color = getPixelColor(device, 360, 240);
4656         ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4657
4658         IDirect3DPixelShader9_Release(shader_dp2add);
4659     } else {
4660         skip("dp2add shader creation failed\n");
4661     }
4662
4663     if (shader_dp2add_sat) {
4664
4665         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
4666         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4667
4668         hr = IDirect3DDevice9_BeginScene(device);
4669         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4670         if(SUCCEEDED(hr))
4671         {
4672             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4673             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4674
4675             hr = IDirect3DDevice9_EndScene(device);
4676             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4677         }
4678         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4679         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4680
4681         color = getPixelColor(device, 360, 240);
4682         ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4683
4684         IDirect3DPixelShader9_Release(shader_dp2add_sat);
4685     } else {
4686         skip("dp2add shader creation failed\n");
4687     }
4688
4689     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4690     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4691 }
4692
4693 static void cnd_test(IDirect3DDevice9 *device)
4694 {
4695     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
4696     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
4697     HRESULT hr;
4698     DWORD color;
4699     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
4700      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
4701      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
4702      */
4703     DWORD shader_code_11[] =  {
4704         0xffff0101,                                                                 /* ps_1_1               */
4705         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4706         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4707         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
4708         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
4709         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4710         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4711         0x0000ffff                                                                  /* end                  */
4712     };
4713     DWORD shader_code_12[] =  {
4714         0xffff0102,                                                                 /* ps_1_2               */
4715         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4716         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4717         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
4718         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
4719         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4720         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4721         0x0000ffff                                                                  /* end                  */
4722     };
4723     DWORD shader_code_13[] =  {
4724         0xffff0103,                                                                 /* ps_1_3               */
4725         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4726         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4727         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
4728         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
4729         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4730         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4731         0x0000ffff                                                                  /* end                  */
4732     };
4733     DWORD shader_code_14[] =  {
4734         0xffff0104,                                                                 /* ps_1_3               */
4735         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
4736         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
4737         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
4738         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
4739         0x0000ffff                                                                  /* end                  */
4740     };
4741
4742     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
4743      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
4744      * set by the compiler, it was added manually after compilation. It isn't always allowed,
4745      * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
4746      * native CreatePixelShader returns an error.
4747      *
4748      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
4749      * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
4750      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
4751      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
4752      */
4753     DWORD shader_code_11_coissue[] =  {
4754         0xffff0101,                                                             /* ps_1_1                   */
4755         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4756         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4757         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4758         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4759         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4760         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4761         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4762         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4763         /* 0x40000000 = D3DSI_COISSUE */
4764         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4765         0x0000ffff                                                              /* end                      */
4766     };
4767     DWORD shader_code_12_coissue[] =  {
4768         0xffff0102,                                                             /* ps_1_2                   */
4769         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4770         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4771         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4772         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4773         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4774         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4775         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4776         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4777         /* 0x40000000 = D3DSI_COISSUE */
4778         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4779         0x0000ffff                                                              /* end                      */
4780     };
4781     DWORD shader_code_13_coissue[] =  {
4782         0xffff0103,                                                             /* ps_1_3                   */
4783         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4784         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4785         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4786         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4787         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4788         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4789         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4790         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4791         /* 0x40000000 = D3DSI_COISSUE */
4792         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4793         0x0000ffff                                                              /* end                      */
4794     };
4795     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
4796      * compare against 0.5
4797      */
4798     DWORD shader_code_14_coissue[] =  {
4799         0xffff0104,                                                             /* ps_1_4                   */
4800         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
4801         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
4802         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
4803         /* 0x40000000 = D3DSI_COISSUE */
4804         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
4805         0x0000ffff                                                              /* end                      */
4806     };
4807     float quad1[] = {
4808         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
4809          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
4810         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
4811          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
4812     };
4813     float quad2[] = {
4814          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
4815          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
4816          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
4817          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
4818     };
4819     float quad3[] = {
4820          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
4821          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
4822          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
4823          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
4824     };
4825     float quad4[] = {
4826         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
4827          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
4828         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
4829          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
4830     };
4831     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
4832     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
4833     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
4834     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
4835
4836     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4837     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4838
4839     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4840     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4841     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4842     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4843     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
4844     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4845     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4846     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4847     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
4848     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4849     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
4850     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4851     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
4852     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4853     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
4854     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4855
4856     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4857     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4858     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4859     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4860     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4861     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4862
4863     hr = IDirect3DDevice9_BeginScene(device);
4864     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4865     if(SUCCEEDED(hr))
4866     {
4867         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4868         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4869         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4870         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4871
4872         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4873         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4874         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4875         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4876
4877         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
4878         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4879         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4880         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4881
4882         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4883         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4884         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4885         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4886
4887         hr = IDirect3DDevice9_EndScene(device);
4888         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4889     }
4890     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4891     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4892
4893     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4894     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4895
4896     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
4897     color = getPixelColor(device, 158, 118);
4898     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
4899     color = getPixelColor(device, 162, 118);
4900     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
4901     color = getPixelColor(device, 158, 122);
4902     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
4903     color = getPixelColor(device, 162, 122);
4904     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
4905
4906     /* 1.1 shader. All 3 components get set, based on the .w comparison */
4907     color = getPixelColor(device, 158, 358);
4908     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
4909     color = getPixelColor(device, 162, 358);
4910     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4911         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
4912     color = getPixelColor(device, 158, 362);
4913     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
4914     color = getPixelColor(device, 162, 362);
4915     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4916         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
4917
4918     /* 1.2 shader */
4919     color = getPixelColor(device, 478, 358);
4920     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
4921     color = getPixelColor(device, 482, 358);
4922     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4923         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
4924     color = getPixelColor(device, 478, 362);
4925     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
4926     color = getPixelColor(device, 482, 362);
4927     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4928         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
4929
4930     /* 1.3 shader */
4931     color = getPixelColor(device, 478, 118);
4932     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
4933     color = getPixelColor(device, 482, 118);
4934     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4935         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
4936     color = getPixelColor(device, 478, 122);
4937     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
4938     color = getPixelColor(device, 482, 122);
4939     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4940         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
4941
4942     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4943     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4944     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
4945     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4946     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
4947     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4948
4949     hr = IDirect3DDevice9_BeginScene(device);
4950     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4951     if(SUCCEEDED(hr))
4952     {
4953         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
4954         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4955         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4956         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4957
4958         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
4959         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4960         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4961         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4962
4963         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
4964         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4965         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4966         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4967
4968         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
4969         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4970         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4971         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4972
4973         hr = IDirect3DDevice9_EndScene(device);
4974         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4975     }
4976     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4977     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4978
4979     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4980     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4981
4982     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
4983      * that we swapped the values in c1 and c2 to make the other tests return some color
4984      */
4985     color = getPixelColor(device, 158, 118);
4986     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
4987     color = getPixelColor(device, 162, 118);
4988     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
4989     color = getPixelColor(device, 158, 122);
4990     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
4991     color = getPixelColor(device, 162, 122);
4992     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
4993
4994     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
4995     color = getPixelColor(device, 158, 358);
4996     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4997         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
4998     color = getPixelColor(device, 162, 358);
4999     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5000         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5001     color = getPixelColor(device, 158, 362);
5002     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5003         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5004     color = getPixelColor(device, 162, 362);
5005     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5006         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5007
5008     /* 1.2 shader */
5009     color = getPixelColor(device, 478, 358);
5010     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5011         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5012     color = getPixelColor(device, 482, 358);
5013     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5014         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5015     color = getPixelColor(device, 478, 362);
5016     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5017         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5018     color = getPixelColor(device, 482, 362);
5019     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5020         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5021
5022     /* 1.3 shader */
5023     color = getPixelColor(device, 478, 118);
5024     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5025         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5026     color = getPixelColor(device, 482, 118);
5027     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5028         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5029     color = getPixelColor(device, 478, 122);
5030     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5031         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5032     color = getPixelColor(device, 482, 122);
5033     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5034         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5035
5036     IDirect3DPixelShader9_Release(shader_14_coissue);
5037     IDirect3DPixelShader9_Release(shader_13_coissue);
5038     IDirect3DPixelShader9_Release(shader_12_coissue);
5039     IDirect3DPixelShader9_Release(shader_11_coissue);
5040     IDirect3DPixelShader9_Release(shader_14);
5041     IDirect3DPixelShader9_Release(shader_13);
5042     IDirect3DPixelShader9_Release(shader_12);
5043     IDirect3DPixelShader9_Release(shader_11);
5044 }
5045
5046 static void nested_loop_test(IDirect3DDevice9 *device) {
5047     const DWORD shader_code[] = {
5048         0xffff0300,                                                             /* ps_3_0               */
5049         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
5050         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5051         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
5052         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
5053         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5054         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5055         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
5056         0x0000001d,                                                             /* endloop              */
5057         0x0000001d,                                                             /* endloop              */
5058         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
5059         0x0000ffff                                                              /* end                  */
5060     };
5061     IDirect3DPixelShader9 *shader;
5062     HRESULT hr;
5063     DWORD color;
5064     const float quad[] = {
5065         -1.0,   -1.0,   0.1,
5066          1.0,   -1.0,   0.1,
5067         -1.0,    1.0,   0.1,
5068          1.0,    1.0,   0.1
5069     };
5070
5071     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5072     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5073     hr = IDirect3DDevice9_SetPixelShader(device, shader);
5074     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5075     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5076     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5077     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5078     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5079
5080     hr = IDirect3DDevice9_BeginScene(device);
5081     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5082     if(SUCCEEDED(hr))
5083     {
5084         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5085         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5086         hr = IDirect3DDevice9_EndScene(device);
5087         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5088     }
5089     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5090     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5091
5092     color = getPixelColor(device, 360, 240);
5093     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5094        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5095
5096     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5097     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5098     IDirect3DPixelShader9_Release(shader);
5099 }
5100
5101 struct varying_test_struct
5102 {
5103     const DWORD             *shader_code;
5104     IDirect3DPixelShader9   *shader;
5105     DWORD                   color, color_rhw;
5106     const char              *name;
5107     BOOL                    todo, todo_rhw;
5108 };
5109
5110 struct hugeVertex
5111 {
5112     float pos_x,        pos_y,      pos_z,      rhw;
5113     float weight_1,     weight_2,   weight_3,   weight_4;
5114     float index_1,      index_2,    index_3,    index_4;
5115     float normal_1,     normal_2,   normal_3,   normal_4;
5116     float fog_1,        fog_2,      fog_3,      fog_4;
5117     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
5118     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
5119     float binormal_1,   binormal_2, binormal_3, binormal_4;
5120     float depth_1,      depth_2,    depth_3,    depth_4;
5121     DWORD diffuse, specular;
5122 };
5123
5124 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5125     /* dcl_position: fails to compile */
5126     const DWORD blendweight_code[] = {
5127         0xffff0300,                             /* ps_3_0                   */
5128         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
5129         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5130         0x0000ffff                              /* end                      */
5131     };
5132     const DWORD blendindices_code[] = {
5133         0xffff0300,                             /* ps_3_0                   */
5134         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
5135         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5136         0x0000ffff                              /* end                      */
5137     };
5138     const DWORD normal_code[] = {
5139         0xffff0300,                             /* ps_3_0                   */
5140         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
5141         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5142         0x0000ffff                              /* end                      */
5143     };
5144     /* psize: fails? */
5145     const DWORD texcoord0_code[] = {
5146         0xffff0300,                             /* ps_3_0                   */
5147         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
5148         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5149         0x0000ffff                              /* end                      */
5150     };
5151     const DWORD tangent_code[] = {
5152         0xffff0300,                             /* ps_3_0                   */
5153         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
5154         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5155         0x0000ffff                              /* end                      */
5156     };
5157     const DWORD binormal_code[] = {
5158         0xffff0300,                             /* ps_3_0                   */
5159         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
5160         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5161         0x0000ffff                              /* end                      */
5162     };
5163     /* tessfactor: fails */
5164     /* positiont: fails */
5165     const DWORD color_code[] = {
5166         0xffff0300,                             /* ps_3_0                   */
5167         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
5168         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5169         0x0000ffff                              /* end                      */
5170     };
5171     const DWORD fog_code[] = {
5172         0xffff0300,                             /* ps_3_0                   */
5173         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
5174         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5175         0x0000ffff                              /* end                      */
5176     };
5177     const DWORD depth_code[] = {
5178         0xffff0300,                             /* ps_3_0                   */
5179         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
5180         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5181         0x0000ffff                              /* end                      */
5182     };
5183     const DWORD specular_code[] = {
5184         0xffff0300,                             /* ps_3_0                   */
5185         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
5186         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5187         0x0000ffff                              /* end                      */
5188     };
5189     /* sample: fails */
5190
5191     struct varying_test_struct tests[] = {
5192        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
5193        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
5194        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
5195        /* Why does dx not forward the texcoord? */
5196        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
5197        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
5198        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
5199        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
5200        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
5201        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
5202        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
5203     };
5204     /* Declare a monster vertex type :-) */
5205     static const D3DVERTEXELEMENT9 decl_elements[] = {
5206         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5207         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5208         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5209         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5210         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5211         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5212         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5213         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5214         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5215         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5216         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5217         D3DDECL_END()
5218     };
5219     static const D3DVERTEXELEMENT9 decl_elements2[] = {
5220         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
5221         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5222         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5223         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5224         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5225         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5226         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5227         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5228         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5229         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5230         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5231         D3DDECL_END()
5232     };
5233     struct hugeVertex data[4] = {
5234         {
5235             -1.0,   -1.0,   0.1,    1.0,
5236              0.1,    0.1,   0.1,    0.1,
5237              0.2,    0.2,   0.2,    0.2,
5238              0.3,    0.3,   0.3,    0.3,
5239              0.4,    0.4,   0.4,    0.4,
5240              0.50,   0.55,  0.55,   0.55,
5241              0.6,    0.6,   0.6,    0.7,
5242              0.7,    0.7,   0.7,    0.6,
5243              0.8,    0.8,   0.8,    0.8,
5244              0xe6e6e6e6, /* 0.9 * 256 */
5245              0x224488ff  /* Nothing special */
5246         },
5247         {
5248              1.0,   -1.0,   0.1,    1.0,
5249              0.1,    0.1,   0.1,    0.1,
5250              0.2,    0.2,   0.2,    0.2,
5251              0.3,    0.3,   0.3,    0.3,
5252              0.4,    0.4,   0.4,    0.4,
5253              0.50,   0.55,  0.55,   0.55,
5254              0.6,    0.6,   0.6,    0.7,
5255              0.7,    0.7,   0.7,    0.6,
5256              0.8,    0.8,   0.8,    0.8,
5257              0xe6e6e6e6, /* 0.9 * 256 */
5258              0x224488ff /* Nothing special */
5259         },
5260         {
5261             -1.0,    1.0,   0.1,    1.0,
5262              0.1,    0.1,   0.1,    0.1,
5263              0.2,    0.2,   0.2,    0.2,
5264              0.3,    0.3,   0.3,    0.3,
5265              0.4,    0.4,   0.4,    0.4,
5266              0.50,   0.55,  0.55,   0.55,
5267              0.6,    0.6,   0.6,    0.7,
5268              0.7,    0.7,   0.7,    0.6,
5269              0.8,    0.8,   0.8,    0.8,
5270              0xe6e6e6e6, /* 0.9 * 256 */
5271              0x224488ff /* Nothing special */
5272         },
5273         {
5274              1.0,    1.0,   0.1,    1.0,
5275              0.1,    0.1,   0.1,    0.1,
5276              0.2,    0.2,   0.2,    0.2,
5277              0.3,    0.3,   0.3,    0.3,
5278              0.4,    0.4,   0.4,    0.4,
5279              0.50,   0.55,  0.55,   0.55,
5280              0.6,    0.6,   0.6,    0.7,
5281              0.7,    0.7,   0.7,    0.6,
5282              0.8,    0.8,   0.8,    0.8,
5283              0xe6e6e6e6, /* 0.9 * 256 */
5284              0x224488ff /* Nothing special */
5285         },
5286     };
5287     struct hugeVertex data2[4];
5288     IDirect3DVertexDeclaration9 *decl;
5289     IDirect3DVertexDeclaration9 *decl2;
5290     HRESULT hr;
5291     unsigned int i;
5292     DWORD color, r, g, b, r_e, g_e, b_e;
5293     BOOL drawok;
5294
5295     memcpy(data2, data, sizeof(data2));
5296     data2[0].pos_x = 0;     data2[0].pos_y = 0;
5297     data2[1].pos_x = 640;   data2[1].pos_y = 0;
5298     data2[2].pos_x = 0;     data2[2].pos_y = 480;
5299     data2[3].pos_x = 640;   data2[3].pos_y = 480;
5300
5301     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5302     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5303     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5304     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5305     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5306     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5307
5308     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5309     {
5310         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5311         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5312            tests[i].name, hr);
5313     }
5314
5315     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5316     {
5317         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5318         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5319
5320         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5321         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5322
5323         hr = IDirect3DDevice9_BeginScene(device);
5324         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5325         drawok = FALSE;
5326         if(SUCCEEDED(hr))
5327         {
5328             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5329             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5330             drawok = SUCCEEDED(hr);
5331             hr = IDirect3DDevice9_EndScene(device);
5332             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5333         }
5334         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5335         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5336
5337         /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5338          * the failure and do not check the color if it failed
5339          */
5340         if(!drawok) {
5341             continue;
5342         }
5343
5344         color = getPixelColor(device, 360, 240);
5345         r = color & 0x00ff0000 >> 16;
5346         g = color & 0x0000ff00 >>  8;
5347         b = color & 0x000000ff;
5348         r_e = tests[i].color & 0x00ff0000 >> 16;
5349         g_e = tests[i].color & 0x0000ff00 >>  8;
5350         b_e = tests[i].color & 0x000000ff;
5351
5352         if(tests[i].todo) {
5353             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5354                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5355                          tests[i].name, color, tests[i].color);
5356         } else {
5357             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5358                "Test %s returned color 0x%08x, expected 0x%08x\n",
5359                tests[i].name, color, tests[i].color);
5360         }
5361     }
5362
5363     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5364     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5365     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5366     {
5367         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5368         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5369
5370         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5371         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5372
5373         hr = IDirect3DDevice9_BeginScene(device);
5374         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5375         if(SUCCEEDED(hr))
5376         {
5377             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5378             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5379             hr = IDirect3DDevice9_EndScene(device);
5380             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5381         }
5382         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5383         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5384
5385         color = getPixelColor(device, 360, 240);
5386         r = color & 0x00ff0000 >> 16;
5387         g = color & 0x0000ff00 >>  8;
5388         b = color & 0x000000ff;
5389         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5390         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
5391         b_e = tests[i].color_rhw & 0x000000ff;
5392
5393         if(tests[i].todo_rhw) {
5394             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5395              * pipeline
5396              */
5397             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5398                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5399                          tests[i].name, color, tests[i].color_rhw);
5400         } else {
5401             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5402                "Test %s returned color 0x%08x, expected 0x%08x\n",
5403                tests[i].name, color, tests[i].color_rhw);
5404         }
5405     }
5406
5407     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5408     {
5409         IDirect3DPixelShader9_Release(tests[i].shader);
5410     }
5411
5412     IDirect3DVertexDeclaration9_Release(decl2);
5413     IDirect3DVertexDeclaration9_Release(decl);
5414 }
5415
5416 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5417     static const DWORD ps_code[] = {
5418     0xffff0300,                                                             /* ps_3_0                       */
5419     0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0          */
5420     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5421     0x0200001f, 0x8001000a, 0x900f0003,                                     /* dcl_color1 v3                */
5422     0x0200001f, 0x8000000b, 0x900f0004,                                     /* dcl_fog v4                   */
5423     0x0200001f, 0x80030005, 0x900f0005,                                     /* dcl_texcoord3 v5             */
5424     0x0200001f, 0x80000003, 0x900f0006,                                     /* dcl_normal v6                */
5425     0x0200001f, 0x80000006, 0x900f0007,                                     /* dcl_tangent v7               */
5426     0x0200001f, 0x80000001, 0x900f0008,                                     /* dcl_blendweight v8           */
5427     0x0200001f, 0x8000000c, 0x900f0009,                                     /* dcl_depth v9                 */
5428
5429     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5430     0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0                  */
5431     0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800,             /* add r0, r0, v0[aL]           */
5432     0x0000001d,                                                             /* endloop                      */
5433     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5434     0x0000ffff                                                              /* end                          */
5435     };
5436     static const DWORD vs_1_code[] = {
5437     0xfffe0101,                                                             /* vs_1_1                       */
5438     0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5439     0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5440     0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5441     0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5442     0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5443     0x00000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5444     0x00000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5445     0x00000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5446     0x00000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5447     0x00000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5448     0x00000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5449     0x00000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5450     0x00000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5451     0x00000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5452     0x00000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5453     0x00000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5454     0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5455     0x0000ffff
5456     };
5457     DWORD vs_2_code[] = {
5458     0xfffe0200,                                                             /* vs_2_0                       */
5459     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5460     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5461     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5462     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5463     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5464     0x02000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5465     0x02000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5466     0x02000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5467     0x02000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5468     0x02000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5469     0x02000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5470     0x02000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5471     0x02000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5472     0x02000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5473     0x02000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5474     0x02000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5475     0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5476     0x0000ffff                                                              /* end                          */
5477     };
5478     /* TODO: Define normal, tangent, blendweight and depth here */
5479     static const DWORD vs_3_code[] = {
5480     0xfffe0300,                                                             /* vs_3_0                       */
5481     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5482     0x0200001f, 0x8001000a, 0xe00f0009,                                     /* dcl_color1 o9                */
5483     0x0200001f, 0x8000000b, 0xe00f0002,                                     /* dcl_fog o2                   */
5484     0x0200001f, 0x80030005, 0xe00f0005,                                     /* dcl_texcoord3 o5             */
5485     0x0200001f, 0x80000000, 0xe00f000b,                                     /* dcl_position o11             */
5486     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5487     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5488     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5489     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5490     0x02000001, 0xe00f0009, 0xa0e40000,                                     /* mov o9, c0                   */
5491     0x02000001, 0xe00f0002, 0xa0e40001,                                     /* mov o2, c1                   */
5492     0x02000001, 0xe00f0005, 0xa0e40002,                                     /* mov o5, c2                   */
5493     0x02000001, 0xe00f000b, 0x90e40000,                                     /* mov o11, v0                  */
5494     0x0000ffff                                                              /* end                          */
5495     };
5496     float quad1[] =  {
5497         -1.0,   -1.0,   0.1,
5498          0.0,   -1.0,   0.1,
5499         -1.0,    0.0,   0.1,
5500          0.0,    0.0,   0.1
5501     };
5502     float quad2[] =  {
5503          0.0,   -1.0,   0.1,
5504          1.0,   -1.0,   0.1,
5505          0.0,    0.0,   0.1,
5506          1.0,    0.0,   0.1
5507     };
5508     float quad3[] =  {
5509         -1.0,    0.0,   0.1,
5510          0.0,    0.0,   0.1,
5511         -1.0,    1.0,   0.1,
5512          0.0,    1.0,   0.1
5513     };
5514
5515     HRESULT hr;
5516     DWORD color;
5517     IDirect3DPixelShader9 *pixelshader = NULL;
5518     IDirect3DVertexShader9 *vs_1_shader = NULL;
5519     IDirect3DVertexShader9 *vs_2_shader = NULL;
5520     IDirect3DVertexShader9 *vs_3_shader = NULL;
5521
5522     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5523
5524     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5525     ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %08x\n", hr);
5526     hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5527     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5528     hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5529     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5530     hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5531     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5532     hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5533     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5534     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5535
5536     hr = IDirect3DDevice9_BeginScene(device);
5537     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5538     if(SUCCEEDED(hr))
5539     {
5540         hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5541         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5542         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5543         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5544
5545         hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5546         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5547         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5548         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5549
5550         hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5551         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5552         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5553         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5554
5555         hr = IDirect3DDevice9_EndScene(device);
5556         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5557     }
5558     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5559     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5560
5561     color = getPixelColor(device, 160, 120);
5562     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x1a, 0x34, 0x67), 1),
5563        "vs_3_0 returned color 0x%08x, expected 0x00193366\n", color);
5564     color = getPixelColor(device, 160, 360);
5565     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1),
5566        "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5567     color = getPixelColor(device, 480, 360);
5568     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1),
5569        "vs_2_0 returned color 0x%08x, expected 0x004c0066\n", color);
5570
5571     /* cleanup */
5572     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5573     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5574     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5575     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5576     if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5577     if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5578     if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5579     if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5580 }
5581
5582 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5583     static const DWORD vs_code[] = {
5584     0xfffe0300,                                                             /* vs_3_0                       */
5585     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5586     0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0              */
5587     0x0200001f, 0x8000000a, 0xe00f0001,                                     /* dcl_color0 o1                */
5588     0x0200001f, 0x80000005, 0xe00f0002,                                     /* dcl_texcoord0 o2             */
5589     0x0200001f, 0x8000000b, 0xe00f0003,                                     /* dcl_fog o3                   */
5590     0x0200001f, 0x80000003, 0xe00f0004,                                     /* dcl_normal o4                */
5591     0x0200001f, 0x8000000c, 0xe00f0005,                                     /* dcl_depth o5                 */
5592     0x0200001f, 0x80000006, 0xe00f0006,                                     /* dcl_tangent o6               */
5593     0x0200001f, 0x80000001, 0xe00f0007,                                     /* dcl_blendweight o7           */
5594     0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0   */
5595     0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0   */
5596     0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0   */
5597     0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0   */
5598
5599     0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                   */
5600     0x02000001, 0xe00f0001, 0xa0e40001,                                     /* mov o1, c1                   */
5601     0x02000001, 0xe00f0002, 0xa0e40002,                                     /* mov o2, c2                   */
5602     0x02000001, 0xe00f0003, 0xa0e40003,                                     /* mov o3, c3                   */
5603     0x02000001, 0xe00f0004, 0xa0e40000,                                     /* mov o4, c0                   */
5604     0x02000001, 0xe00f0005, 0xa0e40000,                                     /* mov o5, c0                   */
5605     0x02000001, 0xe00f0006, 0xa0e40000,                                     /* mov o6, c0                   */
5606     0x02000001, 0xe00f0007, 0xa0e40000,                                     /* mov o7, c0                   */
5607     0x0000ffff                                                              /* end                          */
5608     };
5609     static const DWORD ps_1_code[] = {
5610     0xffff0104,                                                             /* ps_1_4                       */
5611     0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5612     0x00000040, 0x80070001, 0xb0e40000,                                     /* texcrd r1.xyz, t0            */
5613     0x00000001, 0x80080001, 0xa0ff0000,                                     /* mov r1.a, c0.a               */
5614     0x00000002, 0x800f0000, 0x90e40000, 0x80e40001,                         /* add r0, v0, r1               */
5615     0x0000ffff                                                              /* end                          */
5616     };
5617     static const DWORD ps_2_code[] = {
5618     0xffff0200,                                                             /* ps_2_0                       */
5619     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
5620     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl v0                       */
5621     0x0200001f, 0x80000000, 0x900f0001,                                     /* dcl v1                       */
5622
5623     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
5624     0x03000002, 0x800f0000, 0x80e40000,0xb0e40000,                          /* add r0, r0, t0               */
5625     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5626     0x0000ffff                                                              /* end                          */
5627     };
5628     static const DWORD ps_3_code[] = {
5629     0xffff0300,                                                             /* ps_3_0                       */
5630     0x0200001f, 0x80000005, 0x900f0000,                                     /* dcl_texcoord0 v0             */
5631     0x0200001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
5632     0x0200001f, 0x8000000b, 0x900f0002,                                     /* dcl_fog v2                   */
5633
5634     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
5635     0x03000002, 0x800f0000, 0x80e40000, 0x90e40001,                         /* add r0, r0, v1               */
5636     0x03000002, 0x800f0000, 0x80e40000, 0x90e40002,                         /* mov r0, r0, v2               */
5637     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5638     0x0000ffff                                                              /* end                          */
5639     };
5640
5641     float quad1[] =  {
5642         -1.0,   -1.0,   0.1,
5643          0.0,   -1.0,   0.1,
5644         -1.0,    0.0,   0.1,
5645          0.0,    0.0,   0.1
5646     };
5647     float quad2[] =  {
5648          0.0,   -1.0,   0.1,
5649          1.0,   -1.0,   0.1,
5650          0.0,    0.0,   0.1,
5651          1.0,    0.0,   0.1
5652     };
5653     float quad3[] =  {
5654         -1.0,    0.0,   0.1,
5655          0.0,    0.0,   0.1,
5656         -1.0,    1.0,   0.1,
5657          0.0,    1.0,   0.1
5658     };
5659     float quad4[] =  {
5660          0.0,    0.0,   0.1,
5661          1.0,    0.0,   0.1,
5662          0.0,    1.0,   0.1,
5663          1.0,    1.0,   0.1
5664     };
5665
5666     HRESULT hr;
5667     DWORD color;
5668     IDirect3DVertexShader9 *vertexshader = NULL;
5669     IDirect3DPixelShader9 *ps_1_shader = NULL;
5670     IDirect3DPixelShader9 *ps_2_shader = NULL;
5671     IDirect3DPixelShader9 *ps_3_shader = NULL;
5672     IDirect3DTexture9 *texture = NULL;
5673     D3DLOCKED_RECT lr;
5674     unsigned int x, y;
5675
5676     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5677
5678     hr = IDirect3DDevice9_CreateTexture(device, 512,  512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
5679     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5680     if(FAILED(hr)) {
5681         skip("D3DFMT_A16B16G16R16 textures not supported\n");
5682         return;
5683     }
5684     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5685     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
5686     for(y = 0; y < 512; y++) {
5687         for(x = 0; x < 512; x++) {
5688             double r_f = (double) x / (double) 512;
5689             double g_f = (double) y / (double) 512;
5690             unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
5691             unsigned short r = (unsigned short) (r_f * 65535.0);
5692             unsigned short g = (unsigned short) (g_f * 65535.0);
5693             dst[0] = r;
5694             dst[1] = g;
5695             dst[2] = 0;
5696             dst[3] = 65535;
5697         }
5698     }
5699     hr = IDirect3DTexture9_UnlockRect(texture, 0);
5700     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
5701
5702     hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
5703     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5704     hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
5705     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5706     hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
5707     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5708     hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
5709     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5710     hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
5711     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5712     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5713
5714     hr = IDirect3DDevice9_BeginScene(device);
5715     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5716     if(SUCCEEDED(hr))
5717     {
5718         hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
5719         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5720         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5721         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5722
5723         hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
5724         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5725         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5726         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5727
5728         hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
5729         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5730         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5731         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5732
5733         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5734         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5735         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5736         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5737         hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5738         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
5739         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5740         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
5741         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5742         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5743
5744         hr = IDirect3DDevice9_EndScene(device);
5745         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5746     }
5747     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5748     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5749
5750     color = getPixelColor(device, 160, 120);
5751     ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
5752        (color & 0x0000ff00) == 0x0000ff00 &&
5753        (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
5754        "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
5755     color = getPixelColor(device, 160, 360);
5756     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5757        (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
5758        (color & 0x000000ff) == 0x00000000,
5759        "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
5760     color = getPixelColor(device, 480, 360);
5761     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5762        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5763        (color & 0x000000ff) == 0x00000000,
5764        "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
5765     color = getPixelColor(device, 480, 160);
5766     ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
5767        (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5768        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5769        (color & 0x000000ff) == 0x00000000),
5770        "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
5771
5772     /* cleanup */
5773     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5774     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5775     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5776     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5777     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5778     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5779     if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
5780     if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
5781     if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
5782     if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
5783     if(texture) IDirect3DTexture9_Release(texture);
5784 }
5785
5786 static void test_compare_instructions(IDirect3DDevice9 *device)
5787 {
5788     DWORD shader_sge_vec_code[] = {
5789         0xfffe0101,                                         /* vs_1_1                   */
5790         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5791         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5792         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5793         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
5794         0x0000ffff                                          /* end                      */
5795     };
5796     DWORD shader_slt_vec_code[] = {
5797         0xfffe0101,                                         /* vs_1_1                   */
5798         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5799         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5800         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5801         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
5802         0x0000ffff                                          /* end                      */
5803     };
5804     DWORD shader_sge_scalar_code[] = {
5805         0xfffe0101,                                         /* vs_1_1                   */
5806         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5807         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5808         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5809         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
5810         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
5811         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
5812         0x0000ffff                                          /* end                      */
5813     };
5814     DWORD shader_slt_scalar_code[] = {
5815         0xfffe0101,                                         /* vs_1_1                   */
5816         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5817         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5818         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5819         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
5820         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
5821         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
5822         0x0000ffff                                          /* end                      */
5823     };
5824     IDirect3DVertexShader9 *shader_sge_vec;
5825     IDirect3DVertexShader9 *shader_slt_vec;
5826     IDirect3DVertexShader9 *shader_sge_scalar;
5827     IDirect3DVertexShader9 *shader_slt_scalar;
5828     HRESULT hr, color;
5829     float quad1[] =  {
5830         -1.0,   -1.0,   0.1,
5831          0.0,   -1.0,   0.1,
5832         -1.0,    0.0,   0.1,
5833          0.0,    0.0,   0.1
5834     };
5835     float quad2[] =  {
5836          0.0,   -1.0,   0.1,
5837          1.0,   -1.0,   0.1,
5838          0.0,    0.0,   0.1,
5839          1.0,    0.0,   0.1
5840     };
5841     float quad3[] =  {
5842         -1.0,    0.0,   0.1,
5843          0.0,    0.0,   0.1,
5844         -1.0,    1.0,   0.1,
5845          0.0,    1.0,   0.1
5846     };
5847     float quad4[] =  {
5848          0.0,    0.0,   0.1,
5849          1.0,    0.0,   0.1,
5850          0.0,    1.0,   0.1,
5851          1.0,    1.0,   0.1
5852     };
5853     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5854     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5855
5856     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5857
5858     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5859     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5860     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5861     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5862     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5863     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5864     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5865     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5866     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5867     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5868     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5869     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5870     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5871     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5872
5873     hr = IDirect3DDevice9_BeginScene(device);
5874     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5875     if(SUCCEEDED(hr))
5876     {
5877         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5878         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5879         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5880         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5881
5882         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5883         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5884         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5885         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5886
5887         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5888         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5889         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5890         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5891
5892         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5893         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5894
5895         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5896         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5897         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5898         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5899
5900         hr = IDirect3DDevice9_EndScene(device);
5901         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5902     }
5903
5904     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5905     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5906     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5907     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5908
5909     color = getPixelColor(device, 160, 360);
5910     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
5911     color = getPixelColor(device, 480, 360);
5912     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
5913     color = getPixelColor(device, 160, 120);
5914     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
5915     color = getPixelColor(device, 480, 160);
5916     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
5917
5918     IDirect3DVertexShader9_Release(shader_sge_vec);
5919     IDirect3DVertexShader9_Release(shader_slt_vec);
5920     IDirect3DVertexShader9_Release(shader_sge_scalar);
5921     IDirect3DVertexShader9_Release(shader_slt_scalar);
5922 }
5923
5924 static void test_vshader_input(IDirect3DDevice9 *device)
5925 {
5926     DWORD swapped_shader_code_3[] = {
5927         0xfffe0300,                                         /* vs_3_0               */
5928         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5929         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5930         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5931         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5932         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5933         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5934         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5935         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5936         0x0000ffff                                          /* end                  */
5937     };
5938     DWORD swapped_shader_code_1[] = {
5939         0xfffe0101,                                         /* vs_1_1               */
5940         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5941         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5942         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5943         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
5944         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5945         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5946         0x0000ffff                                          /* end                  */
5947     };
5948     DWORD swapped_shader_code_2[] = {
5949         0xfffe0200,                                         /* vs_2_0               */
5950         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5951         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5952         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5953         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
5954         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5955         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5956         0x0000ffff                                          /* end                  */
5957     };
5958     DWORD texcoord_color_shader_code_3[] = {
5959         0xfffe0300,                                         /* vs_3_0               */
5960         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5961         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5962         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5963         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
5964         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5965         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
5966         0x0000ffff                                          /* end                  */
5967     };
5968     DWORD texcoord_color_shader_code_2[] = {
5969         0xfffe0200,                                         /* vs_2_0               */
5970         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5971         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
5972         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5973         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
5974         0x0000ffff                                          /* end                  */
5975     };
5976     DWORD texcoord_color_shader_code_1[] = {
5977         0xfffe0101,                                         /* vs_1_1               */
5978         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5979         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
5980         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5981         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
5982         0x0000ffff                                          /* end                  */
5983     };
5984     DWORD color_color_shader_code_3[] = {
5985         0xfffe0300,                                         /* vs_3_0               */
5986         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5987         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5988         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5989         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
5990         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5991         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
5992         0x0000ffff                                          /* end                  */
5993     };
5994     DWORD color_color_shader_code_2[] = {
5995         0xfffe0200,                                         /* vs_2_0               */
5996         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5997         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
5998         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5999         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6000         0x0000ffff                                          /* end                  */
6001     };
6002     DWORD color_color_shader_code_1[] = {
6003         0xfffe0101,                                         /* vs_1_1               */
6004         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6005         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6006         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6007         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6008         0x0000ffff                                          /* end                  */
6009     };
6010     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6011     HRESULT hr;
6012     DWORD color;
6013     float quad1[] =  {
6014         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6015          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6016         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6017          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6018     };
6019     float quad2[] =  {
6020          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6021          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6022          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6023          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6024     };
6025     float quad3[] =  {
6026         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
6027          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
6028         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
6029          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6030     };
6031     float quad4[] =  {
6032          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6033          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6034          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6035          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6036     };
6037     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6038         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6039         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6040         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6041         D3DDECL_END()
6042     };
6043     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6044         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6045         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6046         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6047         D3DDECL_END()
6048     };
6049     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6050         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6051         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6052         D3DDECL_END()
6053     };
6054     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6055         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6056         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6057         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
6058         D3DDECL_END()
6059     };
6060     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6061         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6062         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6063         D3DDECL_END()
6064     };
6065     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6066         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6067         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6068         D3DDECL_END()
6069     };
6070     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6071         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6072         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6073         D3DDECL_END()
6074     };
6075     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6076         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6077         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6078         D3DDECL_END()
6079     };
6080     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6081     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6082     unsigned int i;
6083     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6084     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6085
6086     struct vertex quad1_color[] =  {
6087        {-1.0,   -1.0,   0.1,    0x00ff8040},
6088        { 0.0,   -1.0,   0.1,    0x00ff8040},
6089        {-1.0,    0.0,   0.1,    0x00ff8040},
6090        { 0.0,    0.0,   0.1,    0x00ff8040}
6091     };
6092     struct vertex quad2_color[] =  {
6093        { 0.0,   -1.0,   0.1,    0x00ff8040},
6094        { 1.0,   -1.0,   0.1,    0x00ff8040},
6095        { 0.0,    0.0,   0.1,    0x00ff8040},
6096        { 1.0,    0.0,   0.1,    0x00ff8040}
6097     };
6098     struct vertex quad3_color[] =  {
6099        {-1.0,    0.0,   0.1,    0x00ff8040},
6100        { 0.0,    0.0,   0.1,    0x00ff8040},
6101        {-1.0,    1.0,   0.1,    0x00ff8040},
6102        { 0.0,    1.0,   0.1,    0x00ff8040}
6103     };
6104     float quad4_color[] =  {
6105          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6106          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6107          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6108          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6109     };
6110
6111     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6112     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6113     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6114     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6115     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6116     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6117     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6118     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6119
6120     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6121     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6122     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6123     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6124     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6125     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6126     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6127     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6128
6129     for(i = 1; i <= 3; i++) {
6130         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6131         if(i == 3) {
6132             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6133             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6134         } else if(i == 2){
6135             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6136             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6137         } else if(i == 1) {
6138             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6139             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6140         }
6141
6142         hr = IDirect3DDevice9_BeginScene(device);
6143         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6144         if(SUCCEEDED(hr))
6145         {
6146             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6147             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6148
6149             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6150             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6151             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6152             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6153
6154             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6155             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6156             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6157             if(i == 3 || i == 2) {
6158                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6159             } else if(i == 1) {
6160                 /* Succeeds or fails, depending on SW or HW vertex processing */
6161                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6162             }
6163
6164             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6165             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6166             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6167             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6168
6169             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6170             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6171             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6172             if(i == 3 || i == 2) {
6173                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6174             } else if(i == 1) {
6175                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6176             }
6177
6178             hr = IDirect3DDevice9_EndScene(device);
6179             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6180         }
6181
6182         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6183         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6184
6185         if(i == 3 || i == 2) {
6186             color = getPixelColor(device, 160, 360);
6187             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6188                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6189
6190             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6191             color = getPixelColor(device, 480, 360);
6192             ok(color == 0x00FFFF00 || color ==0x00FF0000,
6193                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6194             color = getPixelColor(device, 160, 120);
6195             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6196             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6197                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6198
6199             color = getPixelColor(device, 480, 160);
6200             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6201         } else if(i == 1) {
6202             color = getPixelColor(device, 160, 360);
6203             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6204                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6205             color = getPixelColor(device, 480, 360);
6206             /* Accept the clear color as well in this case, since SW VP returns an error */
6207             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6208             color = getPixelColor(device, 160, 120);
6209             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6210                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6211             color = getPixelColor(device, 480, 160);
6212             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6213         }
6214
6215         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6216         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6217
6218         /* Now find out if the whole streams are re-read, or just the last active value for the
6219          * vertices is used.
6220          */
6221         hr = IDirect3DDevice9_BeginScene(device);
6222         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6223         if(SUCCEEDED(hr))
6224         {
6225             float quad1_modified[] =  {
6226                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6227                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6228                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6229                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6230             };
6231             float quad2_modified[] =  {
6232                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6233                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6234                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6235                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6236             };
6237
6238             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6239             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6240
6241             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6242             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6243             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6244             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6245
6246             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6247             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6248             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6249             if(i == 3 || i == 2) {
6250                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6251             } else if(i == 1) {
6252                 /* Succeeds or fails, depending on SW or HW vertex processing */
6253                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6254             }
6255
6256             hr = IDirect3DDevice9_EndScene(device);
6257             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6258         }
6259         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6260         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6261
6262         color = getPixelColor(device, 480, 350);
6263         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6264          * as well.
6265          *
6266          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6267          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6268          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6269          * refrast's result.
6270          *
6271          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6272          */
6273         ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6274            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6275         color = getPixelColor(device, 160, 120);
6276
6277         IDirect3DDevice9_SetVertexShader(device, NULL);
6278         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6279
6280         IDirect3DVertexShader9_Release(swapped_shader);
6281     }
6282
6283     for(i = 1; i <= 3; i++) {
6284         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6285         if(i == 3) {
6286             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6287             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6288             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6289             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6290         } else if(i == 2){
6291             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6292             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6293             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6294             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6295         } else if(i == 1) {
6296             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6297             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6298             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6299             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6300         }
6301
6302         hr = IDirect3DDevice9_BeginScene(device);
6303         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6304         if(SUCCEEDED(hr))
6305         {
6306             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6307             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6308             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6309             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6310             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6311             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6312
6313             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6314             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6315
6316             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6317             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6318             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6319             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6320             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6321             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6322
6323             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6324             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6325             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6326             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6327             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6328             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6329
6330             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6331             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6332             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6333             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6334
6335             hr = IDirect3DDevice9_EndScene(device);
6336             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6337         }
6338         IDirect3DDevice9_SetVertexShader(device, NULL);
6339         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6340
6341         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6342         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6343
6344         color = getPixelColor(device, 160, 360);
6345         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6346            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6347         color = getPixelColor(device, 480, 360);
6348         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6349            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6350         color = getPixelColor(device, 160, 120);
6351         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6352            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6353         color = getPixelColor(device, 480, 160);
6354         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6355            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6356
6357         IDirect3DVertexShader9_Release(texcoord_color_shader);
6358         IDirect3DVertexShader9_Release(color_color_shader);
6359     }
6360
6361     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6362     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6363     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6364     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6365
6366     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6367     IDirect3DVertexDeclaration9_Release(decl_color_color);
6368     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6369     IDirect3DVertexDeclaration9_Release(decl_color_float);
6370 }
6371
6372 static void srgbtexture_test(IDirect3DDevice9 *device)
6373 {
6374     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6375      * texture stage state to render a quad using that texture.  The resulting
6376      * color components should be 0x36 (~ 0.21), per this formula:
6377      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6378      * This is true where srgb_color > 0.04045.
6379      */
6380     IDirect3D9 *d3d = NULL;
6381     HRESULT hr;
6382     LPDIRECT3DTEXTURE9 texture = NULL;
6383     LPDIRECT3DSURFACE9 surface = NULL;
6384     D3DLOCKED_RECT lr;
6385     DWORD color;
6386     float quad[] = {
6387         -1.0,       1.0,       0.0,     0.0,    0.0,
6388          1.0,       1.0,       0.0,     1.0,    0.0,
6389         -1.0,      -1.0,       0.0,     0.0,    1.0,
6390          1.0,      -1.0,       0.0,     1.0,    1.0,
6391     };
6392
6393
6394     memset(&lr, 0, sizeof(lr));
6395     IDirect3DDevice9_GetDirect3D(device, &d3d);
6396     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6397                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6398                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6399         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6400         goto out;
6401     }
6402
6403     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6404                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6405                                         &texture, NULL);
6406     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6407     if(!texture) {
6408         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6409         goto out;
6410     }
6411     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6412     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6413
6414     fill_surface(surface, 0xff7f7f7f);
6415     IDirect3DSurface9_Release(surface);
6416
6417     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6418     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6419     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6420     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6421
6422     hr = IDirect3DDevice9_BeginScene(device);
6423     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6424     if(SUCCEEDED(hr))
6425     {
6426         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6427         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6428
6429         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6430         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6431
6432
6433         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6434         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6435
6436         hr = IDirect3DDevice9_EndScene(device);
6437         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6438     }
6439
6440     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6441     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6442     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6443     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6444
6445     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6446     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6447
6448     color = getPixelColor(device, 320, 240);
6449     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6450
6451 out:
6452     if(texture) IDirect3DTexture9_Release(texture);
6453     IDirect3D9_Release(d3d);
6454 }
6455
6456 static void shademode_test(IDirect3DDevice9 *device)
6457 {
6458     /* Render a quad and try all of the different fixed function shading models. */
6459     HRESULT hr;
6460     DWORD color0, color1;
6461     DWORD color0_gouraud = 0, color1_gouraud = 0;
6462     DWORD shademode = D3DSHADE_FLAT;
6463     DWORD primtype = D3DPT_TRIANGLESTRIP;
6464     LPVOID data = NULL;
6465     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6466     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6467     UINT i, j;
6468     struct vertex quad_strip[] =
6469     {
6470         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6471         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6472         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6473         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6474     };
6475     struct vertex quad_list[] =
6476     {
6477         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6478         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6479         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6480
6481         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6482         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6483         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6484     };
6485
6486     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6487                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6488     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6489     if (FAILED(hr)) goto bail;
6490
6491     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6492                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6493     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6494     if (FAILED(hr)) goto bail;
6495
6496     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6497     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6498
6499     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6500     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6501
6502     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6503     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6504     memcpy(data, quad_strip, sizeof(quad_strip));
6505     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6506     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6507
6508     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6509     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6510     memcpy(data, quad_list, sizeof(quad_list));
6511     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6512     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6513
6514     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
6515      * the color fixups we have to do for FLAT shading will be dependent on that. */
6516     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6517     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6518
6519     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6520     for (j=0; j<2; j++) {
6521
6522         /* Inner loop just changes the D3DRS_SHADEMODE */
6523         for (i=0; i<3; i++) {
6524             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6525             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6526
6527             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6528             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6529
6530             hr = IDirect3DDevice9_BeginScene(device);
6531             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6532             if(SUCCEEDED(hr))
6533             {
6534                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6535                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6536
6537                 hr = IDirect3DDevice9_EndScene(device);
6538                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6539             }
6540
6541             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6542             ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6543
6544             /* Sample two spots from the output */
6545             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6546             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6547             switch(shademode) {
6548                 case D3DSHADE_FLAT:
6549                     /* Should take the color of the first vertex of each triangle */
6550                     todo_wine ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000 (todo)\n", color0);
6551                     todo_wine ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00 (todo)\n", color1);
6552                     shademode = D3DSHADE_GOURAUD;
6553                     break;
6554                 case D3DSHADE_GOURAUD:
6555                     /* Should be an interpolated blend */
6556
6557                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6558                        "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6559                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6560                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6561
6562                     color0_gouraud = color0;
6563                     color1_gouraud = color1;
6564
6565                     shademode = D3DSHADE_PHONG;
6566                     break;
6567                 case D3DSHADE_PHONG:
6568                     /* Should be the same as GOURAUD, since no hardware implements this */
6569                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6570                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6571                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6572                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6573
6574                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6575                             color0_gouraud, color0);
6576                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6577                             color1_gouraud, color1);
6578                     break;
6579             }
6580         }
6581         /* Now, do it all over again with a TRIANGLELIST */
6582         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6583         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6584         primtype = D3DPT_TRIANGLELIST;
6585         shademode = D3DSHADE_FLAT;
6586     }
6587
6588 bail:
6589     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6590     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6591     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6592     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6593
6594     if (vb_strip)
6595         IDirect3DVertexBuffer9_Release(vb_strip);
6596     if (vb_list)
6597         IDirect3DVertexBuffer9_Release(vb_list);
6598 }
6599
6600
6601 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
6602 {
6603     /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
6604      * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
6605      * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
6606      * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
6607      * 0.73
6608      *
6609      * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
6610      * so use shaders for this task
6611      */
6612     IDirect3DPixelShader9 *pshader;
6613     IDirect3DVertexShader9 *vshader;
6614     IDirect3D9 *d3d;
6615     DWORD vshader_code[] = {
6616         0xfffe0101,                                                             /* vs_1_1                       */
6617         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
6618         0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0   */
6619         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
6620         0x00000001, 0xc00f0001, 0xa0000000,                                     /* mov oFog, c0.x               */
6621         0x0000ffff                                                              /* end                          */
6622     };
6623     DWORD pshader_code[] = {
6624         0xffff0101,                                                             /* ps_1_1                       */
6625         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
6626         0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
6627         0x0000ffff                                                              /* end                          */
6628     };
6629     const float quad[] = {
6630        -1.0,   -1.0,    0.1,
6631         1.0,   -1.0,    0.1,
6632        -1.0,    1.0,    0.1,
6633         1.0,    1.0,    0.1
6634     };
6635     HRESULT hr;
6636     DWORD color;
6637
6638     IDirect3DDevice9_GetDirect3D(device, &d3d);
6639     /* Ask for srgb writing on D3DRTYPE_TEXTURE. Some Windows drivers do not report it on surfaces.
6640      * For some not entirely understood reasons D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE
6641      * passes on surfaces, while asking for SRGBWRITE alone fails. Textures advertize srgb writing
6642      * alone as well, so use that since it is not the point of this test to show how CheckDeviceFormat
6643      * works
6644      */
6645     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6646                                     D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
6647                                     D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK) {
6648         skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
6649         IDirect3D9_Release(d3d);
6650         return;
6651     }
6652     IDirect3D9_Release(d3d);
6653
6654     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6655     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6656
6657     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6658     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6659     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
6660     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6661     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
6662     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6663     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
6664     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6665     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
6666     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6667
6668     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6669     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6670     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
6671     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6672     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6673     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6674     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6675     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6676     hr = IDirect3DDevice9_SetPixelShader(device, pshader);
6677     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6678
6679     hr = IDirect3DDevice9_BeginScene(device);
6680     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6681     if(SUCCEEDED(hr)) {
6682         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
6683         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6684
6685         hr = IDirect3DDevice9_EndScene(device);
6686         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6687     }
6688
6689     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6690     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6691     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6692     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6693     IDirect3DPixelShader9_Release(pshader);
6694     IDirect3DVertexShader9_Release(vshader);
6695
6696     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
6697     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6698     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
6699     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6700
6701     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6702     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6703     color = getPixelColor(device, 160, 360);
6704     ok(color == 0x00808080 || color == 0x007f7f7f || color == 0x00818181,
6705        "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
6706 }
6707
6708 static void alpha_test(IDirect3DDevice9 *device)
6709 {
6710     HRESULT hr;
6711     IDirect3DTexture9 *offscreenTexture;
6712     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6713     DWORD color;
6714
6715     struct vertex quad1[] =
6716     {
6717         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
6718         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
6719         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
6720         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
6721     };
6722     struct vertex quad2[] =
6723     {
6724         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
6725         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
6726         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
6727         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
6728     };
6729     static const float composite_quad[][5] = {
6730         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6731         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
6732         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6733         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
6734     };
6735
6736     /* Clear the render target with alpha = 0.5 */
6737     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6738     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6739
6740     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6741     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6742
6743     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6744     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6745     if(!backbuffer) {
6746         goto out;
6747     }
6748
6749     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6750     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6751     if(!offscreen) {
6752         goto out;
6753     }
6754
6755     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6756     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6757
6758     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6759     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6760     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6761     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6762     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6763     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6764     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6765     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6766     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6767     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6768
6769     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6770     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6771     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6772
6773         /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6774         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6775         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6776         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6777         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6778         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6779         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6780
6781         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6782         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6783         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6784         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6785         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6786         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6787
6788         /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6789          * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6790          * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6791         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6792         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6793         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6794         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6795
6796         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6797         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6798         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6799         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6800         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6801         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6802
6803         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6804         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6805         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6806         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6807         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6808         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6809
6810         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6811         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6812
6813         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6814          * Disable alpha blending for the final composition
6815          */
6816         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6817         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6818         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6819         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6820
6821         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6822         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6823         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6824         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6825         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6826         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6827
6828         hr = IDirect3DDevice9_EndScene(device);
6829         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6830     }
6831
6832     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6833
6834     color = getPixelColor(device, 160, 360);
6835     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6836        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6837
6838     color = getPixelColor(device, 160, 120);
6839     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
6840        "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
6841
6842     color = getPixelColor(device, 480, 360);
6843     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6844        "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
6845
6846     color = getPixelColor(device, 480, 120);
6847     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
6848        "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
6849
6850     out:
6851     /* restore things */
6852     if(backbuffer) {
6853         IDirect3DSurface9_Release(backbuffer);
6854     }
6855     if(offscreenTexture) {
6856         IDirect3DTexture9_Release(offscreenTexture);
6857     }
6858     if(offscreen) {
6859         IDirect3DSurface9_Release(offscreen);
6860     }
6861 }
6862
6863 struct vertex_shortcolor {
6864     float x, y, z;
6865     unsigned short r, g, b, a;
6866 };
6867 struct vertex_floatcolor {
6868     float x, y, z;
6869     float r, g, b, a;
6870 };
6871
6872 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6873 {
6874     HRESULT hr;
6875     BOOL s_ok, ub_ok, f_ok;
6876     DWORD color, size, i;
6877     void *data;
6878     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6879         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6880         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6881         D3DDECL_END()
6882     };
6883     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6884         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6885         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6886         D3DDECL_END()
6887     };
6888     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6889         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6890         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6891         D3DDECL_END()
6892     };
6893     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6894         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6895         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6896         D3DDECL_END()
6897     };
6898     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6899         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6900         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6901         D3DDECL_END()
6902     };
6903     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6904         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6905         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6906         D3DDECL_END()
6907     };
6908     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6909         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
6910         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6911         D3DDECL_END()
6912     };
6913     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6914     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6915     IDirect3DVertexBuffer9 *vb, *vb2;
6916     struct vertex quad1[] =                             /* D3DCOLOR */
6917     {
6918         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
6919         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6920         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
6921         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6922     };
6923     struct vertex quad2[] =                             /* UBYTE4N */
6924     {
6925         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6926         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
6927         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6928         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
6929     };
6930     struct vertex_shortcolor quad3[] =                  /* short */
6931     {
6932         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6933         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6934         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6935         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6936     };
6937     struct vertex_floatcolor quad4[] =
6938     {
6939         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6940         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6941         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6942         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6943     };
6944     DWORD colors[] = {
6945         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6946         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6947         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6948         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6949         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6950         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6951         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6952         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6953         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6954         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6955         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6956         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6957         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6958         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6959         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6960         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6961     };
6962     float quads[] = {
6963         -1.0,   -1.0,     0.1,
6964         -1.0,    0.0,     0.1,
6965          0.0,   -1.0,     0.1,
6966          0.0,    0.0,     0.1,
6967
6968          0.0,   -1.0,     0.1,
6969          0.0,    0.0,     0.1,
6970          1.0,   -1.0,     0.1,
6971          1.0,    0.0,     0.1,
6972
6973          0.0,    0.0,     0.1,
6974          0.0,    1.0,     0.1,
6975          1.0,    0.0,     0.1,
6976          1.0,    1.0,     0.1,
6977
6978         -1.0,    0.0,     0.1,
6979         -1.0,    1.0,     0.1,
6980          0.0,    0.0,     0.1,
6981          0.0,    1.0,     0.1
6982     };
6983     struct tvertex quad_transformed[] = {
6984        {  90,    110,     0.1,      2.0,        0x00ffff00},
6985        { 570,    110,     0.1,      2.0,        0x00ffff00},
6986        {  90,    300,     0.1,      2.0,        0x00ffff00},
6987        { 570,    300,     0.1,      2.0,        0x00ffff00}
6988     };
6989     D3DCAPS9 caps;
6990
6991     memset(&caps, 0, sizeof(caps));
6992     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6993     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
6994
6995     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6996     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6997
6998     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
6999     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7000     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7001     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7002     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7003     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7004     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7005         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7006         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7007         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7008         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7009     } else {
7010         trace("D3DDTCAPS_UBYTE4N not supported\n");
7011         dcl_ubyte_2 = NULL;
7012         dcl_ubyte = NULL;
7013     }
7014     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7015     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7016     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7017     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7018
7019     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7020     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7021                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
7022     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7023
7024     hr = IDirect3DDevice9_BeginScene(device);
7025     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7026     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7027     if(SUCCEEDED(hr)) {
7028         if(dcl_color) {
7029             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7030             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7031             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7032             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7033         }
7034
7035         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7036          * accepts them, the nvidia driver accepts them all. All those differences even though we're
7037          * using software vertex processing. Doh!
7038          */
7039         if(dcl_ubyte) {
7040             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7041             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7042             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7043             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7044             ub_ok = SUCCEEDED(hr);
7045         }
7046
7047         if(dcl_short) {
7048             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7049             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7050             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7051             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7052             s_ok = SUCCEEDED(hr);
7053         }
7054
7055         if(dcl_float) {
7056             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7057             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7058             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7059             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7060             f_ok = SUCCEEDED(hr);
7061         }
7062
7063         hr = IDirect3DDevice9_EndScene(device);
7064         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7065     }
7066
7067     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7068     if(dcl_short) {
7069         color = getPixelColor(device, 480, 360);
7070         ok(color == 0x000000ff || !s_ok,
7071            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7072     }
7073     if(dcl_ubyte) {
7074         color = getPixelColor(device, 160, 120);
7075         ok(color == 0x0000ffff || !ub_ok,
7076            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7077     }
7078     if(dcl_color) {
7079         color = getPixelColor(device, 160, 360);
7080         ok(color == 0x00ffff00,
7081            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7082     }
7083     if(dcl_float) {
7084         color = getPixelColor(device, 480, 120);
7085         ok(color == 0x00ff0000 || !f_ok,
7086            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7087     }
7088
7089     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7090      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7091      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7092      * whether the immediate mode code works
7093      */
7094     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7095     hr = IDirect3DDevice9_BeginScene(device);
7096     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7097     if(SUCCEEDED(hr)) {
7098         if(dcl_color) {
7099             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7100             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7101             memcpy(data, quad1, sizeof(quad1));
7102             hr = IDirect3DVertexBuffer9_Unlock(vb);
7103             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7104             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7105             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7106             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7107             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7108             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7109             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7110         }
7111
7112         if(dcl_ubyte) {
7113             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7114             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7115             memcpy(data, quad2, sizeof(quad2));
7116             hr = IDirect3DVertexBuffer9_Unlock(vb);
7117             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7118             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7119             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7120             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7121             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7122             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7123             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7124                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7125             ub_ok = SUCCEEDED(hr);
7126         }
7127
7128         if(dcl_short) {
7129             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7130             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7131             memcpy(data, quad3, sizeof(quad3));
7132             hr = IDirect3DVertexBuffer9_Unlock(vb);
7133             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7134             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7135             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7136             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7137             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7138             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7139             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7140                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7141             s_ok = SUCCEEDED(hr);
7142         }
7143
7144         if(dcl_float) {
7145             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7146             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7147             memcpy(data, quad4, sizeof(quad4));
7148             hr = IDirect3DVertexBuffer9_Unlock(vb);
7149             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7150             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7151             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7152             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7153             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7154             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7155             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7156                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7157             f_ok = SUCCEEDED(hr);
7158         }
7159
7160         hr = IDirect3DDevice9_EndScene(device);
7161         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7162     }
7163
7164     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7165     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7166     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7167     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7168
7169     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7170     if(dcl_short) {
7171         color = getPixelColor(device, 480, 360);
7172         ok(color == 0x000000ff || !s_ok,
7173            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7174     }
7175     if(dcl_ubyte) {
7176         color = getPixelColor(device, 160, 120);
7177         ok(color == 0x0000ffff || !ub_ok,
7178            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7179     }
7180     if(dcl_color) {
7181         color = getPixelColor(device, 160, 360);
7182         ok(color == 0x00ffff00,
7183            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7184     }
7185     if(dcl_float) {
7186         color = getPixelColor(device, 480, 120);
7187         ok(color == 0x00ff0000 || !f_ok,
7188            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7189     }
7190
7191     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7192     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7193
7194     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7195     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7196     memcpy(data, quad_transformed, sizeof(quad_transformed));
7197     hr = IDirect3DVertexBuffer9_Unlock(vb);
7198     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7199
7200     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7201     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7202
7203     hr = IDirect3DDevice9_BeginScene(device);
7204     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7205     if(SUCCEEDED(hr)) {
7206         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7207         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7208         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7209         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7210
7211         hr = IDirect3DDevice9_EndScene(device);
7212         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7213     }
7214
7215     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7216     color = getPixelColor(device, 88, 108);
7217     ok(color == 0x000000ff,
7218        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7219     color = getPixelColor(device, 92, 108);
7220     ok(color == 0x000000ff,
7221        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7222     color = getPixelColor(device, 88, 112);
7223     ok(color == 0x000000ff,
7224        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7225     color = getPixelColor(device, 92, 112);
7226     ok(color == 0x00ffff00,
7227        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7228
7229     color = getPixelColor(device, 568, 108);
7230     ok(color == 0x000000ff,
7231        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7232     color = getPixelColor(device, 572, 108);
7233     ok(color == 0x000000ff,
7234        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7235     color = getPixelColor(device, 568, 112);
7236     ok(color == 0x00ffff00,
7237        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7238     color = getPixelColor(device, 572, 112);
7239     ok(color == 0x000000ff,
7240        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7241
7242     color = getPixelColor(device, 88, 298);
7243     ok(color == 0x000000ff,
7244        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7245     color = getPixelColor(device, 92, 298);
7246     ok(color == 0x00ffff00,
7247        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7248     color = getPixelColor(device, 88, 302);
7249     ok(color == 0x000000ff,
7250        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7251     color = getPixelColor(device, 92, 302);
7252     ok(color == 0x000000ff,
7253        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7254
7255     color = getPixelColor(device, 568, 298);
7256     ok(color == 0x00ffff00,
7257        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7258     color = getPixelColor(device, 572, 298);
7259     ok(color == 0x000000ff,
7260        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7261     color = getPixelColor(device, 568, 302);
7262     ok(color == 0x000000ff,
7263        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7264     color = getPixelColor(device, 572, 302);
7265     ok(color == 0x000000ff,
7266        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7267
7268     /* This test is pointless without those two declarations: */
7269     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7270         skip("color-ubyte switching test declarations aren't supported\n");
7271         goto out;
7272     }
7273
7274     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7275     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7276     memcpy(data, quads, sizeof(quads));
7277     hr = IDirect3DVertexBuffer9_Unlock(vb);
7278     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7279     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7280                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7281     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7282     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7283     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7284     memcpy(data, colors, sizeof(colors));
7285     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7286     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7287
7288     for(i = 0; i < 2; i++) {
7289         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7290         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7291
7292         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7293         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7294         if(i == 0) {
7295             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7296         } else {
7297             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7298         }
7299         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7300
7301         hr = IDirect3DDevice9_BeginScene(device);
7302         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7303         ub_ok = FALSE;
7304         if(SUCCEEDED(hr)) {
7305             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7306             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7307             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7308             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7309                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7310             ub_ok = SUCCEEDED(hr);
7311
7312             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7313             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7314             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7315             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7316
7317             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7318             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7319             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7320             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7321                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7322             ub_ok = (SUCCEEDED(hr) && ub_ok);
7323
7324             hr = IDirect3DDevice9_EndScene(device);
7325             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7326         }
7327
7328         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7329         if(i == 0) {
7330             color = getPixelColor(device, 480, 360);
7331             ok(color == 0x00ff0000,
7332                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7333             color = getPixelColor(device, 160, 120);
7334             ok(color == 0x00ffffff,
7335                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7336             color = getPixelColor(device, 160, 360);
7337             ok(color == 0x000000ff || !ub_ok,
7338                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7339             color = getPixelColor(device, 480, 120);
7340             ok(color == 0x000000ff || !ub_ok,
7341                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7342         } else {
7343             color = getPixelColor(device, 480, 360);
7344             ok(color == 0x000000ff,
7345                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7346             color = getPixelColor(device, 160, 120);
7347             ok(color == 0x00ffffff,
7348                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7349             color = getPixelColor(device, 160, 360);
7350             ok(color == 0x00ff0000 || !ub_ok,
7351                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7352             color = getPixelColor(device, 480, 120);
7353             ok(color == 0x00ff0000 || !ub_ok,
7354                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7355         }
7356     }
7357
7358     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7359     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7360     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7361     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7362     IDirect3DVertexBuffer9_Release(vb2);
7363
7364     out:
7365     IDirect3DVertexBuffer9_Release(vb);
7366     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7367     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7368     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7369     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7370     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7371     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7372     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7373 }
7374
7375 struct vertex_float16color {
7376     float x, y, z;
7377     DWORD c1, c2;
7378 };
7379
7380 static void test_vshader_float16(IDirect3DDevice9 *device)
7381 {
7382     HRESULT hr;
7383     DWORD color;
7384     void *data;
7385     static const D3DVERTEXELEMENT9 decl_elements[] = {
7386         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7387         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7388         D3DDECL_END()
7389     };
7390     IDirect3DVertexDeclaration9 *vdecl = NULL;
7391     IDirect3DVertexBuffer9 *buffer = NULL;
7392     IDirect3DVertexShader9 *shader;
7393     DWORD shader_code[] = {
7394         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7395         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7396         0x90e40001, 0x0000ffff
7397     };
7398     struct vertex_float16color quad[] = {
7399         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7400         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7401         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7402         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7403
7404         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7405         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7406         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7407         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7408
7409         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7410         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7411         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7412         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7413
7414         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7415         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7416         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7417         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7418     };
7419
7420     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7421     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7422
7423     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7424     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7425     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7426     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7427     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7428     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7429
7430     hr = IDirect3DDevice9_BeginScene(device);
7431     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7432     if(SUCCEEDED(hr)) {
7433         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7434         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7435         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7436         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7437         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7438         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7439         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7440         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7441         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7442         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7443
7444         hr = IDirect3DDevice9_EndScene(device);
7445         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7446     }
7447     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7448     color = getPixelColor(device, 480, 360);
7449     ok(color == 0x00ff0000,
7450        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7451     color = getPixelColor(device, 160, 120);
7452     ok(color == 0x00000000,
7453        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7454     color = getPixelColor(device, 160, 360);
7455     ok(color == 0x0000ff00,
7456        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7457     color = getPixelColor(device, 480, 120);
7458     ok(color == 0x000000ff,
7459        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7460
7461     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7462     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7463
7464     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7465                                              D3DPOOL_MANAGED, &buffer, NULL);
7466     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7467     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7468     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7469     memcpy(data, quad, sizeof(quad));
7470     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7471     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7472     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7473     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7474
7475     hr = IDirect3DDevice9_BeginScene(device);
7476     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7477     if(SUCCEEDED(hr)) {
7478             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7479             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7480             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7481             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7482             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7483             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7484             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7485             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7486
7487             hr = IDirect3DDevice9_EndScene(device);
7488             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7489     }
7490
7491     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7492     color = getPixelColor(device, 480, 360);
7493     ok(color == 0x00ff0000,
7494        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7495     color = getPixelColor(device, 160, 120);
7496     ok(color == 0x00000000,
7497        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7498     color = getPixelColor(device, 160, 360);
7499     ok(color == 0x0000ff00,
7500        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7501     color = getPixelColor(device, 480, 120);
7502     ok(color == 0x000000ff,
7503        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7504
7505     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7506     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7507     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7508     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7509     IDirect3DDevice9_SetVertexShader(device, NULL);
7510     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7511
7512     IDirect3DVertexDeclaration9_Release(vdecl);
7513     IDirect3DVertexShader9_Release(shader);
7514     IDirect3DVertexBuffer9_Release(buffer);
7515 }
7516
7517 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7518 {
7519     D3DCAPS9 caps;
7520     IDirect3DTexture9 *texture;
7521     HRESULT hr;
7522     D3DLOCKED_RECT rect;
7523     unsigned int x, y;
7524     DWORD *dst, color;
7525     const float quad[] = {
7526         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
7527          1.0,   -1.0,   0.1,    1.2,   -0.2,
7528         -1.0,    1.0,   0.1,   -0.2,    1.2,
7529          1.0,    1.0,   0.1,    1.2,    1.2
7530     };
7531     memset(&caps, 0, sizeof(caps));
7532
7533     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7534     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7535     if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7536         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7537         ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7538            "Card has conditional NP2 support without power of two restriction set\n");
7539         skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7540         return;
7541     } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7542         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7543         return;
7544     }
7545
7546     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7547     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7548
7549     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7550     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7551
7552     memset(&rect, 0, sizeof(rect));
7553     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7554     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7555     for(y = 0; y < 10; y++) {
7556         for(x = 0; x < 10; x++) {
7557             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7558             if(x == 0 || x == 9 || y == 0 || y == 9) {
7559                 *dst = 0x00ff0000;
7560             } else {
7561                 *dst = 0x000000ff;
7562             }
7563         }
7564     }
7565     hr = IDirect3DTexture9_UnlockRect(texture, 0);
7566     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7567
7568     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7569     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7570     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7571     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7572     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7573     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7574     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7575     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7576
7577     hr = IDirect3DDevice9_BeginScene(device);
7578     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7579     if(SUCCEEDED(hr)) {
7580         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7581         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7582
7583         hr = IDirect3DDevice9_EndScene(device);
7584         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7585     }
7586
7587     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7588
7589     color = getPixelColor(device,    1,  1);
7590     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
7591     color = getPixelColor(device, 639, 479);
7592     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7593
7594     color = getPixelColor(device, 135, 101);
7595     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7596     color = getPixelColor(device, 140, 101);
7597     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7598     color = getPixelColor(device, 135, 105);
7599     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7600     color = getPixelColor(device, 140, 105);
7601     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7602
7603     color = getPixelColor(device, 135, 376);
7604     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7605     color = getPixelColor(device, 140, 376);
7606     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7607     color = getPixelColor(device, 135, 379);
7608     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7609     color = getPixelColor(device, 140, 379);
7610     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7611
7612     color = getPixelColor(device, 500, 101);
7613     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7614     color = getPixelColor(device, 504, 101);
7615     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7616     color = getPixelColor(device, 500, 105);
7617     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7618     color = getPixelColor(device, 504, 105);
7619     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7620
7621     color = getPixelColor(device, 500, 376);
7622     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7623     color = getPixelColor(device, 504, 376);
7624     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7625     color = getPixelColor(device, 500, 380);
7626     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7627     color = getPixelColor(device, 504, 380);
7628     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7629
7630     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7631     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7632     IDirect3DTexture9_Release(texture);
7633 }
7634
7635 static void vFace_register_test(IDirect3DDevice9 *device)
7636 {
7637     HRESULT hr;
7638     DWORD color;
7639     const DWORD shader_code[] = {
7640         0xffff0300,                                                             /* ps_3_0                     */
7641         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7642         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7643         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
7644         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
7645         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
7646         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
7647         0x0000ffff                                                              /* END                        */
7648     };
7649     IDirect3DPixelShader9 *shader;
7650     IDirect3DTexture9 *texture;
7651     IDirect3DSurface9 *surface, *backbuffer;
7652     const float quad[] = {
7653         -1.0,   -1.0,   0.1,
7654          1.0,   -1.0,   0.1,
7655         -1.0,    0.0,   0.1,
7656
7657          1.0,   -1.0,   0.1,
7658          1.0,    0.0,   0.1,
7659         -1.0,    0.0,   0.1,
7660
7661         -1.0,    0.0,   0.1,
7662         -1.0,    1.0,   0.1,
7663          1.0,    0.0,   0.1,
7664
7665          1.0,    0.0,   0.1,
7666         -1.0,    1.0,   0.1,
7667          1.0,    1.0,   0.1,
7668     };
7669     const float blit[] = {
7670          0.0,   -1.0,   0.1,    0.0,    0.0,
7671          1.0,   -1.0,   0.1,    1.0,    0.0,
7672          0.0,    1.0,   0.1,    0.0,    1.0,
7673          1.0,    1.0,   0.1,    1.0,    1.0,
7674     };
7675
7676     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7677     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7678     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7679     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7680     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7681     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7682     hr = IDirect3DDevice9_SetPixelShader(device, shader);
7683     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7684     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7685     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7686     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7687     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7688
7689     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7690     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7691
7692     hr = IDirect3DDevice9_BeginScene(device);
7693     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7694     if(SUCCEEDED(hr)) {
7695         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7696         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7697         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7698         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7699         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7700         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7701         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7702         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7703         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7704         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7705         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7706
7707         /* Blit the texture onto the back buffer to make it visible */
7708         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7709         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7710         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7711         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7712         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7713         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7714         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7715         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7716         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7717         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7718
7719         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7720         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7721
7722         hr = IDirect3DDevice9_EndScene(device);
7723         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7724     }
7725
7726     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7727     color = getPixelColor(device, 160, 360);
7728     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7729     color = getPixelColor(device, 160, 120);
7730     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7731     color = getPixelColor(device, 480, 360);
7732     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7733     color = getPixelColor(device, 480, 120);
7734     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7735
7736     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7737     IDirect3DDevice9_SetTexture(device, 0, NULL);
7738     IDirect3DPixelShader9_Release(shader);
7739     IDirect3DSurface9_Release(surface);
7740     IDirect3DSurface9_Release(backbuffer);
7741     IDirect3DTexture9_Release(texture);
7742 }
7743
7744 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7745 {
7746     HRESULT hr;
7747     DWORD color;
7748     int i;
7749     D3DCAPS9 caps;
7750     BOOL L6V5U5_supported = FALSE;
7751     IDirect3DTexture9 *tex1, *tex2;
7752     D3DLOCKED_RECT locked_rect;
7753
7754     static const float quad[][7] = {
7755         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7756         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7757         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7758         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7759     };
7760
7761     static const D3DVERTEXELEMENT9 decl_elements[] = {
7762         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7763         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7764         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7765         D3DDECL_END()
7766     };
7767
7768     /* use asymmetric matrix to test loading */
7769     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7770     float scale, offset;
7771
7772     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7773     IDirect3DTexture9           *texture            = NULL;
7774
7775     memset(&caps, 0, sizeof(caps));
7776     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7777     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7778     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7779         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7780         return;
7781     } else {
7782         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7783          * They report that it is not supported, but after that bump mapping works properly. So just test
7784          * if the format is generally supported, and check the BUMPENVMAP flag
7785          */
7786         IDirect3D9 *d3d9;
7787
7788         IDirect3DDevice9_GetDirect3D(device, &d3d9);
7789         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7790                                           D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
7791         L6V5U5_supported = SUCCEEDED(hr);
7792         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7793                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7794         IDirect3D9_Release(d3d9);
7795         if(FAILED(hr)) {
7796             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7797             return;
7798         }
7799     }
7800
7801     /* Generate the textures */
7802     generate_bumpmap_textures(device);
7803
7804     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7805     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7806     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7807     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7808     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7809     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7810     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7811     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7812
7813     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7814     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7815     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7816     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7817     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7818     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7819
7820     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7821     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7822     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7823     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7824     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7825     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7826
7827     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7828     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7829
7830     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7831     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7832
7833     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7834     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7835
7836
7837     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7838     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7839     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7840     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7841
7842     hr = IDirect3DDevice9_BeginScene(device);
7843     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7844
7845     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7846     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7847
7848     hr = IDirect3DDevice9_EndScene(device);
7849     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7850
7851     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7852     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7853
7854     /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
7855      * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
7856      * But since testing the color match is not the purpose of the test don't be too picky
7857      */
7858     color = getPixelColor(device, 320-32, 240);
7859     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7860     color = getPixelColor(device, 320+32, 240);
7861     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7862     color = getPixelColor(device, 320, 240-32);
7863     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7864     color = getPixelColor(device, 320, 240+32);
7865     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7866     color = getPixelColor(device, 320, 240);
7867     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7868     color = getPixelColor(device, 320+32, 240+32);
7869     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7870     color = getPixelColor(device, 320-32, 240+32);
7871     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7872     color = getPixelColor(device, 320+32, 240-32);
7873     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7874     color = getPixelColor(device, 320-32, 240-32);
7875     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7876
7877     for(i = 0; i < 2; i++) {
7878         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7879         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7880         IDirect3DTexture9_Release(texture); /* For the GetTexture */
7881         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7882         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7883         IDirect3DTexture9_Release(texture); /* To destroy it */
7884     }
7885
7886     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
7887         skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
7888         goto cleanup;
7889     }
7890     if(L6V5U5_supported == FALSE) {
7891         skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
7892         goto cleanup;
7893     }
7894
7895     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
7896     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7897     /* This test only tests the luminance part. The bumpmapping part was already tested above and
7898      * would only make this test more complicated
7899      */
7900     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
7901     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7902     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
7903     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7904
7905     memset(&locked_rect, 0, sizeof(locked_rect));
7906     hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
7907     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7908     *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
7909     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
7910     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7911
7912     memset(&locked_rect, 0, sizeof(locked_rect));
7913     hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
7914     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7915     *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
7916     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
7917     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7918
7919     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
7920     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7921     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
7922     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7923
7924     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
7925     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7926     scale = 2.0;
7927     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7928     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7929     offset = 0.1;
7930     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7931     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7932
7933     hr = IDirect3DDevice9_BeginScene(device);
7934     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7935     if(SUCCEEDED(hr)) {
7936         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7937         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7938         hr = IDirect3DDevice9_EndScene(device);
7939         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7940     }
7941
7942     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7943     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7944     color = getPixelColor(device, 320, 240);
7945     /* red:   1.0  * (0.25 * 2.0 + 0.1) = 1.0  * 0.6 = 0.6  = 0x99
7946      * green: 0.5  * (0.25 * 2.0 + 0.1) = 0.5  * 0.6 = 0.3  = 0x4c
7947      * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
7948      */
7949     ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
7950
7951     /* Check a result scale factor > 1.0 */
7952     scale = 10;
7953     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7954     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7955     offset = 10;
7956     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7957     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7958
7959     hr = IDirect3DDevice9_BeginScene(device);
7960     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7961     if(SUCCEEDED(hr)) {
7962         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7963         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7964         hr = IDirect3DDevice9_EndScene(device);
7965         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7966     }
7967     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7968     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7969     color = getPixelColor(device, 320, 240);
7970     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7971
7972     /* Check clamping in the scale factor calculation */
7973     scale = 1000;
7974     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7975     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7976     offset = -1;
7977     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7978     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7979
7980     hr = IDirect3DDevice9_BeginScene(device);
7981     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7982     if(SUCCEEDED(hr)) {
7983         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7984         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7985         hr = IDirect3DDevice9_EndScene(device);
7986         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7987     }
7988     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7989     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7990     color = getPixelColor(device, 320, 240);
7991     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7992
7993     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7994     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7995     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
7996     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7997
7998     IDirect3DTexture9_Release(tex1);
7999     IDirect3DTexture9_Release(tex2);
8000
8001 cleanup:
8002     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8003     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8004     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8005     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8006
8007     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8008     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8009     IDirect3DVertexDeclaration9_Release(vertex_declaration);
8010 }
8011
8012 static void stencil_cull_test(IDirect3DDevice9 *device) {
8013     HRESULT hr;
8014     IDirect3DSurface9 *depthstencil = NULL;
8015     D3DSURFACE_DESC desc;
8016     float quad1[] = {
8017         -1.0,   -1.0,   0.1,
8018          0.0,   -1.0,   0.1,
8019         -1.0,    0.0,   0.1,
8020          0.0,    0.0,   0.1,
8021     };
8022     float quad2[] = {
8023          0.0,   -1.0,   0.1,
8024          1.0,   -1.0,   0.1,
8025          0.0,    0.0,   0.1,
8026          1.0,    0.0,   0.1,
8027     };
8028     float quad3[] = {
8029         0.0,    0.0,   0.1,
8030         1.0,    0.0,   0.1,
8031         0.0,    1.0,   0.1,
8032         1.0,    1.0,   0.1,
8033     };
8034     float quad4[] = {
8035         -1.0,    0.0,   0.1,
8036          0.0,    0.0,   0.1,
8037         -1.0,    1.0,   0.1,
8038          0.0,    1.0,   0.1,
8039     };
8040     struct vertex painter[] = {
8041        {-1.0,   -1.0,   0.0,    0x00000000},
8042        { 1.0,   -1.0,   0.0,    0x00000000},
8043        {-1.0,    1.0,   0.0,    0x00000000},
8044        { 1.0,    1.0,   0.0,    0x00000000},
8045     };
8046     WORD indices_cw[]  = {0, 1, 3};
8047     WORD indices_ccw[] = {0, 2, 3};
8048     unsigned int i;
8049     DWORD color;
8050
8051     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8052     if(depthstencil == NULL) {
8053         skip("No depth stencil buffer\n");
8054         return;
8055     }
8056     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8057     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8058     IDirect3DSurface9_Release(depthstencil);
8059     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8060         skip("No 4 or 8 bit stencil surface\n");
8061         return;
8062     }
8063
8064     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8065     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8066     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8067
8068     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8069     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8070     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8071     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8072     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8073     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8074     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8075     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8076
8077     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8078     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8079     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8080     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8081     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8082     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8083
8084     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8085     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8086     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8087     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8088
8089     /* First pass: Fill the stencil buffer with some values... */
8090     hr = IDirect3DDevice9_BeginScene(device);
8091     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8092     if(SUCCEEDED(hr))
8093     {
8094         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8095         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8096         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8097                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8098         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8099                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8100
8101         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8102         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8103         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8104         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8105         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8106                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8107         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8108                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8109
8110         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8111         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8112         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8113                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8114         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8115                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8116
8117         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8118         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8119         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8120                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8121         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8122                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8123
8124         hr = IDirect3DDevice9_EndScene(device);
8125         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8126     }
8127
8128     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8129     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8130     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8131     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8132     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8133     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8134     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8135     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8136     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8137     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8138     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8139     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8140     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8141
8142     /* 2nd pass: Make the stencil values visible */
8143     hr = IDirect3DDevice9_BeginScene(device);
8144     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8145     if(SUCCEEDED(hr))
8146     {
8147         IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8148         for(i = 0; i < 16; i++) {
8149             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8150             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8151
8152             painter[0].diffuse = (i * 16); /* Creates shades of blue */
8153             painter[1].diffuse = (i * 16);
8154             painter[2].diffuse = (i * 16);
8155             painter[3].diffuse = (i * 16);
8156             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8157             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8158         }
8159         hr = IDirect3DDevice9_EndScene(device);
8160         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8161     }
8162
8163     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8164     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8165
8166     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8167     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8168
8169     color = getPixelColor(device, 160, 420);
8170     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8171     color = getPixelColor(device, 160, 300);
8172     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8173
8174     color = getPixelColor(device, 480, 420);
8175     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8176     color = getPixelColor(device, 480, 300);
8177     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8178
8179     color = getPixelColor(device, 160, 180);
8180     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8181     color = getPixelColor(device, 160, 60);
8182     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8183
8184     color = getPixelColor(device, 480, 180);
8185     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8186     color = getPixelColor(device, 480, 60);
8187     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8188 }
8189
8190 static void vpos_register_test(IDirect3DDevice9 *device)
8191 {
8192     HRESULT hr;
8193     DWORD color;
8194     const DWORD shader_code[] = {
8195     0xffff0300,                                                             /* ps_3_0                     */
8196     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8197     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8198     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8199     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8200     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8201     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8202     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8203     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8204     0x0000ffff                                                              /* end                        */
8205     };
8206     const DWORD shader_frac_code[] = {
8207     0xffff0300,                                                             /* ps_3_0                     */
8208     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8209     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8210     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8211     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8212     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8213     0x0000ffff                                                              /* end                        */
8214     };
8215     IDirect3DPixelShader9 *shader, *shader_frac;
8216     IDirect3DSurface9 *surface = NULL, *backbuffer;
8217     const float quad[] = {
8218         -1.0,   -1.0,   0.1,    0.0,    0.0,
8219          1.0,   -1.0,   0.1,    1.0,    0.0,
8220         -1.0,    1.0,   0.1,    0.0,    1.0,
8221          1.0,    1.0,   0.1,    1.0,    1.0,
8222     };
8223     D3DLOCKED_RECT lr;
8224     float constant[4] = {1.0, 0.0, 320, 240};
8225     DWORD *pos;
8226
8227     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8228     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8229     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8230     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8231     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8232     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8233     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8234     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8235     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8236     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8237     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8238     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8239
8240     hr = IDirect3DDevice9_BeginScene(device);
8241     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8242     if(SUCCEEDED(hr)) {
8243         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8244         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8245         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8246         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8247         hr = IDirect3DDevice9_EndScene(device);
8248         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8249     }
8250
8251     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8252     /* This has to be pixel exact */
8253     color = getPixelColor(device, 319, 239);
8254     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8255     color = getPixelColor(device, 320, 239);
8256     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8257     color = getPixelColor(device, 319, 240);
8258     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8259     color = getPixelColor(device, 320, 240);
8260     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8261
8262     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8263                                              &surface, NULL);
8264     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8265     hr = IDirect3DDevice9_BeginScene(device);
8266     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8267     if(SUCCEEDED(hr)) {
8268         constant[2] = 16; constant[3] = 16;
8269         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8270         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8271         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8272         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8273         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8274         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8275         hr = IDirect3DDevice9_EndScene(device);
8276         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8277     }
8278     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8279     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8280
8281     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8282     color = *pos & 0x00ffffff;
8283     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8284     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8285     color = *pos & 0x00ffffff;
8286     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8287     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8288     color = *pos & 0x00ffffff;
8289     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8290     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8291     color = *pos & 0x00ffffff;
8292     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8293
8294     hr = IDirect3DSurface9_UnlockRect(surface);
8295     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8296
8297     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8298      * have full control over the multisampling setting inside this test
8299      */
8300     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8301     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8302     hr = IDirect3DDevice9_BeginScene(device);
8303     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8304     if(SUCCEEDED(hr)) {
8305         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8306         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8307         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8308         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8309         hr = IDirect3DDevice9_EndScene(device);
8310         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8311     }
8312     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8313     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8314
8315     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8316     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8317
8318     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8319     color = *pos & 0x00ffffff;
8320     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8321
8322     hr = IDirect3DSurface9_UnlockRect(surface);
8323     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8324
8325     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8326     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8327     IDirect3DPixelShader9_Release(shader);
8328     IDirect3DPixelShader9_Release(shader_frac);
8329     if(surface) IDirect3DSurface9_Release(surface);
8330     IDirect3DSurface9_Release(backbuffer);
8331 }
8332
8333 static void pointsize_test(IDirect3DDevice9 *device)
8334 {
8335     HRESULT hr;
8336     D3DCAPS9 caps;
8337     D3DMATRIX matrix;
8338     D3DMATRIX identity;
8339     float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8340     DWORD color;
8341
8342     const float vertices[] = {
8343         64,     64,     0.1,
8344         128,    64,     0.1,
8345         192,    64,     0.1,
8346         256,    64,     0.1,
8347         320,    64,     0.1,
8348         384,    64,     0.1,
8349         448,    64,     0.1,
8350         512,    64,     0.1,
8351         576,    64,     0.1,
8352     };
8353
8354     /* 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 */
8355     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;
8356     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;
8357     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;
8358     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;
8359
8360     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;
8361     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;
8362     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;
8363     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;
8364
8365     memset(&caps, 0, sizeof(caps));
8366     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8367     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8368     if(caps.MaxPointSize < 32.0) {
8369         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8370         return;
8371     }
8372
8373     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8374     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8375     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8376     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8377     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8378     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8379     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8380     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8381
8382     hr = IDirect3DDevice9_BeginScene(device);
8383     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8384     if(SUCCEEDED(hr)) {
8385         ptsize = 16.0;
8386         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8387         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8388         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8389         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8390
8391         ptsize = 32.0;
8392         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8393         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8394         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8395         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8396
8397         ptsize = 31.5;
8398         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8399         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8400         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8401         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8402
8403         if(caps.MaxPointSize >= 64.0) {
8404             ptsize = 64.0;
8405             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8406             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8407             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8408             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8409
8410             ptsize = 63.75;
8411             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8412             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8413             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8414             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8415         }
8416
8417         ptsize = 1.0;
8418         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8419         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8420         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8421         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8422
8423         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8424         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8425         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemin_orig));
8426         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8427
8428         /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8429         ptsize = 16.0;
8430         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8431         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8432         ptsize = 1.0;
8433         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8434         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8435         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8436         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8437
8438         /* What happens if POINTSIZE_MAX < POINTSIZE_MIN?
8439          * ptsize = 4.0, ptsize_max = 1.0, ptsize_min = 16.0
8440          */
8441         ptsize = 4.0;
8442         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8443         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8444         ptsize = 16.0;
8445         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8446         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8447         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8448         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8449
8450         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8451         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8452
8453         /* pointsize < pointsize_min < pointsize_max?
8454          * pointsize = 1.0, pointsize_min = 16.0, pointsize_max = default(usually 64.0)
8455          */
8456         ptsize = 1.0;
8457         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8458         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8459         ptsize = 16.0;
8460         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8461         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8462         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[24], sizeof(float) * 3);
8463         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8464
8465         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8466         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8467
8468         hr = IDirect3DDevice9_EndScene(device);
8469         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8470     }
8471     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8472     color = getPixelColor(device, 64-9, 64-9);
8473     ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
8474     color = getPixelColor(device, 64-8, 64-8);
8475     todo_wine ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
8476     color = getPixelColor(device, 64-7, 64-7);
8477     ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
8478     color = getPixelColor(device, 64+7, 64+7);
8479     ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
8480     color = getPixelColor(device, 64+8, 64+8);
8481     ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
8482     color = getPixelColor(device, 64+9, 64+9);
8483     ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
8484
8485     color = getPixelColor(device, 128-17, 64-17);
8486     ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8487     color = getPixelColor(device, 128-16, 64-16);
8488     todo_wine ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
8489     color = getPixelColor(device, 128-15, 64-15);
8490     ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8491     color = getPixelColor(device, 128+15, 64+15);
8492     ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8493     color = getPixelColor(device, 128+16, 64+16);
8494     ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8495     color = getPixelColor(device, 128+17, 64+17);
8496     ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8497
8498     color = getPixelColor(device, 192-17, 64-17);
8499     ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8500     color = getPixelColor(device, 192-16, 64-16);
8501     ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
8502     color = getPixelColor(device, 192-15, 64-15);
8503     ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8504     color = getPixelColor(device, 192+15, 64+15);
8505     ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8506     color = getPixelColor(device, 192+16, 64+16);
8507     ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8508     color = getPixelColor(device, 192+17, 64+17);
8509     ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8510
8511     if(caps.MaxPointSize >= 64.0) {
8512         color = getPixelColor(device, 256-33, 64-33);
8513         ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8514         color = getPixelColor(device, 256-32, 64-32);
8515         todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
8516         color = getPixelColor(device, 256-31, 64-31);
8517         ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8518         color = getPixelColor(device, 256+31, 64+31);
8519         ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8520         color = getPixelColor(device, 256+32, 64+32);
8521         ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8522         color = getPixelColor(device, 256+33, 64+33);
8523         ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8524
8525         color = getPixelColor(device, 384-33, 64-33);
8526         ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8527         color = getPixelColor(device, 384-32, 64-32);
8528         ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
8529         color = getPixelColor(device, 384-31, 64-31);
8530         ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8531         color = getPixelColor(device, 384+31, 64+31);
8532         ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8533         color = getPixelColor(device, 384+32, 64+32);
8534         ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8535         color = getPixelColor(device, 384+33, 64+33);
8536         ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8537     }
8538
8539     color = getPixelColor(device, 320-1, 64-1);
8540     ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
8541     color = getPixelColor(device, 320-0, 64-0);
8542     ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
8543     color = getPixelColor(device, 320+1, 64+1);
8544     ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
8545
8546     /* ptsize = 16, ptsize_max = 1 --> point has size 1 */
8547     color = getPixelColor(device, 448-4, 64-4);
8548     ok(color == 0x000000ff, "pSize: Pixel (448-4),(64-4) has color 0x%08x, expected 0x00ffffff\n", color);
8549     color = getPixelColor(device, 448+4, 64+4);
8550     ok(color == 0x000000ff, "pSize: Pixel (448+4),(64+4) has color 0x%08x, expected 0x00ffffff\n", color);
8551
8552     /* ptsize = 4, ptsize_max = 1, ptsize_min = 16 --> point has size 1 */
8553     color = getPixelColor(device, 512-4, 64-4);
8554     ok(color == 0x000000ff, "pSize: Pixel (448-4),(64-4) has color 0x%08x, expected 0x00ffffff\n", color);
8555     color = getPixelColor(device, 512+4, 64+4);
8556     ok(color == 0x000000ff, "pSize: Pixel (448+4),(64+4) has color 0x%08x, expected 0x00ffffff\n", color);
8557
8558     /* ptsize = 1, ptsize_max = default(64), ptsize_min = 16 --> point has size 16
8559      * Don't be overly picky - just show that the point is bigger than 1 pixel
8560      */
8561     color = getPixelColor(device, 576-4, 64-4);
8562     ok(color == 0x00ffffff, "pSize: Pixel (448-4),(64-4) has color 0x%08x, expected 0x00ffffff\n", color);
8563     color = getPixelColor(device, 576+4, 64+4);
8564     ok(color == 0x00ffffff, "pSize: Pixel (448+4),(64+4) has color 0x%08x, expected 0x00ffffff\n", color);
8565
8566     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8567     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8568     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8569     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8570 }
8571
8572 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8573 {
8574     HRESULT hr;
8575     IDirect3DPixelShader9 *ps;
8576     IDirect3DTexture9 *tex1, *tex2;
8577     IDirect3DSurface9 *surf1, *surf2, *backbuf;
8578     D3DCAPS9 caps;
8579     DWORD color;
8580     DWORD shader_code[] = {
8581     0xffff0300,                                                             /* ps_3_0             */
8582     0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
8583     0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
8584     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0        */
8585     0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1        */
8586     0x0000ffff                                                              /* END                */
8587     };
8588     float quad[] = {
8589        -1.0,   -1.0,    0.1,
8590         1.0,   -1.0,    0.1,
8591        -1.0,    1.0,    0.1,
8592         1.0,    1.0,    0.1,
8593     };
8594     float texquad[] = {
8595        -1.0,   -1.0,    0.1,    0.0,    0.0,
8596         0.0,   -1.0,    0.1,    1.0,    0.0,
8597        -1.0,    1.0,    0.1,    0.0,    1.0,
8598         0.0,    1.0,    0.1,    1.0,    1.0,
8599
8600         0.0,   -1.0,    0.1,    0.0,    0.0,
8601         1.0,   -1.0,    0.1,    1.0,    0.0,
8602         0.0,    1.0,    0.1,    0.0,    1.0,
8603         1.0,    1.0,    0.1,    1.0,    1.0,
8604     };
8605
8606     memset(&caps, 0, sizeof(caps));
8607     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8608     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8609     if(caps.NumSimultaneousRTs < 2) {
8610         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8611         return;
8612     }
8613
8614     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8615     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8616
8617     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8618     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8619     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8620     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8621     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
8622     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
8623
8624     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8625     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8626     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8627     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8628     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8629     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8630
8631     hr = IDirect3DDevice9_SetPixelShader(device, ps);
8632     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8633     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8634     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8635     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8636     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8637     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8638     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8639
8640     hr = IDirect3DDevice9_BeginScene(device);
8641     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8642     if(SUCCEEDED(hr)) {
8643         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8644         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8645
8646         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8647         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8648         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8649         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8650         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8651         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8652         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8653         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8654
8655         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8656         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8657         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8658         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8659
8660         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8661         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8662         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8663         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8664
8665         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8666         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8667
8668         hr = IDirect3DDevice9_EndScene(device);
8669         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8670     }
8671
8672     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8673     color = getPixelColor(device, 160, 240);
8674     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8675     color = getPixelColor(device, 480, 240);
8676     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8677
8678     IDirect3DPixelShader9_Release(ps);
8679     IDirect3DTexture9_Release(tex1);
8680     IDirect3DTexture9_Release(tex2);
8681     IDirect3DSurface9_Release(surf1);
8682     IDirect3DSurface9_Release(surf2);
8683     IDirect3DSurface9_Release(backbuf);
8684 }
8685
8686 struct formats {
8687     const char *fmtName;
8688     D3DFORMAT textureFormat;
8689     DWORD resultColorBlending;
8690     DWORD resultColorNoBlending;
8691 };
8692
8693 const struct formats test_formats[] = {
8694   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
8695   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8696   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8697   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8698   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8699   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8700   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8701   { NULL, 0 }
8702 };
8703
8704 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8705 {
8706     HRESULT hr;
8707     IDirect3DTexture9 *offscreenTexture = NULL;
8708     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8709     IDirect3D9 *d3d = NULL;
8710     DWORD color;
8711     DWORD r0, g0, b0, r1, g1, b1;
8712     int fmt_index;
8713
8714     static const float quad[][5] = {
8715         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8716         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
8717         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8718         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
8719     };
8720
8721     /* Quad with R=0x10, G=0x20 */
8722     static const struct vertex quad1[] = {
8723         {-1.0f, -1.0f, 0.1f, 0x80102000},
8724         {-1.0f,  1.0f, 0.1f, 0x80102000},
8725         { 1.0f, -1.0f, 0.1f, 0x80102000},
8726         { 1.0f,  1.0f, 0.1f, 0x80102000},
8727     };
8728
8729     /* Quad with R=0x20, G=0x10 */
8730     static const struct vertex quad2[] = {
8731         {-1.0f, -1.0f, 0.1f, 0x80201000},
8732         {-1.0f,  1.0f, 0.1f, 0x80201000},
8733         { 1.0f, -1.0f, 0.1f, 0x80201000},
8734         { 1.0f,  1.0f, 0.1f, 0x80201000},
8735     };
8736
8737     IDirect3DDevice9_GetDirect3D(device, &d3d);
8738
8739     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8740     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8741     if(!backbuffer) {
8742         goto out;
8743     }
8744
8745     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8746     {
8747         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8748         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
8749            skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
8750            continue;
8751         }
8752
8753         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8754         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8755
8756         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8757         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
8758         if(!offscreenTexture) {
8759             continue;
8760         }
8761
8762         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8763         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8764         if(!offscreen) {
8765             continue;
8766         }
8767
8768         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8769         ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8770
8771         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8772         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8773         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8774         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8775         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8776         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8777         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8778         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8779         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8780         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8781
8782         /* Below we will draw two quads with different colors and try to blend them together.
8783          * The result color is compared with the expected outcome.
8784          */
8785         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8786             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8787             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8788             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8789             ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8790
8791             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8792             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8793
8794             /* Draw a quad using color 0x0010200 */
8795             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8796             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8797             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8798             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8799             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8800             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8801
8802             /* Draw a quad using color 0x0020100 */
8803             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8804             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8805             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8806             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8807             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8808             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8809
8810             /* We don't want to blend the result on the backbuffer */
8811             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8812             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8813
8814             /* Prepare rendering the 'blended' texture quad to the backbuffer */
8815             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8816             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8817             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8818             ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
8819
8820             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8821             ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8822
8823             /* This time with the texture */
8824             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8825             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
8826
8827             IDirect3DDevice9_EndScene(device);
8828         }
8829         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8830
8831
8832         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
8833             /* Compare the color of the center quad with our expectation */
8834             color = getPixelColor(device, 320, 240);
8835             r0 = (color & 0x00ff0000) >> 16;
8836             g0 = (color & 0x0000ff00) >>  8;
8837             b0 = (color & 0x000000ff) >>  0;
8838
8839             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
8840             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
8841             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
8842
8843             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
8844                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
8845                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
8846                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
8847         } else {
8848             /* No pixel shader blending is supported so expected garbage.The type of 'garbage' depends on the driver version and OS.
8849              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
8850              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
8851             color = getPixelColor(device, 320, 240);
8852             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);
8853         }
8854
8855         IDirect3DDevice9_SetTexture(device, 0, NULL);
8856         if(offscreenTexture) {
8857             IDirect3DTexture9_Release(offscreenTexture);
8858         }
8859         if(offscreen) {
8860             IDirect3DSurface9_Release(offscreen);
8861         }
8862     }
8863
8864 out:
8865     /* restore things */
8866     if(backbuffer) {
8867         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8868         IDirect3DSurface9_Release(backbuffer);
8869     }
8870 }
8871
8872 static void tssargtemp_test(IDirect3DDevice9 *device)
8873 {
8874     HRESULT hr;
8875     DWORD color;
8876     static const struct vertex quad[] = {
8877         {-1.0,     -1.0,    0.1,    0x00ff0000},
8878         { 1.0,     -1.0,    0.1,    0x00ff0000},
8879         {-1.0,      1.0,    0.1,    0x00ff0000},
8880         { 1.0,      1.0,    0.1,    0x00ff0000}
8881     };
8882     D3DCAPS9 caps;
8883
8884     memset(&caps, 0, sizeof(caps));
8885     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8886     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
8887     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
8888         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
8889         return;
8890     }
8891
8892     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
8893     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
8894
8895     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8896     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8897     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
8898     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8899
8900     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8901     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8902     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
8903     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8904     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
8905     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8906
8907     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
8908     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8909     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
8910     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8911     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
8912     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8913
8914     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8915     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8916
8917     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
8918     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8919     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8920     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
8921
8922     hr = IDirect3DDevice9_BeginScene(device);
8923     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
8924     if(SUCCEEDED(hr)) {
8925
8926         hr = IDirect3DDevice9_EndScene(device);
8927         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
8928         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8929         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
8930     }
8931     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8932     color = getPixelColor(device, 320, 240);
8933     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
8934
8935     /* Set stage 1 back to default */
8936     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
8937     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8938     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8939     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8940     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8941     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8942     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8943     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8944     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8945     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8946 }
8947
8948 struct testdata
8949 {
8950     DWORD idxVertex; /* number of instances in the first stream */
8951     DWORD idxColor; /* number of instances in the second stream */
8952     DWORD idxInstance; /* should be 1 ?? */
8953     DWORD color1; /* color 1 instance */
8954     DWORD color2; /* color 2 instance */
8955     DWORD color3; /* color 3 instance */
8956     DWORD color4; /* color 4 instance */
8957     WORD strVertex; /* specify which stream to use 0-2*/
8958     WORD strColor;
8959     WORD strInstance;
8960 };
8961
8962 static const struct testdata testcases[]=
8963 {
8964     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
8965     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
8966     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
8967     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
8968     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  4 */
8969     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
8970     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
8971     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
8972     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  8 */
8973     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  9 */
8974     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
8975     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
8976     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
8977     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
8978     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
8979 /*
8980     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
8981     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
8982 */
8983 };
8984
8985 /* Drawing Indexed Geometry with instances*/
8986 static void stream_test(IDirect3DDevice9 *device)
8987 {
8988     IDirect3DVertexBuffer9 *vb = NULL;
8989     IDirect3DVertexBuffer9 *vb2 = NULL;
8990     IDirect3DVertexBuffer9 *vb3 = NULL;
8991     IDirect3DIndexBuffer9 *ib = NULL;
8992     IDirect3DVertexDeclaration9 *pDecl = NULL;
8993     IDirect3DVertexShader9 *shader = NULL;
8994     HRESULT hr;
8995     BYTE *data;
8996     DWORD color;
8997     DWORD ind;
8998     unsigned i;
8999
9000     const DWORD shader_code[] =
9001     {
9002         0xfffe0101,                                     /* vs_1_1 */
9003         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
9004         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
9005         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
9006         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
9007         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9008         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
9009         0x0000ffff
9010     };
9011
9012     const float quad[][3] =
9013     {
9014         {-0.5f, -0.5f,  1.1f}, /*0 */
9015         {-0.5f,  0.5f,  1.1f}, /*1 */
9016         { 0.5f, -0.5f,  1.1f}, /*2 */
9017         { 0.5f,  0.5f,  1.1f}, /*3 */
9018     };
9019
9020     const float vertcolor[][4] =
9021     {
9022         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9023         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9024         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9025         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9026     };
9027
9028     /* 4 position for 4 instances */
9029     const float instancepos[][3] =
9030     {
9031         {-0.6f,-0.6f, 0.0f},
9032         { 0.6f,-0.6f, 0.0f},
9033         { 0.6f, 0.6f, 0.0f},
9034         {-0.6f, 0.6f, 0.0f},
9035     };
9036
9037     short indices[] = {0, 1, 2, 1, 2, 3};
9038
9039     D3DVERTEXELEMENT9 decl[] =
9040     {
9041         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9042         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9043         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9044         D3DDECL_END()
9045     };
9046
9047     /* set the default value because it isn't done in wine? */
9048     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9049     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9050
9051     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9052     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9053     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9054
9055     /* check wrong cases */
9056     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9057     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9058     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9059     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9060     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9061     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9062     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9063     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9064     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9065     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9066     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9067     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9068     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9069     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9070     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9071     ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9072     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9073     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9074     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9075     ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9076
9077     /* set the default value back */
9078     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9079     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9080
9081     /* create all VertexBuffers*/
9082     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9083     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9084     if(!vb) {
9085         skip("Failed to create a vertex buffer\n");
9086         return;
9087     }
9088     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9089     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9090     if(!vb2) {
9091         skip("Failed to create a vertex buffer\n");
9092         goto out;
9093     }
9094     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9095     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9096     if(!vb3) {
9097         skip("Failed to create a vertex buffer\n");
9098         goto out;
9099     }
9100
9101     /* create IndexBuffer*/
9102     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9103     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9104     if(!ib) {
9105         skip("Failed to create a index buffer\n");
9106         goto out;
9107     }
9108
9109     /* copy all Buffers (Vertex + Index)*/
9110     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9111     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9112     memcpy(data, quad, sizeof(quad));
9113     hr = IDirect3DVertexBuffer9_Unlock(vb);
9114     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9115     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9116     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9117     memcpy(data, vertcolor, sizeof(vertcolor));
9118     hr = IDirect3DVertexBuffer9_Unlock(vb2);
9119     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9120     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9121     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9122     memcpy(data, instancepos, sizeof(instancepos));
9123     hr = IDirect3DVertexBuffer9_Unlock(vb3);
9124     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9125     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9126     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9127     memcpy(data, indices, sizeof(indices));
9128     hr = IDirect3DIndexBuffer9_Unlock(ib);
9129     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9130
9131     /* create VertexShader */
9132     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9133     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9134     if(!shader) {
9135         skip("Failed to create a vetex shader\n");
9136         goto out;
9137     }
9138
9139     hr = IDirect3DDevice9_SetVertexShader(device, shader);
9140     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9141
9142     hr = IDirect3DDevice9_SetIndices(device, ib);
9143     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9144
9145     /* run all tests */
9146     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9147     {
9148         struct testdata act = testcases[i];
9149         decl[0].Stream = act.strVertex;
9150         decl[1].Stream = act.strColor;
9151         decl[2].Stream = act.strInstance;
9152         /* create VertexDeclarations */
9153         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9154         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9155
9156         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9157         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9158
9159         hr = IDirect3DDevice9_BeginScene(device);
9160         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9161         if(SUCCEEDED(hr))
9162         {
9163             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9164             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9165
9166             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9167             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9168             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9169             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9170
9171             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9172             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9173             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9174             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9175
9176             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9177             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9178             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9179             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9180
9181             /* don't know if this is right (1*3 and 4*1)*/
9182             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
9183             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9184             hr = IDirect3DDevice9_EndScene(device);
9185             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9186
9187             /* set all StreamSource && StreamSourceFreq back to default */
9188             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9189             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9190             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9191             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9192             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9193             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9194             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9195             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9196             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9197             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9198             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9199             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9200         }
9201
9202         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9203         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9204
9205         hr = IDirect3DVertexDeclaration9_Release(pDecl);
9206         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9207
9208         color = getPixelColor(device, 160, 360);
9209         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9210         color = getPixelColor(device, 480, 360);
9211         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9212         color = getPixelColor(device, 480, 120);
9213         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9214         color = getPixelColor(device, 160, 120);
9215         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9216     }
9217
9218     hr = IDirect3DDevice9_SetIndices(device, NULL);
9219     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9220
9221 out:
9222     if(vb) IDirect3DVertexBuffer9_Release(vb);
9223     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9224     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9225     if(ib)IDirect3DIndexBuffer9_Release(ib);
9226     if(shader)IDirect3DVertexShader9_Release(shader);
9227 }
9228
9229 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9230     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9231     IDirect3DTexture9 *dsttex = NULL;
9232     HRESULT hr;
9233     DWORD color;
9234     D3DRECT r1 = {0,  0,  50,  50 };
9235     D3DRECT r2 = {50, 0,  100, 50 };
9236     D3DRECT r3 = {50, 50, 100, 100};
9237     D3DRECT r4 = {0,  50,  50, 100};
9238     const float quad[] = {
9239         -1.0,   -1.0,   0.1,    0.0,    0.0,
9240          1.0,   -1.0,   0.1,    1.0,    0.0,
9241         -1.0,    1.0,   0.1,    0.0,    1.0,
9242          1.0,    1.0,   0.1,    1.0,    1.0,
9243     };
9244
9245     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9246     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9247
9248     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9249     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9250     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9251     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9252
9253     if(!src || !dsttex) {
9254         skip("One or more test resources could not be created\n");
9255         goto cleanup;
9256     }
9257
9258     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9259     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9260
9261     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9262     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9263
9264     /* Clear the StretchRect destination for debugging */
9265     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9266     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9267     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9268     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9269
9270     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9271     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9272
9273     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9274     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9275     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9276     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9277     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9278     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9279     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9280     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9281
9282     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9283      * the target -> texture GL blit path
9284      */
9285     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9286     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9287     IDirect3DSurface9_Release(dst);
9288
9289     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9290     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9291
9292     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9293     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9294     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9295     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9296     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9297     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9298     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9299     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9300
9301     hr = IDirect3DDevice9_BeginScene(device);
9302     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9303     if(SUCCEEDED(hr)) {
9304         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9305         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9306         hr = IDirect3DDevice9_EndScene(device);
9307         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9308     }
9309
9310     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9311     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9312     color = getPixelColor(device, 160, 360);
9313     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9314     color = getPixelColor(device, 480, 360);
9315     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9316     color = getPixelColor(device, 480, 120);
9317     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9318     color = getPixelColor(device, 160, 120);
9319     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9320
9321     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9322     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9323     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9324     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9325
9326 cleanup:
9327     if(src) IDirect3DSurface9_Release(src);
9328     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9329     if(dsttex) IDirect3DTexture9_Release(dsttex);
9330 }
9331
9332 static void texop_test(IDirect3DDevice9 *device)
9333 {
9334     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9335     IDirect3DTexture9 *texture = NULL;
9336     D3DLOCKED_RECT locked_rect;
9337     D3DCOLOR color;
9338     D3DCAPS9 caps;
9339     HRESULT hr;
9340     unsigned i;
9341
9342     static const struct {
9343         float x, y, z;
9344         float s, t;
9345         D3DCOLOR diffuse;
9346     } quad[] = {
9347         {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9348         {-1.0f,  1.0f, 0.1f, -1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9349         { 1.0f, -1.0f, 0.1f,  1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9350         { 1.0f,  1.0f, 0.1f,  1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9351     };
9352
9353     static const D3DVERTEXELEMENT9 decl_elements[] = {
9354         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9355         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9356         {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9357         D3DDECL_END()
9358     };
9359
9360     static const struct {
9361         D3DTEXTUREOP op;
9362         const char *name;
9363         DWORD caps_flag;
9364         D3DCOLOR result;
9365     } test_data[] = {
9366         {D3DTOP_SELECTARG1,                "SELECTARG1",                D3DTEXOPCAPS_SELECTARG1,                D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9367         {D3DTOP_SELECTARG2,                "SELECTARG2",                D3DTEXOPCAPS_SELECTARG2,                D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9368         {D3DTOP_MODULATE,                  "MODULATE",                  D3DTEXOPCAPS_MODULATE,                  D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9369         {D3DTOP_MODULATE2X,                "MODULATE2X",                D3DTEXOPCAPS_MODULATE2X,                D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9370         {D3DTOP_MODULATE4X,                "MODULATE4X",                D3DTEXOPCAPS_MODULATE4X,                D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9371         {D3DTOP_ADD,                       "ADD",                       D3DTEXOPCAPS_ADD,                       D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9372         {D3DTOP_ADDSIGNED,                 "ADDSIGNED",                 D3DTEXOPCAPS_ADDSIGNED,                 D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9373         {D3DTOP_ADDSIGNED2X,               "ADDSIGNED2X",               D3DTEXOPCAPS_ADDSIGNED2X,               D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9374         {D3DTOP_SUBTRACT,                  "SUBTRACT",                  D3DTEXOPCAPS_SUBTRACT,                  D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9375         {D3DTOP_ADDSMOOTH,                 "ADDSMOOTH",                 D3DTEXOPCAPS_ADDSMOOTH,                 D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9376         {D3DTOP_BLENDDIFFUSEALPHA,         "BLENDDIFFUSEALPHA",         D3DTEXOPCAPS_BLENDDIFFUSEALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9377         {D3DTOP_BLENDTEXTUREALPHA,         "BLENDTEXTUREALPHA",         D3DTEXOPCAPS_BLENDTEXTUREALPHA,         D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9378         {D3DTOP_BLENDFACTORALPHA,          "BLENDFACTORALPHA",          D3DTEXOPCAPS_BLENDFACTORALPHA,          D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9379         {D3DTOP_BLENDTEXTUREALPHAPM,       "BLENDTEXTUREALPHAPM",       D3DTEXOPCAPS_BLENDTEXTUREALPHAPM,       D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9380         {D3DTOP_BLENDCURRENTALPHA,         "BLENDCURRENTALPHA",         D3DTEXOPCAPS_BLENDCURRENTALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9381         {D3DTOP_MODULATEALPHA_ADDCOLOR,    "MODULATEALPHA_ADDCOLOR",    D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR,    D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9382         {D3DTOP_MODULATECOLOR_ADDALPHA,    "MODULATECOLOR_ADDALPHA",    D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA,    D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9383         {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9384         {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9385         /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9386         {D3DTOP_DOTPRODUCT3,               "DOTPRODUCT2",               D3DTEXOPCAPS_DOTPRODUCT3,               D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9387         {D3DTOP_MULTIPLYADD,               "MULTIPLYADD",               D3DTEXOPCAPS_MULTIPLYADD,               D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9388         {D3DTOP_LERP,                      "LERP",                      D3DTEXOPCAPS_LERP,                      D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9389     };
9390
9391     memset(&caps, 0, sizeof(caps));
9392     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9393     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9394
9395     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9396     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9397     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9398     ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9399
9400     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9401     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9402     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9403     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9404     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9405     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9406     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9407     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9408     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9409
9410     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9411     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9412     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9413     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9414     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9415     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9416
9417     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9418     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9419
9420     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9421     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9422     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9423     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9424     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9425     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9426
9427     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9428     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9429
9430     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9431     {
9432         if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9433         {
9434             skip("tex operation %s not supported\n", test_data[i].name);
9435             continue;
9436         }
9437
9438         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9439         ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9440
9441         hr = IDirect3DDevice9_BeginScene(device);
9442         ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9443
9444         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9445         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9446
9447         hr = IDirect3DDevice9_EndScene(device);
9448         ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9449
9450         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9451         ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9452
9453         color = getPixelColor(device, 320, 240);
9454         ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9455                 test_data[i].name, color, test_data[i].result);
9456     }
9457
9458     if (texture) IDirect3DTexture9_Release(texture);
9459     if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9460 }
9461
9462 static void yuv_color_test(IDirect3DDevice9 *device) {
9463     HRESULT hr;
9464     IDirect3DSurface9 *surface = NULL, *target = NULL;
9465     unsigned int fmt, i;
9466     D3DFORMAT format;
9467     const char *fmt_string;
9468     D3DLOCKED_RECT lr;
9469     IDirect3D9 *d3d;
9470     HRESULT color;
9471     DWORD ref_color_left, ref_color_right;
9472
9473     struct {
9474         DWORD in;           /* The input color */
9475         DWORD uyvy_left;    /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9476         DWORD uyvy_right;   /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9477         DWORD yuy2_left;    /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9478         DWORD yuy2_right;   /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9479     } test_data[] = {
9480     /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9481      * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9482      * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9483      * that
9484      */
9485       { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9486       { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9487       { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9488       { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9489       { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9490       { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9491       { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9492       { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9493       { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9494       { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9495       { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9496       { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9497       { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9498       { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9499
9500       { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9501       { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9502       { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9503       { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9504     };
9505
9506     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9507     ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9508     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9509     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9510
9511     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9512     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9513
9514     for(fmt = 0; fmt < 2; fmt++) {
9515         if(fmt == 0) {
9516             format = D3DFMT_UYVY;
9517             fmt_string = "D3DFMT_UYVY";
9518         } else {
9519             format = D3DFMT_YUY2;
9520             fmt_string = "D3DFMT_YUY2";
9521         }
9522
9523         /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9524                        * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9525                        */
9526         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9527                                         D3DRTYPE_SURFACE, format) != D3D_OK) {
9528             skip("%s is not supported\n", fmt_string);
9529             continue;
9530         }
9531
9532         /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9533         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9534         ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9535
9536         for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9537             if(fmt == 0) {
9538                 ref_color_left = test_data[i].uyvy_left;
9539                 ref_color_right = test_data[i].uyvy_right;
9540             } else {
9541                 ref_color_left = test_data[i].yuy2_left;
9542                 ref_color_right = test_data[i].yuy2_right;
9543             }
9544
9545             memset(&lr, 0, sizeof(lr));
9546             hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9547             ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9548             *((DWORD *) lr.pBits) = test_data[i].in;
9549             hr = IDirect3DSurface9_UnlockRect(surface);
9550             ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9551
9552             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9553             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9554             hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9555             ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9556             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9557             ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9558
9559             /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9560              * prevent running into precision problems, read a far left and far right pixel. In the future we may
9561              * want to add tests for the filtered pixels as well.
9562              *
9563              * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9564              * differently, so we need a max diff of 16
9565              */
9566             color = getPixelColor(device, 40, 240);
9567             ok(color_match(color, ref_color_left, 16),
9568                "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9569                test_data[i].in, color, ref_color_left, fmt_string);
9570             color = getPixelColor(device, 600, 240);
9571             ok(color_match(color, ref_color_right, 16),
9572                "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9573                test_data[i].in, color, ref_color_left, fmt_string);
9574         }
9575         IDirect3DSurface9_Release(surface);
9576     }
9577     IDirect3DSurface9_Release(target);
9578     IDirect3D9_Release(d3d);
9579 }
9580
9581 static void texop_range_test(IDirect3DDevice9 *device)
9582 {
9583     static const struct {
9584         float x, y, z;
9585         D3DCOLOR diffuse;
9586     } quad[] = {
9587         {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9588         {-1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9589         { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9590         { 1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
9591     };
9592     HRESULT hr;
9593     IDirect3DTexture9 *texture;
9594     D3DLOCKED_RECT locked_rect;
9595     D3DCAPS9 caps;
9596     DWORD color;
9597
9598     /* We need ADD and SUBTRACT operations */
9599     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9600     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9601     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
9602         skip("D3DTOP_ADD is not supported, skipping value range test\n");
9603     }
9604     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
9605         skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
9606     }
9607
9608     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9609     ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
9610     /* Stage 1: result = diffuse(=1.0) + diffuse
9611      * stage 2: result = result - tfactor(= 0.5)
9612      */
9613     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9614     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9615     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9616     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9617     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9618     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9619     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9620     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9621     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9622     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9623     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9624     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9625     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9626     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9627
9628     hr = IDirect3DDevice9_BeginScene(device);
9629     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9630     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9631     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9632     hr = IDirect3DDevice9_EndScene(device);
9633     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9634     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9635     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9636
9637     color = getPixelColor(device, 320, 240);
9638     ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
9639        color);
9640
9641     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9642     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9643     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9644     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9645     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
9646     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9647     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9648     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9649     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9650
9651     /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
9652      * stage 2: result = result + diffuse(1.0)
9653      */
9654     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9655     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9656     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9657     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9658     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9659     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9660     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9661     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9662     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9663     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9664     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9665     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9666     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9667     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9668
9669     hr = IDirect3DDevice9_BeginScene(device);
9670     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9671     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9672     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9673     hr = IDirect3DDevice9_EndScene(device);
9674     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9675     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9676     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9677
9678     color = getPixelColor(device, 320, 240);
9679     ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
9680        color);
9681
9682     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9683     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9684     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9685     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9686     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
9687     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9688     IDirect3DTexture9_Release(texture);
9689 }
9690
9691 static void alphareplicate_test(IDirect3DDevice9 *device) {
9692     struct vertex quad[] = {
9693         { -1.0,    -1.0,    0.1,    0x80ff00ff },
9694         {  1.0,    -1.0,    0.1,    0x80ff00ff },
9695         { -1.0,     1.0,    0.1,    0x80ff00ff },
9696         {  1.0,     1.0,    0.1,    0x80ff00ff },
9697     };
9698     HRESULT hr;
9699     DWORD color;
9700
9701     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9702     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9703
9704     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9705     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9706
9707     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9708     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9709     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
9710     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9711
9712     hr = IDirect3DDevice9_BeginScene(device);
9713     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9714     if(SUCCEEDED(hr)) {
9715         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9716         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9717         hr = IDirect3DDevice9_EndScene(device);
9718         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9719     }
9720
9721     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9722     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9723
9724     color = getPixelColor(device, 320, 240);
9725     ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
9726        color);
9727
9728     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9729     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9730
9731 }
9732
9733 static void dp3_alpha_test(IDirect3DDevice9 *device) {
9734     HRESULT hr;
9735     D3DCAPS9 caps;
9736     DWORD color;
9737     struct vertex quad[] = {
9738         { -1.0,    -1.0,    0.1,    0x408080c0 },
9739         {  1.0,    -1.0,    0.1,    0x408080c0 },
9740         { -1.0,     1.0,    0.1,    0x408080c0 },
9741         {  1.0,     1.0,    0.1,    0x408080c0 },
9742     };
9743
9744     memset(&caps, 0, sizeof(caps));
9745     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9746     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9747     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
9748         skip("D3DTOP_DOTPRODUCT3 not supported\n");
9749         return;
9750     }
9751
9752     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9753     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9754
9755     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9756     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9757
9758     /* dp3_x4 r0, diffuse_bias, tfactor_bias
9759      * mov r0.a, diffuse.a
9760      * mov r0, r0.a
9761      *
9762      * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
9763      * 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
9764      * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
9765      */
9766     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
9767     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9768     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9769     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9770     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9771     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9772     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
9773     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9774     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
9775     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9776     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9777     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9778     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
9779     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9780     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9781     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9782     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
9783     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9784
9785     hr = IDirect3DDevice9_BeginScene(device);
9786     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9787     if(SUCCEEDED(hr)) {
9788         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9789         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9790         hr = IDirect3DDevice9_EndScene(device);
9791         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9792     }
9793
9794     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9795     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9796
9797     color = getPixelColor(device, 320, 240);
9798     ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
9799        color);
9800
9801     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9802     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9803     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9804     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9805     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9806     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9807 }
9808
9809 static void zwriteenable_test(IDirect3DDevice9 *device) {
9810     HRESULT hr;
9811     DWORD color;
9812     struct vertex quad1[] = {
9813         { -1.0,  -1.0,  0.1,    0x00ff0000},
9814         { -1.0,   1.0,  0.1,    0x00ff0000},
9815         {  1.0,  -1.0,  0.1,    0x00ff0000},
9816         {  1.0,   1.0,  0.1,    0x00ff0000},
9817     };
9818     struct vertex quad2[] = {
9819         { -1.0,  -1.0,  0.9,    0x0000ff00},
9820         { -1.0,   1.0,  0.9,    0x0000ff00},
9821         {  1.0,  -1.0,  0.9,    0x0000ff00},
9822         {  1.0,   1.0,  0.9,    0x0000ff00},
9823     };
9824
9825     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
9826     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9827
9828     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9829     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9830     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9831     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9832     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
9833     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9834     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
9835     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9836
9837     hr = IDirect3DDevice9_BeginScene(device);
9838     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9839     if(SUCCEEDED(hr)) {
9840         /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
9841          * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
9842          * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
9843          * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
9844          * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
9845          * the screen is green, so zenable = D3DZB_FALSE and zwriteenable  = TRUE does NOT write to the z buffer.
9846          */
9847         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
9848         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9849         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
9850         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9851         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
9852         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9853
9854         hr = IDirect3DDevice9_EndScene(device);
9855         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9856     }
9857
9858     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9859     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9860     color = getPixelColor(device, 320, 240);
9861     ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
9862        color);
9863
9864     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9865     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9866 }
9867
9868 START_TEST(visual)
9869 {
9870     IDirect3DDevice9 *device_ptr;
9871     D3DCAPS9 caps;
9872     HRESULT hr;
9873     DWORD color;
9874
9875     d3d9_handle = LoadLibraryA("d3d9.dll");
9876     if (!d3d9_handle)
9877     {
9878         skip("Could not load d3d9.dll\n");
9879         return;
9880     }
9881
9882     device_ptr = init_d3d9();
9883     if (!device_ptr)
9884     {
9885         skip("Creating the device failed\n");
9886         return;
9887     }
9888
9889     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
9890
9891     /* Check for the reliability of the returned data */
9892     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9893     if(FAILED(hr))
9894     {
9895         skip("Clear failed, can't assure correctness of the test results, skipping\n");
9896         goto cleanup;
9897     }
9898     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
9899
9900     color = getPixelColor(device_ptr, 1, 1);
9901     if(color !=0x00ff0000)
9902     {
9903         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
9904         goto cleanup;
9905     }
9906
9907     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
9908     if(FAILED(hr))
9909     {
9910         skip("Clear failed, can't assure correctness of the test results, skipping\n");
9911         goto cleanup;
9912     }
9913     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
9914
9915     color = getPixelColor(device_ptr, 639, 479);
9916     if(color != 0x0000ddee)
9917     {
9918         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
9919         goto cleanup;
9920     }
9921
9922     /* Now execute the real tests */
9923     stretchrect_test(device_ptr);
9924     lighting_test(device_ptr);
9925     clear_test(device_ptr);
9926     fog_test(device_ptr);
9927     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
9928     {
9929         test_cube_wrap(device_ptr);
9930     } else {
9931         skip("No cube texture support\n");
9932     }
9933     z_range_test(device_ptr);
9934     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
9935     {
9936         maxmip_test(device_ptr);
9937     }
9938     else
9939     {
9940         skip("No mipmap support\n");
9941     }
9942     offscreen_test(device_ptr);
9943     alpha_test(device_ptr);
9944     shademode_test(device_ptr);
9945     srgbtexture_test(device_ptr);
9946     release_buffer_test(device_ptr);
9947     float_texture_test(device_ptr);
9948     g16r16_texture_test(device_ptr);
9949     pixelshader_blending_test(device_ptr);
9950     texture_transform_flags_test(device_ptr);
9951     autogen_mipmap_test(device_ptr);
9952     fixed_function_decl_test(device_ptr);
9953     conditional_np2_repeat_test(device_ptr);
9954     fixed_function_bumpmap_test(device_ptr);
9955     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
9956         stencil_cull_test(device_ptr);
9957     } else {
9958         skip("No two sided stencil support\n");
9959     }
9960     pointsize_test(device_ptr);
9961     tssargtemp_test(device_ptr);
9962     np2_stretch_rect_test(device_ptr);
9963     yuv_color_test(device_ptr);
9964     zwriteenable_test(device_ptr);
9965
9966     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
9967     {
9968         test_constant_clamp_vs(device_ptr);
9969         test_compare_instructions(device_ptr);
9970     }
9971     else skip("No vs_1_1 support\n");
9972
9973     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
9974     {
9975         test_mova(device_ptr);
9976         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
9977             test_vshader_input(device_ptr);
9978             test_vshader_float16(device_ptr);
9979             stream_test(device_ptr);
9980         } else {
9981             skip("No vs_3_0 support\n");
9982         }
9983     }
9984     else skip("No vs_2_0 support\n");
9985
9986     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9987     {
9988         fog_with_shader_test(device_ptr);
9989         fog_srgbwrite_test(device_ptr);
9990     }
9991     else skip("No vs_1_1 and ps_1_1 support\n");
9992
9993     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9994     {
9995         texbem_test(device_ptr);
9996         texdepth_test(device_ptr);
9997         texkill_test(device_ptr);
9998         x8l8v8u8_test(device_ptr);
9999         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
10000             constant_clamp_ps_test(device_ptr);
10001             cnd_test(device_ptr);
10002             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
10003                 dp2add_ps_test(device_ptr);
10004                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
10005                     nested_loop_test(device_ptr);
10006                     fixed_function_varying_test(device_ptr);
10007                     vFace_register_test(device_ptr);
10008                     vpos_register_test(device_ptr);
10009                     multiple_rendertargets_test(device_ptr);
10010                     if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
10011                         vshader_version_varying_test(device_ptr);
10012                         pshader_version_varying_test(device_ptr);
10013                     } else {
10014                         skip("No vs_3_0 support\n");
10015                     }
10016                 } else {
10017                     skip("No ps_3_0 support\n");
10018                 }
10019             } else {
10020                 skip("No ps_2_0 support\n");
10021             }
10022         }
10023     }
10024     else skip("No ps_1_1 support\n");
10025
10026     texop_test(device_ptr);
10027     texop_range_test(device_ptr);
10028     alphareplicate_test(device_ptr);
10029     dp3_alpha_test(device_ptr);
10030
10031 cleanup:
10032     if(device_ptr) {
10033         ULONG ref;
10034
10035         D3DPRESENT_PARAMETERS present_parameters;
10036         IDirect3DSwapChain9 *swapchain;
10037         IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
10038         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
10039         IDirect3DSwapChain9_Release(swapchain);
10040         ref = IDirect3DDevice9_Release(device_ptr);
10041         DestroyWindow(present_parameters.hDeviceWindow);
10042         ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
10043     }
10044 }