comctl32: Add implementation of LVS_EX_ONECLICKACTIVATE.
[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     ok(d3d9_ptr != NULL, "Failed to create IDirect3D9 object\n");
165     if (!d3d9_ptr) return NULL;
166
167     ZeroMemory(&present_parameters, sizeof(present_parameters));
168     present_parameters.Windowed = FALSE;
169     present_parameters.hDeviceWindow = create_window();
170     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
171     present_parameters.BackBufferWidth = 640;
172     present_parameters.BackBufferHeight = 480;
173     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
174     present_parameters.EnableAutoDepthStencil = TRUE;
175     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
176
177     memset(&identifier, 0, sizeof(identifier));
178     hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
179     ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
180     trace("Driver string: \"%s\"\n", identifier.Driver);
181     trace("Description string: \"%s\"\n", identifier.Description);
182     trace("Device name string: \"%s\"\n", identifier.DeviceName);
183     trace("Driver version %d.%d.%d.%d\n",
184           HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
185           HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
186
187     hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
188     if(FAILED(hr)) {
189         present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
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             hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
193         }
194     }
195     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %08x\n", hr);
196
197     return device_ptr;
198 }
199
200 struct vertex
201 {
202     float x, y, z;
203     DWORD diffuse;
204 };
205
206 struct tvertex
207 {
208     float x, y, z, rhw;
209     DWORD diffuse;
210 };
211
212 struct nvertex
213 {
214     float x, y, z;
215     float nx, ny, nz;
216     DWORD diffuse;
217 };
218
219 static void lighting_test(IDirect3DDevice9 *device)
220 {
221     HRESULT hr;
222     DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
223     DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
224     DWORD color;
225     D3DMATERIAL9 material, old_material;
226     DWORD cop, carg;
227
228     float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
229                       0.0f, 1.0f, 0.0f, 0.0f,
230                       0.0f, 0.0f, 1.0f, 0.0f,
231                       0.0f, 0.0f, 0.0f, 1.0f };
232
233     struct vertex unlitquad[] =
234     {
235         {-1.0f, -1.0f,   0.1f,                          0xffff0000},
236         {-1.0f,  0.0f,   0.1f,                          0xffff0000},
237         { 0.0f,  0.0f,   0.1f,                          0xffff0000},
238         { 0.0f, -1.0f,   0.1f,                          0xffff0000},
239     };
240     struct vertex litquad[] =
241     {
242         {-1.0f,  0.0f,   0.1f,                          0xff00ff00},
243         {-1.0f,  1.0f,   0.1f,                          0xff00ff00},
244         { 0.0f,  1.0f,   0.1f,                          0xff00ff00},
245         { 0.0f,  0.0f,   0.1f,                          0xff00ff00},
246     };
247     struct nvertex unlitnquad[] =
248     {
249         { 0.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
250         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
251         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
252         { 1.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
253     };
254     struct nvertex litnquad[] =
255     {
256         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
257         { 0.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
258         { 1.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
259         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
260     };
261     WORD Indices[] = {0, 1, 2, 2, 3, 0};
262
263     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
264     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
265
266     /* Setup some states that may cause issues */
267     hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
268     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
269     hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
270     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
271     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
272     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
273     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
274     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
275     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
276     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
277     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
278     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
279     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
280     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
281     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
282     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
283     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
284     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
285     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
286     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
287     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
288     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
289     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
290     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
291
292     hr = IDirect3DDevice9_SetFVF(device, fvf);
293     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
294
295     hr = IDirect3DDevice9_BeginScene(device);
296     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
297     if(hr == D3D_OK)
298     {
299         /* No lights are defined... That means, lit vertices should be entirely black */
300         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
301         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
302         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
303                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
304         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
305
306         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
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, litquad, sizeof(litquad[0]));
310         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
311
312         hr = IDirect3DDevice9_SetFVF(device, nfvf);
313         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
314
315         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
316         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
317         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
318                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
319         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
320
321         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
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, litnquad, sizeof(litnquad[0]));
325         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
326
327         IDirect3DDevice9_EndScene(device);
328         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
329     }
330
331     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
332
333     color = getPixelColor(device, 160, 360); /* lower left quad - unlit without normals */
334     ok(color == 0x00ff0000, "Unlit quad without normals has color %08x\n", color);
335     color = getPixelColor(device, 160, 120); /* upper left quad - lit without normals */
336     ok(color == 0x00000000, "Lit quad without normals has color %08x\n", color);
337     color = getPixelColor(device, 480, 360); /* lower left quad - unlit with normals */
338     ok(color == 0x000000ff, "Unlit quad with normals has color %08x\n", color);
339     color = getPixelColor(device, 480, 120); /* upper left quad - lit with normals */
340     ok(color == 0x00000000, "Lit quad with normals has color %08x\n", color);
341
342     hr = IDirect3DDevice9_GetMaterial(device, &old_material);
343     ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
344     memset(&material, 0, sizeof(material));
345     material.Diffuse.r = 0.0;
346     material.Diffuse.g = 0.0;
347     material.Diffuse.b = 0.0;
348     material.Diffuse.a = 1.0;
349     material.Ambient.r = 0.0;
350     material.Ambient.g = 0.0;
351     material.Ambient.b = 0.0;
352     material.Ambient.a = 0.0;
353     material.Specular.r = 0.0;
354     material.Specular.g = 0.0;
355     material.Specular.b = 0.0;
356     material.Specular.a = 0.0;
357     material.Emissive.r = 0.0;
358     material.Emissive.g = 0.0;
359     material.Emissive.b = 0.0;
360     material.Emissive.a = 0.0;
361     material.Power = 0.0;
362     IDirect3DDevice9_SetMaterial(device, &material);
363     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
364
365     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
366     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
367     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
368     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
369
370     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
371     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
372     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
373     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
374     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
375     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
376     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
377     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
378
379     hr = IDirect3DDevice9_BeginScene(device);
380     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
381     if(SUCCEEDED(hr)) {
382         struct vertex lighting_test[] = {
383             {-1.0,   -1.0,   0.1,    0x8000ff00},
384             { 1.0,   -1.0,   0.1,    0x80000000},
385             {-1.0,    1.0,   0.1,    0x8000ff00},
386             { 1.0,    1.0,   0.1,    0x80000000}
387         };
388         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
389         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
390         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
391         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
392
393         hr = IDirect3DDevice9_EndScene(device);
394         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
395     }
396
397     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
398     color = getPixelColor(device, 320, 240);
399     ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
400
401     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
402     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
403     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
404     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
405     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
406     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
407     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
408     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
409     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
410     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
411     hr = IDirect3DDevice9_SetMaterial(device, &old_material);
412     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
413 }
414
415 static void clear_test(IDirect3DDevice9 *device)
416 {
417     /* Tests the correctness of clearing parameters */
418     HRESULT hr;
419     D3DRECT rect[2];
420     D3DRECT rect_negneg;
421     DWORD color;
422     D3DVIEWPORT9 old_vp, vp;
423     RECT scissor;
424     DWORD oldColorWrite;
425     BOOL invalid_clear_failed = FALSE;
426
427     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
428     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
429
430     /* Positive x, negative y */
431     rect[0].x1 = 0;
432     rect[0].y1 = 480;
433     rect[0].x2 = 320;
434     rect[0].y2 = 240;
435
436     /* Positive x, positive y */
437     rect[1].x1 = 0;
438     rect[1].y1 = 0;
439     rect[1].x2 = 320;
440     rect[1].y2 = 240;
441     /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
442      * returns D3D_OK, but ignores the rectangle silently
443      */
444     hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
445     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
446     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
447
448     /* negative x, negative y */
449     rect_negneg.x1 = 640;
450     rect_negneg.y1 = 240;
451     rect_negneg.x2 = 320;
452     rect_negneg.y2 = 0;
453     hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
454     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
455     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
456
457     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
458
459     color = getPixelColor(device, 160, 360); /* lower left quad */
460     ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
461     color = getPixelColor(device, 160, 120); /* upper left quad */
462     if(invalid_clear_failed) {
463         /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
464         ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
465     } else {
466         /* If the negative rectangle was dropped silently, the correct ones are cleared */
467         ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
468     }
469     color = getPixelColor(device, 480, 360); /* lower right quad  */
470     ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
471     color = getPixelColor(device, 480, 120); /* upper right quad */
472     ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
473
474     /* Test how the viewport affects clears */
475     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
476     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
477     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
478     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
479
480     vp.X = 160;
481     vp.Y = 120;
482     vp.Width = 160;
483     vp.Height = 120;
484     vp.MinZ = 0.0;
485     vp.MaxZ = 1.0;
486     hr = IDirect3DDevice9_SetViewport(device, &vp);
487     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
488     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
489     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
490
491     vp.X = 320;
492     vp.Y = 240;
493     vp.Width = 320;
494     vp.Height = 240;
495     vp.MinZ = 0.0;
496     vp.MaxZ = 1.0;
497     hr = IDirect3DDevice9_SetViewport(device, &vp);
498     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
499     rect[0].x1 = 160;
500     rect[0].y1 = 120;
501     rect[0].x2 = 480;
502     rect[0].y2 = 360;
503     hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
504     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
505
506     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
507     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
508
509     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
510     color = getPixelColor(device, 158, 118);
511     ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
512     color = getPixelColor(device, 162, 118);
513     ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
514     color = getPixelColor(device, 158, 122);
515     ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
516     color = getPixelColor(device, 162, 122);
517     ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
518
519     color = getPixelColor(device, 318, 238);
520     ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
521     color = getPixelColor(device, 322, 238);
522     ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
523     color = getPixelColor(device, 318, 242);
524     ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
525     color = getPixelColor(device, 322, 242);
526     ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
527
528     color = getPixelColor(device, 478, 358);
529     ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
530     color = getPixelColor(device, 482, 358);
531     ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
532     color = getPixelColor(device, 478, 362);
533     ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
534     color = getPixelColor(device, 482, 362);
535     ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
536
537     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
538     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
539
540     scissor.left = 160;
541     scissor.right = 480;
542     scissor.top = 120;
543     scissor.bottom = 360;
544     hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
545     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
546     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
547     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
548
549     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
550     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
551     hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
552     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
553
554     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
555     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
556
557     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
558     color = getPixelColor(device, 158, 118);
559     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
560     color = getPixelColor(device, 162, 118);
561     ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
562     color = getPixelColor(device, 158, 122);
563     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
564     color = getPixelColor(device, 162, 122);
565     ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
566
567     color = getPixelColor(device, 158, 358);
568     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
569     color = getPixelColor(device, 162, 358);
570     ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
571     color = getPixelColor(device, 158, 358);
572     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
573     color = getPixelColor(device, 162, 362);
574     ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
575
576     color = getPixelColor(device, 478, 118);
577     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
578     color = getPixelColor(device, 478, 122);
579     ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
580     color = getPixelColor(device, 482, 122);
581     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
582     color = getPixelColor(device, 482, 358);
583     ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
584
585     color = getPixelColor(device, 478, 358);
586     ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
587     color = getPixelColor(device, 478, 362);
588     ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
589     color = getPixelColor(device, 482, 358);
590     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
591     color = getPixelColor(device, 482, 362);
592     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
593
594     color = getPixelColor(device, 318, 238);
595     ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
596     color = getPixelColor(device, 318, 242);
597     ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
598     color = getPixelColor(device, 322, 238);
599     ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
600     color = getPixelColor(device, 322, 242);
601     ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
602
603     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
604     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
605     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
606     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
607
608     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
609     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
610
611     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
612     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
613
614     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
615
616     /* Colorwriteenable does not affect the clear */
617     color = getPixelColor(device, 320, 240);
618     ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
619 }
620
621 typedef struct {
622     float in[4];
623     DWORD out;
624 } test_data_t;
625
626 /*
627  *  c7      mova    ARGB            mov     ARGB
628  * -2.4     -2      0x00ffff00      -3      0x00ff0000
629  * -1.6     -2      0x00ffff00      -2      0x00ffff00
630  * -0.4      0      0x0000ffff      -1      0x0000ff00
631  *  0.4      0      0x0000ffff       0      0x0000ffff
632  *  1.6      2      0x00ff00ff       1      0x000000ff
633  *  2.4      2      0x00ff00ff       2      0x00ff00ff
634  */
635 static void test_mova(IDirect3DDevice9 *device)
636 {
637     static const DWORD mova_test[] = {
638         0xfffe0200,                                                             /* vs_2_0                       */
639         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
640         0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
641         0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
642         0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
643         0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
644         0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
645         0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
646         0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
647         0x0200002e, 0xb0010000, 0xa0000007,                                     /* mova a0.x, c7.x              */
648         0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000,                         /* mov oD0, c[a0.x + 3]         */
649         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
650         0x0000ffff                                                              /* END                          */
651     };
652     static const DWORD mov_test[] = {
653         0xfffe0101,                                                             /* vs_1_1                       */
654         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
655         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
656         0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
657         0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
658         0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
659         0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
660         0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
661         0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
662         0x00000001, 0xb0010000, 0xa0000007,                                     /* mov a0.x, c7.x               */
663         0x00000001, 0xd00f0000, 0xa0e42003,                                     /* mov oD0, c[a0.x + 3]         */
664         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
665         0x0000ffff                                                              /* END                          */
666     };
667
668     static const test_data_t test_data[2][6] = {
669         {
670             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
671             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
672             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
673             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
674             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
675             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
676         },
677         {
678             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
679             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
680             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
681             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
682             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
683             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
684         }
685     };
686
687     static const float quad[][3] = {
688         {-1.0f, -1.0f, 0.0f},
689         {-1.0f,  1.0f, 0.0f},
690         { 1.0f, -1.0f, 0.0f},
691         { 1.0f,  1.0f, 0.0f},
692     };
693
694     static const D3DVERTEXELEMENT9 decl_elements[] = {
695         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
696         D3DDECL_END()
697     };
698
699     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
700     IDirect3DVertexShader9 *mova_shader = NULL;
701     IDirect3DVertexShader9 *mov_shader = NULL;
702     HRESULT hr;
703     UINT i, j;
704
705     hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
706     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
707     hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
708     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
709     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
710     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
711     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
712     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
713
714     hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
715     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
716     for(j = 0; j < 2; ++j)
717     {
718         for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
719         {
720             DWORD color;
721
722             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
723             ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
724
725             hr = IDirect3DDevice9_BeginScene(device);
726             ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
727
728             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
729             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
730
731             hr = IDirect3DDevice9_EndScene(device);
732             ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
733
734             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
735             ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
736
737             color = getPixelColor(device, 320, 240);
738             ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
739                test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
740
741             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
742             ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
743         }
744         hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
745         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
746     }
747
748     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
749     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
750
751     IDirect3DVertexDeclaration9_Release(vertex_declaration);
752     IDirect3DVertexShader9_Release(mova_shader);
753     IDirect3DVertexShader9_Release(mov_shader);
754 }
755
756 struct sVertex {
757     float x, y, z;
758     DWORD diffuse;
759     DWORD specular;
760 };
761
762 struct sVertexT {
763     float x, y, z, rhw;
764     DWORD diffuse;
765     DWORD specular;
766 };
767
768 static void fog_test(IDirect3DDevice9 *device)
769 {
770     HRESULT hr;
771     DWORD color;
772     BYTE r, g, b;
773     float start = 0.0f, end = 1.0f;
774     D3DCAPS9 caps;
775     int i;
776
777     /* Gets full z based fog with linear fog, no fog with specular color */
778     struct sVertex unstransformed_1[] = {
779         {-1,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
780         {-1,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
781         { 0,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
782         { 0,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
783     };
784     /* Ok, I am too lazy to deal with transform matrices */
785     struct sVertex unstransformed_2[] = {
786         {-1,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
787         {-1,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
788         { 0,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
789         { 0,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
790     };
791     /* Untransformed ones. Give them a different diffuse color to make the test look
792      * nicer. It also makes making sure that they are drawn correctly easier.
793      */
794     struct sVertexT transformed_1[] = {
795         {320,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
796         {640,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
797         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
798         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
799     };
800     struct sVertexT transformed_2[] = {
801         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
802         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
803         {640,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
804         {320,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
805     };
806     struct vertex rev_fog_quads[] = {
807        {-1.0,   -1.0,   0.1,    0x000000ff},
808        {-1.0,    0.0,   0.1,    0x000000ff},
809        { 0.0,    0.0,   0.1,    0x000000ff},
810        { 0.0,   -1.0,   0.1,    0x000000ff},
811
812        { 0.0,   -1.0,   0.9,    0x000000ff},
813        { 0.0,    0.0,   0.9,    0x000000ff},
814        { 1.0,    0.0,   0.9,    0x000000ff},
815        { 1.0,   -1.0,   0.9,    0x000000ff},
816
817        { 0.0,    0.0,   0.4,    0x000000ff},
818        { 0.0,    1.0,   0.4,    0x000000ff},
819        { 1.0,    1.0,   0.4,    0x000000ff},
820        { 1.0,    0.0,   0.4,    0x000000ff},
821
822        {-1.0,    0.0,   0.7,    0x000000ff},
823        {-1.0,    1.0,   0.7,    0x000000ff},
824        { 0.0,    1.0,   0.7,    0x000000ff},
825        { 0.0,    0.0,   0.7,    0x000000ff},
826     };
827     WORD Indices[] = {0, 1, 2, 2, 3, 0};
828
829     memset(&caps, 0, sizeof(caps));
830     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
831     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
832     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
833     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
834
835     /* Setup initial states: No lighting, fog on, fog color */
836     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
837     ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
838     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
839     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
840     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
841     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
842
843     /* First test: Both table fog and vertex fog off */
844     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
845     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
846     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
847     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
848
849     /* Start = 0, end = 1. Should be default, but set them */
850     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
851     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
852     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
853     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
854
855     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
856     {
857         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
858         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
859         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
860         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
861                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
862                                                      sizeof(unstransformed_1[0]));
863         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
864
865         /* That makes it use the Z value */
866         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
867         ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
868         /* Untransformed, vertex fog != none (or table fog != none):
869          * Use the Z value as input into the equation
870          */
871         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
872                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
873                                                      sizeof(unstransformed_1[0]));
874         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
875
876         /* transformed verts */
877         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
878         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
879         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
880         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
881                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
882                                                      sizeof(transformed_1[0]));
883         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
884
885         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
886         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
887         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
888          * equation
889          */
890         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
891                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
892                                                      sizeof(transformed_2[0]));
893
894         hr = IDirect3DDevice9_EndScene(device);
895         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
896     }
897     else
898     {
899         ok(FALSE, "BeginScene failed\n");
900     }
901
902     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
903     color = getPixelColor(device, 160, 360);
904     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
905     color = getPixelColor(device, 160, 120);
906     ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with linear vertex fog has color %08x\n", color);
907     color = getPixelColor(device, 480, 120);
908     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
909     if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
910     {
911         color = getPixelColor(device, 480, 360);
912         ok(color == 0x0000FF00 || color == 0x0000FE00, "Transformed vertex with linear table fog has color %08x\n", color);
913     }
914     else
915     {
916         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
917          * The settings above result in no fogging with vertex fog
918          */
919         color = getPixelColor(device, 480, 120);
920         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
921         trace("Info: Table fog not supported by this device\n");
922     }
923
924     /* Now test the special case fogstart == fogend */
925     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
926     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
927
928     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
929     {
930         start = 512;
931         end = 512;
932         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
933         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
934         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
935         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
936
937         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
938         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
939         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
940         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
941         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
942         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
943
944         /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
945          * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
946          * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
947          * The third transformed quad remains unfogged because the fogcoords are read from the specular
948          * color and has fixed fogstart and fogend.
949          */
950         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
951                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
952                 sizeof(unstransformed_1[0]));
953         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
954         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
955                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
956                 sizeof(unstransformed_1[0]));
957         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
958
959         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
960         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
961         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
962         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
963                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
964                 sizeof(transformed_1[0]));
965         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
966
967         hr = IDirect3DDevice9_EndScene(device);
968         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
969     }
970     else
971     {
972         ok(FALSE, "BeginScene failed\n");
973     }
974     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
975     color = getPixelColor(device, 160, 360);
976     ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
977     color = getPixelColor(device, 160, 120);
978     ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
979     color = getPixelColor(device, 480, 120);
980     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
981
982     /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
983      * but without shaders it seems to work everywhere
984      */
985     end = 0.2;
986     start = 0.8;
987     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
988     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
989     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
990     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
991     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
992     ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
993
994     /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
995      * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
996      * so skip this for now
997      */
998     for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
999         const char *mode = (i ? "table" : "vertex");
1000         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1001         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1002         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1003         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1004         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1005         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1006         hr = IDirect3DDevice9_BeginScene(device);
1007         ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1008         if(SUCCEEDED(hr)) {
1009             WORD Indices2[] = { 0,  1,  2,  2,  3, 0,
1010                                 4,  5,  6,  6,  7, 4,
1011                                 8,  9, 10, 10, 11, 8,
1012                             12, 13, 14, 14, 15, 12};
1013
1014             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1015                     16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1016                     sizeof(rev_fog_quads[0]));
1017
1018             hr = IDirect3DDevice9_EndScene(device);
1019             ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1020         }
1021         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1022         color = getPixelColor(device, 160, 360);
1023         ok(color == 0x0000FF00 || color == 0x0000FE00, "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00\n", mode, color);
1024
1025         color = getPixelColor(device, 160, 120);
1026         r = (color & 0x00ff0000) >> 16;
1027         g = (color & 0x0000ff00) >>  8;
1028         b = (color & 0x000000ff);
1029         ok(r == 0x00 && g >= 0x29 && g <= 0x2d && b >= 0xd2 && b <= 0xd6,
1030            "Reversed %s fog: z=0.7 has color 0x%08x, expected\n", mode, color);
1031
1032         color = getPixelColor(device, 480, 120);
1033         r = (color & 0x00ff0000) >> 16;
1034         g = (color & 0x0000ff00) >>  8;
1035         b = (color & 0x000000ff);
1036         ok(r == 0x00 && g >= 0xa8 && g <= 0xac && b >= 0x53 && b <= 0x57,
1037            "Reversed %s fog: z=0.4 has color 0x%08x, expected\n", mode, color);
1038
1039         color = getPixelColor(device, 480, 360);
1040         ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1041
1042         if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1043             skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1044             break;
1045         }
1046     }
1047     /* Turn off the fog master switch to avoid confusing other tests */
1048     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1049     ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1050     start = 0.0;
1051     end = 1.0;
1052     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1053     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1054     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1055     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1056     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1057     ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1058     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1059     ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1060 }
1061
1062 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1063  * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1064  * regardless of the actual addressing mode set. */
1065 static void test_cube_wrap(IDirect3DDevice9 *device)
1066 {
1067     static const float quad[][6] = {
1068         {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1069         {-1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1070         { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1071         { 1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1072     };
1073
1074     static const D3DVERTEXELEMENT9 decl_elements[] = {
1075         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1076         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1077         D3DDECL_END()
1078     };
1079
1080     static const struct {
1081         D3DTEXTUREADDRESS mode;
1082         const char *name;
1083     } address_modes[] = {
1084         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1085         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1086         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1087         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1088         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1089     };
1090
1091     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1092     IDirect3DCubeTexture9 *texture = NULL;
1093     IDirect3DSurface9 *surface = NULL;
1094     D3DLOCKED_RECT locked_rect;
1095     HRESULT hr;
1096     UINT x;
1097     INT y, face;
1098
1099     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1100     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1101     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1102     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1103
1104     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1105             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1106     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1107
1108     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1109     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1110
1111     for (y = 0; y < 128; ++y)
1112     {
1113         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1114         for (x = 0; x < 64; ++x)
1115         {
1116             *ptr++ = 0xffff0000;
1117         }
1118         for (x = 64; x < 128; ++x)
1119         {
1120             *ptr++ = 0xff0000ff;
1121         }
1122     }
1123
1124     hr = IDirect3DSurface9_UnlockRect(surface);
1125     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1126
1127     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1128             D3DPOOL_DEFAULT, &texture, NULL);
1129     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1130
1131     /* Create cube faces */
1132     for (face = 0; face < 6; ++face)
1133     {
1134         IDirect3DSurface9 *face_surface = NULL;
1135
1136         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1137         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1138
1139         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1140         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1141
1142         IDirect3DSurface9_Release(face_surface);
1143     }
1144
1145     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1146     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1147
1148     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1149     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1150     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1151     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1152     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1153     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1154
1155     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1156     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1157
1158     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1159     {
1160         DWORD color;
1161
1162         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1163         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1164         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1165         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1166
1167         hr = IDirect3DDevice9_BeginScene(device);
1168         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1169
1170         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1171         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1172
1173         hr = IDirect3DDevice9_EndScene(device);
1174         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1175
1176         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1177         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1178
1179         /* Due to the nature of this test, we sample essentially at the edge
1180          * between two faces. Because of this it's undefined from which face
1181          * the driver will sample. Fortunately that's not important for this
1182          * test, since all we care about is that it doesn't sample from the
1183          * other side of the surface or from the border. */
1184         color = getPixelColor(device, 320, 240);
1185         ok(color == 0x00ff0000 || color == 0x000000ff,
1186                 "Got color 0x%08x for addressing mode %s, expected 0x00ff0000 or 0x000000ff.\n",
1187                 color, address_modes[x].name);
1188
1189         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1190         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1191     }
1192
1193     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1194     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1195
1196     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1197     IDirect3DCubeTexture9_Release(texture);
1198     IDirect3DSurface9_Release(surface);
1199 }
1200
1201 static void offscreen_test(IDirect3DDevice9 *device)
1202 {
1203     HRESULT hr;
1204     IDirect3DTexture9 *offscreenTexture = NULL;
1205     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1206     DWORD color;
1207
1208     static const float quad[][5] = {
1209         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1210         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1211         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1212         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1213     };
1214
1215     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1216     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1217
1218     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1219     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1220     if(!offscreenTexture) {
1221         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1222         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1223         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1224         if(!offscreenTexture) {
1225             skip("Cannot create an offscreen render target\n");
1226             goto out;
1227         }
1228     }
1229
1230     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1231     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1232     if(!backbuffer) {
1233         goto out;
1234     }
1235
1236     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1237     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1238     if(!offscreen) {
1239         goto out;
1240     }
1241
1242     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1243     ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1244
1245     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1246     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1247     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1248     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1249     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1250     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1251     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1252     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1253     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1254     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1255
1256     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1257         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1258         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1259         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1260         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1261
1262         /* Draw without textures - Should result in a white quad */
1263         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1264         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1265
1266         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1267         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1268         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1269         ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1270
1271         /* This time with the texture */
1272         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1273         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1274
1275         IDirect3DDevice9_EndScene(device);
1276     }
1277
1278     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1279
1280     /* Center quad - should be white */
1281     color = getPixelColor(device, 320, 240);
1282     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1283     /* Some quad in the cleared part of the texture */
1284     color = getPixelColor(device, 170, 240);
1285     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1286     /* Part of the originally cleared back buffer */
1287     color = getPixelColor(device, 10, 10);
1288     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1289     if(0) {
1290         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1291          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1292          * the offscreen rendering mode this test would succeed or fail
1293          */
1294         color = getPixelColor(device, 10, 470);
1295         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1296     }
1297
1298 out:
1299     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1300
1301     /* restore things */
1302     if(backbuffer) {
1303         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1304         IDirect3DSurface9_Release(backbuffer);
1305     }
1306     if(offscreenTexture) {
1307         IDirect3DTexture9_Release(offscreenTexture);
1308     }
1309     if(offscreen) {
1310         IDirect3DSurface9_Release(offscreen);
1311     }
1312 }
1313
1314 /* This test tests fog in combination with shaders.
1315  * What's tested: linear fog (vertex and table) with pixel shader
1316  *                linear table fog with non foggy vertex shader
1317  *                vertex fog with foggy vertex shader
1318  * What's not tested: non linear fog with shader
1319  *                    table fog with foggy vertex shader
1320  */
1321 static void fog_with_shader_test(IDirect3DDevice9 *device)
1322 {
1323     HRESULT hr;
1324     DWORD color;
1325     union {
1326         float f;
1327         DWORD i;
1328     } start, end;
1329     unsigned int i, j;
1330
1331     /* basic vertex shader without fog computation ("non foggy") */
1332     static const DWORD vertex_shader_code1[] = {
1333         0xfffe0101,                                                             /* vs_1_1                       */
1334         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1335         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1336         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1337         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1338         0x0000ffff
1339     };
1340     /* basic vertex shader with reversed fog computation ("foggy") */
1341     static const DWORD vertex_shader_code2[] = {
1342         0xfffe0101,                                                             /* vs_1_1                        */
1343         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1344         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1345         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1346         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1347         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1348         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1349         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1350         0x0000ffff
1351     };
1352     /* basic pixel shader */
1353     static const DWORD pixel_shader_code[] = {
1354         0xffff0101,                                                             /* ps_1_1     */
1355         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, vo */
1356         0x0000ffff
1357     };
1358
1359     static struct vertex quad[] = {
1360         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1361         {-1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1362         { 1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1363         { 1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1364     };
1365
1366     static const D3DVERTEXELEMENT9 decl_elements[] = {
1367         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1368         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1369         D3DDECL_END()
1370     };
1371
1372     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1373     IDirect3DVertexShader9      *vertex_shader[3]   = {NULL, NULL, NULL};
1374     IDirect3DPixelShader9       *pixel_shader[2]    = {NULL, NULL};
1375
1376     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1377     static const struct test_data_t {
1378         int vshader;
1379         int pshader;
1380         D3DFOGMODE vfog;
1381         D3DFOGMODE tfog;
1382         unsigned int color[11];
1383     } test_data[] = {
1384         /* only pixel shader: */
1385         {0, 1, 0, 3,
1386         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1387         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1388         {0, 1, 1, 3,
1389         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1390         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1391         {0, 1, 2, 3,
1392         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1393         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1394         {0, 1, 3, 0,
1395         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1396         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1397         {0, 1, 3, 3,
1398         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1399         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1400
1401         /* vertex shader */
1402         {1, 0, 0, 0,
1403         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1404          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1405         {1, 0, 0, 3,
1406         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1407         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1408         {1, 0, 1, 3,
1409         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1410         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1411
1412         {1, 0, 2, 3,
1413         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1414         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1415         {1, 0, 3, 3,
1416         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1417         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1418
1419         /* vertex shader and pixel shader */
1420         {1, 1, 0, 3,
1421         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1422         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1423         {1, 1, 1, 3,
1424         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1425         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1426         {1, 1, 2, 3,
1427         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1428         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1429
1430         {1, 1, 3, 3,
1431         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1432         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1433
1434
1435 #if 0  /* FIXME: these fail on GeForce 8500 */
1436         /* foggy vertex shader */
1437         {2, 0, 0, 0,
1438         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1439          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1440         {2, 0, 1, 0,
1441         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1442          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1443         {2, 0, 2, 0,
1444         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1445          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1446         {2, 0, 3, 0,
1447         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1448          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1449 #endif
1450
1451         /* foggy vertex shader and pixel shader */
1452         {2, 1, 0, 0,
1453         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1454          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1455         {2, 1, 1, 0,
1456         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1457          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1458         {2, 1, 2, 0,
1459         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1460          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1461         {2, 1, 3, 0,
1462         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1463          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1464
1465     };
1466
1467     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1468     start.f=0.1f;
1469     end.f=0.9f;
1470
1471     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1472     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1473     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1474     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1475     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1476     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1477     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1478     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1479
1480     /* Setup initial states: No lighting, fog on, fog color */
1481     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1482     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1483     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1484     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1485     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1486     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1487     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1488     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1489
1490     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1491     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1492     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1493     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1494
1495     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1496     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1497     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1498     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1499     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1500
1501     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1502     {
1503         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1504         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1505         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1506         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1507         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1508         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1509         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1510         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1511
1512         for(j=0; j < 11; j++)
1513         {
1514             /* Don't use the whole zrange to prevent rounding errors */
1515             quad[0].z = 0.001f + (float)j / 10.02f;
1516             quad[1].z = 0.001f + (float)j / 10.02f;
1517             quad[2].z = 0.001f + (float)j / 10.02f;
1518             quad[3].z = 0.001f + (float)j / 10.02f;
1519
1520             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1521             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1522
1523             hr = IDirect3DDevice9_BeginScene(device);
1524             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1525
1526             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1527             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1528
1529             hr = IDirect3DDevice9_EndScene(device);
1530             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1531
1532             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1533
1534             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1535             color = getPixelColor(device, 128, 240);
1536             ok(color_match(color, test_data[i].color[j], 13),
1537                "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1538                test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1539         }
1540     }
1541
1542     /* reset states */
1543     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1544     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1545     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1546     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1547     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1548     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1549     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1550     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1551
1552     IDirect3DVertexShader9_Release(vertex_shader[1]);
1553     IDirect3DVertexShader9_Release(vertex_shader[2]);
1554     IDirect3DPixelShader9_Release(pixel_shader[1]);
1555     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1556 }
1557
1558 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1559     unsigned int i, x, y;
1560     HRESULT hr;
1561     IDirect3DTexture9 *texture[2] = {NULL, NULL};
1562     D3DLOCKED_RECT locked_rect;
1563
1564     /* Generate the textures */
1565     for(i=0; i<2; i++)
1566     {
1567         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1568                                             D3DPOOL_MANAGED, &texture[i], NULL);
1569         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1570
1571         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1572         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1573         for (y = 0; y < 128; ++y)
1574         {
1575             if(i)
1576             { /* Set up black texture with 2x2 texel white spot in the middle */
1577                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1578                 for (x = 0; x < 128; ++x)
1579                 {
1580                     if(y>62 && y<66 && x>62 && x<66)
1581                         *ptr++ = 0xffffffff;
1582                     else
1583                         *ptr++ = 0xff000000;
1584                 }
1585             }
1586             else
1587             { /* Set up a displacement map which points away from the center parallel to the closest axis.
1588                * (if multiplied with bumpenvmat)
1589               */
1590                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1591                 for (x = 0; x < 128; ++x)
1592                 {
1593                     if(abs(x-64)>abs(y-64))
1594                     {
1595                         if(x < 64)
1596                             *ptr++ = 0xc000;
1597                         else
1598                             *ptr++ = 0x4000;
1599                     }
1600                     else
1601                     {
1602                         if(y < 64)
1603                             *ptr++ = 0x0040;
1604                         else
1605                             *ptr++ = 0x00c0;
1606                     }
1607                 }
1608             }
1609         }
1610         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1611         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1612
1613         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1614         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1615
1616         /* Disable texture filtering */
1617         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1618         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1619         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1620         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1621
1622         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1623         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1624         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1625         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1626     }
1627 }
1628
1629 /* test the behavior of the texbem instruction
1630  * with normal 2D and projective 2D textures
1631  */
1632 static void texbem_test(IDirect3DDevice9 *device)
1633 {
1634     HRESULT hr;
1635     DWORD color;
1636     int i;
1637
1638     static const DWORD pixel_shader_code[] = {
1639         0xffff0101,                         /* ps_1_1*/
1640         0x00000042, 0xb00f0000,             /* tex t0*/
1641         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1642         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1643         0x0000ffff
1644     };
1645     static const DWORD double_texbem_code[] =  {
1646         0xffff0103,                                         /* ps_1_3           */
1647         0x00000042, 0xb00f0000,                             /* tex t0           */
1648         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
1649         0x00000042, 0xb00f0002,                             /* tex t2           */
1650         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
1651         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
1652         0x0000ffff                                          /* end              */
1653     };
1654
1655
1656     static const float quad[][7] = {
1657         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1658         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1659         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1660         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1661     };
1662     static const float quad_proj[][9] = {
1663         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
1664         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
1665         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
1666         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1667     };
1668
1669     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1670         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1671         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1672         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1673         D3DDECL_END()
1674     },{
1675         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1676         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1677         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1678         D3DDECL_END()
1679     } };
1680
1681     /* use asymmetric matrix to test loading */
1682     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1683
1684     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1685     IDirect3DPixelShader9       *pixel_shader       = NULL;
1686     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
1687     D3DLOCKED_RECT locked_rect;
1688
1689     generate_bumpmap_textures(device);
1690
1691     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1692     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1693     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1694     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1695     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1696
1697     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1698     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1699
1700     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1701     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1702
1703     for(i=0; i<2; i++)
1704     {
1705         if(i)
1706         {
1707             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1708             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1709         }
1710
1711         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1712         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1713         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1714         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1715
1716         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1717         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1718         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1719         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1720
1721         hr = IDirect3DDevice9_BeginScene(device);
1722         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1723
1724         if(!i)
1725             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1726         else
1727             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1728         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1729
1730         hr = IDirect3DDevice9_EndScene(device);
1731         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1732
1733         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1734         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1735
1736         color = getPixelColor(device, 320-32, 240);
1737         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1738         color = getPixelColor(device, 320+32, 240);
1739         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1740         color = getPixelColor(device, 320, 240-32);
1741         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1742         color = getPixelColor(device, 320, 240+32);
1743         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1744
1745         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1746         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1747         IDirect3DPixelShader9_Release(pixel_shader);
1748
1749         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1750         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1751         IDirect3DVertexDeclaration9_Release(vertex_declaration);
1752     }
1753
1754     /* clean up */
1755     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1756     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1757
1758     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1759     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1760
1761     for(i=0; i<2; i++)
1762     {
1763         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1764         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1765         IDirect3DTexture9_Release(texture); /* For the GetTexture */
1766         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1767         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1768         IDirect3DTexture9_Release(texture);
1769     }
1770
1771     /* Test double texbem */
1772     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1773     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1774     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1775     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1776     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1777     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1778     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1779     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1780
1781     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1782     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1783     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1784     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1785
1786     hr = IDirect3DTexture9_UnlockRect(texture, 0);
1787     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1788
1789     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1790     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1791     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1792     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1793     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1794     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1795
1796     {
1797         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1798 #define tex  0x00ff0000
1799 #define tex1 0x0000ff00
1800 #define origin 0x000000ff
1801         static const DWORD pixel_data[] = {
1802             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1803             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1804             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1805             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1806             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
1807             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1808             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1809             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1810         };
1811 #undef tex1
1812 #undef tex2
1813 #undef origin
1814
1815         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1816         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1817         for(i = 0; i < 8; i++) {
1818             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1819         }
1820         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1821         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1822     }
1823
1824     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1825     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1826     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1827     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1828     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1829     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1830     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1831     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1832     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1833     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1834     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1835     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1836
1837     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
1838     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
1839     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1840     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1841     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1842     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1843
1844     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
1845     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
1846     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1847     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1848     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1849     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1850
1851     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1852     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1853     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1854     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1855     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1856     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1857     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1858     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1859
1860     hr = IDirect3DDevice9_BeginScene(device);
1861     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1862     if(SUCCEEDED(hr)) {
1863         static const float double_quad[] = {
1864             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1865              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1866             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1867              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1868         };
1869
1870         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
1871         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1872         hr = IDirect3DDevice9_EndScene(device);
1873         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1874     }
1875     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1876     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1877     color = getPixelColor(device, 320, 240);
1878     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1879
1880     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1881     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1882     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
1883     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1884     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
1885     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1886     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
1887     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1888     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1889     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1890
1891     IDirect3DPixelShader9_Release(pixel_shader);
1892     IDirect3DTexture9_Release(texture);
1893     IDirect3DTexture9_Release(texture1);
1894     IDirect3DTexture9_Release(texture2);
1895 }
1896
1897 static void z_range_test(IDirect3DDevice9 *device)
1898 {
1899     const struct vertex quad[] =
1900     {
1901         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
1902         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
1903         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
1904         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
1905     };
1906     const struct vertex quad2[] =
1907     {
1908         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
1909         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
1910         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
1911         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
1912     };
1913
1914     const struct tvertex quad3[] =
1915     {
1916         {    0,   240,   1.1f,  1.0,                    0xffffff00},
1917         {    0,   480,   1.1f,  1.0,                    0xffffff00},
1918         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
1919         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
1920     };
1921     const struct tvertex quad4[] =
1922     {
1923         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
1924         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
1925         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
1926         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
1927     };
1928     HRESULT hr;
1929     DWORD color;
1930     IDirect3DVertexShader9 *shader;
1931     IDirect3DVertexDeclaration9 *decl;
1932     D3DCAPS9 caps;
1933     const DWORD shader_code[] = {
1934         0xfffe0101,                                     /* vs_1_1           */
1935         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
1936         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
1937         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
1938         0x0000ffff                                      /* end              */
1939     };
1940     static const D3DVERTEXELEMENT9 decl_elements[] = {
1941         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1942         D3DDECL_END()
1943     };
1944     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
1945      * then call Present. Then clear the color buffer to make sure it has some defined content
1946      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
1947      * by the depth value.
1948      */
1949     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
1950     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1951     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1952     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1953
1954     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1955     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1956     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1957     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1958     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
1959     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1960     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1961     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1962     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1963     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1964
1965     hr = IDirect3DDevice9_BeginScene(device);
1966     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
1967     if(hr == D3D_OK)
1968     {
1969         /* Test the untransformed vertex path */
1970         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
1971         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
1972         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
1973         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1974         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
1975         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
1976
1977         /* Test the transformed vertex path */
1978         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
1979         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1980
1981         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
1982         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
1983         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1984         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1985         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
1986         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
1987
1988         hr = IDirect3DDevice9_EndScene(device);
1989         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
1990     }
1991
1992     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1993     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1994
1995     /* Do not test the exact corner pixels, but go pretty close to them */
1996
1997     /* Clipped because z > 1.0 */
1998     color = getPixelColor(device, 28, 238);
1999     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2000     color = getPixelColor(device, 28, 241);
2001     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2002
2003     /* Not clipped, > z buffer clear value(0.75) */
2004     color = getPixelColor(device, 31, 238);
2005     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2006     color = getPixelColor(device, 31, 241);
2007     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2008     color = getPixelColor(device, 100, 238);
2009     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2010     color = getPixelColor(device, 100, 241);
2011     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2012
2013     /* Not clipped, < z buffer clear value */
2014     color = getPixelColor(device, 104, 238);
2015     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2016     color = getPixelColor(device, 104, 241);
2017     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2018     color = getPixelColor(device, 318, 238);
2019     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2020     color = getPixelColor(device, 318, 241);
2021     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2022
2023     /* Clipped because z < 0.0 */
2024     color = getPixelColor(device, 321, 238);
2025     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2026     color = getPixelColor(device, 321, 241);
2027     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2028
2029     /* Test the shader path */
2030     IDirect3DDevice9_GetDeviceCaps(device, &caps);
2031     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2032         skip("Vertex shaders not supported\n");
2033         goto out;
2034     }
2035     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2036     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2037     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2038     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2039
2040     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2041
2042     IDirect3DDevice9_SetVertexDeclaration(device, decl);
2043     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2044     IDirect3DDevice9_SetVertexShader(device, shader);
2045     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2046
2047     hr = IDirect3DDevice9_BeginScene(device);
2048     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2049     if(hr == D3D_OK)
2050     {
2051         float colorf[] = {1.0, 0.0, 0.0, 1.0};
2052         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2053         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2054         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2055         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2056         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2057         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2058         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2059         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2060         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2061
2062         hr = IDirect3DDevice9_EndScene(device);
2063         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2064     }
2065
2066     IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2067     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2068     IDirect3DDevice9_SetVertexShader(device, NULL);
2069     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2070
2071     IDirect3DVertexDeclaration9_Release(decl);
2072     IDirect3DVertexShader9_Release(shader);
2073
2074     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2075     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2076     /* Z < 1.0 */
2077     color = getPixelColor(device, 28, 238);
2078     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2079
2080     /* 1.0 < z < 0.75 */
2081     color = getPixelColor(device, 31, 238);
2082     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2083     color = getPixelColor(device, 100, 238);
2084     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2085
2086     /* 0.75 < z < 0.0 */
2087     color = getPixelColor(device, 104, 238);
2088     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2089     color = getPixelColor(device, 318, 238);
2090     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2091
2092     /* 0.0 < z */
2093     color = getPixelColor(device, 321, 238);
2094     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2095
2096     out:
2097     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2098     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2099     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2100     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2101     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2102     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2103 }
2104
2105 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2106 {
2107     D3DSURFACE_DESC desc;
2108     D3DLOCKED_RECT l;
2109     HRESULT hr;
2110     unsigned int x, y;
2111     DWORD *mem;
2112
2113     memset(&desc, 0, sizeof(desc));
2114     memset(&l, 0, sizeof(l));
2115     hr = IDirect3DSurface9_GetDesc(surface, &desc);
2116     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2117     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2118     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2119     if(FAILED(hr)) return;
2120
2121     for(y = 0; y < desc.Height; y++)
2122     {
2123         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2124         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2125         {
2126             mem[x] = color;
2127         }
2128     }
2129     hr = IDirect3DSurface9_UnlockRect(surface);
2130     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2131 }
2132
2133 /* This tests a variety of possible StretchRect() situations */
2134 static void stretchrect_test(IDirect3DDevice9 *device)
2135 {
2136     HRESULT hr;
2137     IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL;
2138     IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL;
2139     IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2140     IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2141     IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2142     IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2143     IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2144     IDirect3DSurface9 *orig_rt = NULL;
2145     DWORD color;
2146
2147     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2148     ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2149     if(!orig_rt) {
2150         goto out;
2151     }
2152
2153     /* Create our temporary surfaces in system memory */
2154     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2155     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2156     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2157     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2158
2159     /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2160     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2161     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2162     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2163     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2164     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2165     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2166
2167     /* Create render target surfaces */
2168     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2169     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2170     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2171     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2172     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2173     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2174
2175     /* Create render target textures */
2176     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2177     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2178     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2179     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2180     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2181     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2182     if (tex_rt32) {
2183         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2184         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2185     }
2186     if (tex_rt64) {
2187         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2188         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2189     }
2190     if (tex_rt_dest64) {
2191         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2192         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2193     }
2194
2195     /* Create regular textures in D3DPOOL_DEFAULT */
2196     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2197     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2198     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2199     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2200     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2201     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2202     if (tex32) {
2203         hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2204         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2205     }
2206     if (tex64) {
2207         hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2208         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2209     }
2210     if (tex_dest64) {
2211         hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2212         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2213     }
2214
2215     /*********************************************************************
2216      * Tests for when the source parameter is an offscreen plain surface *
2217      *********************************************************************/
2218
2219     /* Fill the offscreen 64x64 surface with green */
2220     if (surf_offscreen64)
2221         fill_surface(surf_offscreen64, 0xff00ff00);
2222
2223     /* offscreenplain ==> offscreenplain, same size */
2224     if(surf_offscreen64 && surf_offscreen_dest64) {
2225         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2226         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2227
2228         if (hr == D3D_OK) {
2229             color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2230             ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2231         }
2232     }
2233
2234     /* offscreenplain ==> rendertarget texture, same size */
2235     if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2236         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2237         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2238
2239         /* We can't lock rendertarget textures, so copy to our temp surface first */
2240         if (hr == D3D_OK) {
2241             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2242             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2243         }
2244
2245         if (hr == D3D_OK) {
2246             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2247             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2248         }
2249     }
2250
2251     /* offscreenplain ==> rendertarget surface, same size */
2252     if(surf_offscreen64 && surf_rt_dest64) {
2253         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2254         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2255
2256         if (hr == D3D_OK) {
2257             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2258             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2259         }
2260     }
2261
2262     /* offscreenplain ==> texture, same size (should fail) */
2263     if(surf_offscreen64 && surf_tex_dest64) {
2264         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2265         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2266     }
2267
2268     /* Fill the smaller offscreen surface with red */
2269     fill_surface(surf_offscreen32, 0xffff0000);
2270
2271     /* offscreenplain ==> offscreenplain, scaling (should fail) */
2272     if(surf_offscreen32 && surf_offscreen64) {
2273         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2274         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2275     }
2276
2277     /* offscreenplain ==> rendertarget texture, scaling */
2278     if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2279         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2280         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2281
2282         /* We can't lock rendertarget textures, so copy to our temp surface first */
2283         if (hr == D3D_OK) {
2284             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2285             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2286         }
2287
2288         if (hr == D3D_OK) {
2289             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2290             ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2291         }
2292     }
2293
2294     /* offscreenplain ==> rendertarget surface, scaling */
2295     if(surf_offscreen32 && surf_rt_dest64) {
2296         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2297         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2298
2299         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2300         ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2301     }
2302
2303     /* offscreenplain ==> texture, scaling (should fail) */
2304     if(surf_offscreen32 && surf_tex_dest64) {
2305         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2306         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2307     }
2308
2309     /************************************************************
2310      * Tests for when the source parameter is a regular texture *
2311      ************************************************************/
2312
2313     /* Fill the surface of the regular texture with blue */
2314     if (surf_tex64 && surf_temp64) {
2315         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2316         fill_surface(surf_temp64, 0xff0000ff);
2317         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2318         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2319     }
2320
2321     /* texture ==> offscreenplain, same size */
2322     if(surf_tex64 && surf_offscreen64) {
2323         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2324         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2325     }
2326
2327     /* texture ==> rendertarget texture, same size */
2328     if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2329         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2330         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2331
2332         /* We can't lock rendertarget textures, so copy to our temp surface first */
2333         if (hr == D3D_OK) {
2334             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2335             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2336         }
2337
2338         if (hr == D3D_OK) {
2339             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2340             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2341         }
2342     }
2343
2344     /* texture ==> rendertarget surface, same size */
2345     if(surf_tex64 && surf_rt_dest64) {
2346         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2347         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2348
2349         if (hr == D3D_OK) {
2350             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2351             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2352         }
2353     }
2354
2355     /* texture ==> texture, same size (should fail) */
2356     if(surf_tex64 && surf_tex_dest64) {
2357         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2358         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2359     }
2360
2361     /* Fill the surface of the smaller regular texture with red */
2362     if (surf_tex32 && surf_temp32) {
2363         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2364         fill_surface(surf_temp32, 0xffff0000);
2365         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2366         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2367     }
2368
2369     /* texture ==> offscreenplain, scaling (should fail) */
2370     if(surf_tex32 && surf_offscreen64) {
2371         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2372         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2373     }
2374
2375     /* texture ==> rendertarget texture, scaling */
2376     if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2377         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2378         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2379
2380         /* We can't lock rendertarget textures, so copy to our temp surface first */
2381         if (hr == D3D_OK) {
2382             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2383             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2384         }
2385
2386         if (hr == D3D_OK) {
2387             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2388             ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2389         }
2390     }
2391
2392     /* texture ==> rendertarget surface, scaling */
2393     if(surf_tex32 && surf_rt_dest64) {
2394         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2395         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2396
2397         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2398         ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2399     }
2400
2401     /* texture ==> texture, scaling (should fail) */
2402     if(surf_tex32 && surf_tex_dest64) {
2403         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2404         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2405     }
2406
2407     /*****************************************************************
2408      * Tests for when the source parameter is a rendertarget texture *
2409      *****************************************************************/
2410
2411     /* Fill the surface of the rendertarget texture with white */
2412     if (surf_tex_rt64 && surf_temp64) {
2413         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2414         fill_surface(surf_temp64, 0xffffffff);
2415         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2416         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2417     }
2418
2419     /* rendertarget texture ==> offscreenplain, same size */
2420     if(surf_tex_rt64 && surf_offscreen64) {
2421         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2422         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2423     }
2424
2425     /* rendertarget texture ==> rendertarget texture, same size */
2426     if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2427         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2428         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2429
2430         /* We can't lock rendertarget textures, so copy to our temp surface first */
2431         if (hr == D3D_OK) {
2432             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2433             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2434         }
2435
2436         if (hr == D3D_OK) {
2437             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2438             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2439         }
2440     }
2441
2442     /* rendertarget texture ==> rendertarget surface, same size */
2443     if(surf_tex_rt64 && surf_rt_dest64) {
2444         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2445         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2446
2447         if (hr == D3D_OK) {
2448             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2449             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2450         }
2451     }
2452
2453     /* rendertarget texture ==> texture, same size (should fail) */
2454     if(surf_tex_rt64 && surf_tex_dest64) {
2455         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2456         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2457     }
2458
2459     /* Fill the surface of the smaller rendertarget texture with red */
2460     if (surf_tex_rt32 && surf_temp32) {
2461         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2462         fill_surface(surf_temp32, 0xffff0000);
2463         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2464         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2465     }
2466
2467     /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2468     if(surf_tex_rt32 && surf_offscreen64) {
2469         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2470         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2471     }
2472
2473     /* rendertarget texture ==> rendertarget texture, scaling */
2474     if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2475         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2476         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2477
2478         /* We can't lock rendertarget textures, so copy to our temp surface first */
2479         if (hr == D3D_OK) {
2480             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2481             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2482         }
2483
2484         if (hr == D3D_OK) {
2485             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2486             ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2487         }
2488     }
2489
2490     /* rendertarget texture ==> rendertarget surface, scaling */
2491     if(surf_tex_rt32 && surf_rt_dest64) {
2492         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2493         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2494
2495         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2496         ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2497     }
2498
2499     /* rendertarget texture ==> texture, scaling (should fail) */
2500     if(surf_tex_rt32 && surf_tex_dest64) {
2501         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2502         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2503     }
2504
2505     /*****************************************************************
2506      * Tests for when the source parameter is a rendertarget surface *
2507      *****************************************************************/
2508
2509     /* Fill the surface of the rendertarget surface with black */
2510     if (surf_rt64)
2511         fill_surface(surf_rt64, 0xff000000);
2512
2513     /* rendertarget texture ==> offscreenplain, same size */
2514     if(surf_rt64 && surf_offscreen64) {
2515         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2516         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2517     }
2518
2519     /* rendertarget surface ==> rendertarget texture, same size */
2520     if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2521         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2522         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2523
2524         /* We can't lock rendertarget textures, so copy to our temp surface first */
2525         if (hr == D3D_OK) {
2526             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2527             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2528         }
2529
2530         if (hr == D3D_OK) {
2531             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2532             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2533         }
2534     }
2535
2536     /* rendertarget surface ==> rendertarget surface, same size */
2537     if(surf_rt64 && surf_rt_dest64) {
2538         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2539         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2540
2541         if (hr == D3D_OK) {
2542             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2543             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2544         }
2545     }
2546
2547     /* rendertarget surface ==> texture, same size (should fail) */
2548     if(surf_rt64 && surf_tex_dest64) {
2549         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2550         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2551     }
2552
2553     /* Fill the surface of the smaller rendertarget texture with red */
2554     if (surf_rt32)
2555         fill_surface(surf_rt32, 0xffff0000);
2556
2557     /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2558     if(surf_rt32 && surf_offscreen64) {
2559         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2560         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2561     }
2562
2563     /* rendertarget surface ==> rendertarget texture, scaling */
2564     if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2565         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2566         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2567
2568         /* We can't lock rendertarget textures, so copy to our temp surface first */
2569         if (hr == D3D_OK) {
2570             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2571             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2572         }
2573
2574         if (hr == D3D_OK) {
2575             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2576             ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2577         }
2578     }
2579
2580     /* rendertarget surface ==> rendertarget surface, scaling */
2581     if(surf_rt32 && surf_rt_dest64) {
2582         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2583         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2584
2585         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2586         ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2587     }
2588
2589     /* rendertarget surface ==> texture, scaling (should fail) */
2590     if(surf_rt32 && surf_tex_dest64) {
2591         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2592         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2593     }
2594
2595     /* TODO: Test when source and destination RECT parameters are given... */
2596     /* TODO: Test format conversions */
2597
2598
2599 out:
2600     /* Clean up */
2601     if (surf_rt32)
2602         IDirect3DSurface9_Release(surf_rt32);
2603     if (surf_rt64)
2604         IDirect3DSurface9_Release(surf_rt64);
2605     if (surf_rt_dest64)
2606         IDirect3DSurface9_Release(surf_rt_dest64);
2607     if (surf_temp32)
2608         IDirect3DSurface9_Release(surf_temp32);
2609     if (surf_temp64)
2610         IDirect3DSurface9_Release(surf_temp64);
2611     if (surf_offscreen32)
2612         IDirect3DSurface9_Release(surf_offscreen32);
2613     if (surf_offscreen64)
2614         IDirect3DSurface9_Release(surf_offscreen64);
2615     if (surf_offscreen_dest64)
2616         IDirect3DSurface9_Release(surf_offscreen_dest64);
2617
2618     if (tex_rt32) {
2619         if (surf_tex_rt32)
2620             IDirect3DSurface9_Release(surf_tex_rt32);
2621         IDirect3DTexture9_Release(tex_rt32);
2622     }
2623     if (tex_rt64) {
2624         if (surf_tex_rt64)
2625             IDirect3DSurface9_Release(surf_tex_rt64);
2626         IDirect3DTexture9_Release(tex_rt64);
2627     }
2628     if (tex_rt_dest64) {
2629         if (surf_tex_rt_dest64)
2630             IDirect3DSurface9_Release(surf_tex_rt_dest64);
2631         IDirect3DTexture9_Release(tex_rt_dest64);
2632     }
2633     if (tex32) {
2634         if (surf_tex32)
2635             IDirect3DSurface9_Release(surf_tex32);
2636         IDirect3DTexture9_Release(tex32);
2637     }
2638     if (tex64) {
2639         if (surf_tex64)
2640             IDirect3DSurface9_Release(surf_tex64);
2641         IDirect3DTexture9_Release(tex64);
2642     }
2643     if (tex_dest64) {
2644         if (surf_tex_dest64)
2645             IDirect3DSurface9_Release(surf_tex_dest64);
2646         IDirect3DTexture9_Release(tex_dest64);
2647     }
2648
2649     if (orig_rt) {
2650         hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2651         ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
2652         IDirect3DSurface9_Release(orig_rt);
2653     }
2654 }
2655
2656 static void maxmip_test(IDirect3DDevice9 *device)
2657 {
2658     IDirect3DTexture9 *texture = NULL;
2659     IDirect3DSurface9 *surface = NULL;
2660     HRESULT hr;
2661     DWORD color;
2662     const float quads[] = {
2663         -1.0,   -1.0,   0.0,    0.0,    0.0,
2664         -1.0,    0.0,   0.0,    0.0,    1.0,
2665          0.0,   -1.0,   0.0,    1.0,    0.0,
2666          0.0,    0.0,   0.0,    1.0,    1.0,
2667
2668          0.0,   -1.0,   0.0,    0.0,    0.0,
2669          0.0,    0.0,   0.0,    0.0,    1.0,
2670          1.0,   -1.0,   0.0,    1.0,    0.0,
2671          1.0,    0.0,   0.0,    1.0,    1.0,
2672
2673          0.0,    0.0,   0.0,    0.0,    0.0,
2674          0.0,    1.0,   0.0,    0.0,    1.0,
2675          1.0,    0.0,   0.0,    1.0,    0.0,
2676          1.0,    1.0,   0.0,    1.0,    1.0,
2677
2678         -1.0,    0.0,   0.0,    0.0,    0.0,
2679         -1.0,    1.0,   0.0,    0.0,    1.0,
2680          0.0,    0.0,   0.0,    1.0,    0.0,
2681          0.0,    1.0,   0.0,    1.0,    1.0,
2682     };
2683
2684     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2685     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2686
2687     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2688                                         &texture, NULL);
2689     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2690     if(!texture)
2691     {
2692         skip("Failed to create test texture\n");
2693         return;
2694     }
2695
2696     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
2697     fill_surface(surface, 0xffff0000);
2698     IDirect3DSurface9_Release(surface);
2699     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
2700     fill_surface(surface, 0xff00ff00);
2701     IDirect3DSurface9_Release(surface);
2702     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
2703     fill_surface(surface, 0xff0000ff);
2704     IDirect3DSurface9_Release(surface);
2705
2706     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2707     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2708     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2709     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2710
2711     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2712     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2713
2714     hr = IDirect3DDevice9_BeginScene(device);
2715     if(SUCCEEDED(hr))
2716     {
2717         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2718         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2719         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2720         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2721
2722         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2723         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2724         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2725         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2726
2727         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2728         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2729         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2730         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2731
2732         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2733         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2734         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2735         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2736         hr = IDirect3DDevice9_EndScene(device);
2737     }
2738
2739     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2740     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2741     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
2742     color = getPixelColor(device, 160, 360);
2743     ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
2744     color = getPixelColor(device, 160, 120);
2745     ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
2746     color = getPixelColor(device, 480, 120);
2747     ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
2748     color = getPixelColor(device, 480, 360);
2749     ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
2750
2751     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2752     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2753
2754     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2755     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2756
2757     hr = IDirect3DDevice9_BeginScene(device);
2758     if(SUCCEEDED(hr))
2759     {
2760         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2761         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2762         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2763         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2764
2765         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2766         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2767         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2768         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2769
2770         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2771         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2772         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2773         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2774
2775         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2776         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2777         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2778         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2779         hr = IDirect3DDevice9_EndScene(device);
2780     }
2781
2782     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2783     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2784     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2785     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2786
2787     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2788     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2789     /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2790      * samples from the highest level in the texture(level 2)
2791      */
2792     color = getPixelColor(device, 160, 360);
2793     ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
2794     color = getPixelColor(device, 160, 120);
2795     ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
2796     color = getPixelColor(device, 480, 120);
2797     ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
2798     color = getPixelColor(device, 480, 360);
2799     ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
2800
2801     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2802     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2803     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2804     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2805     IDirect3DTexture9_Release(texture);
2806 }
2807
2808 static void release_buffer_test(IDirect3DDevice9 *device)
2809 {
2810     IDirect3DVertexBuffer9 *vb = NULL;
2811     IDirect3DIndexBuffer9 *ib = NULL;
2812     HRESULT hr;
2813     BYTE *data;
2814     long ref;
2815
2816     static const struct vertex quad[] = {
2817         {-1.0,      -1.0,       0.1,        0xffff0000},
2818         {-1.0,       1.0,       0.1,        0xffff0000},
2819         { 1.0,       1.0,       0.1,        0xffff0000},
2820
2821         {-1.0,      -1.0,       0.1,        0xff00ff00},
2822         {-1.0,       1.0,       0.1,        0xff00ff00},
2823         { 1.0,       1.0,       0.1,        0xff00ff00}
2824     };
2825     short indices[] = {3, 4, 5};
2826
2827     /* Index and vertex buffers should always be creatable */
2828     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
2829                                               D3DPOOL_MANAGED, &vb, NULL);
2830     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
2831     if(!vb) {
2832         skip("Failed to create a vertex buffer\n");
2833         return;
2834     }
2835     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
2836     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
2837     if(!ib) {
2838         skip("Failed to create an index buffer\n");
2839         return;
2840     }
2841
2842     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
2843     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
2844     memcpy(data, quad, sizeof(quad));
2845     hr = IDirect3DVertexBuffer9_Unlock(vb);
2846     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
2847
2848     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
2849     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
2850     memcpy(data, indices, sizeof(indices));
2851     hr = IDirect3DIndexBuffer9_Unlock(ib);
2852     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2853
2854     hr = IDirect3DDevice9_SetIndices(device, ib);
2855     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
2856     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
2857     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
2858     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2859     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2860
2861     /* Now destroy the bound index buffer and draw again */
2862     ref = IDirect3DIndexBuffer9_Release(ib);
2863     ok(ref == 0, "Index Buffer reference count is %08ld\n", ref);
2864
2865     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2866     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2867
2868     hr = IDirect3DDevice9_BeginScene(device);
2869     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2870     if(SUCCEEDED(hr))
2871     {
2872         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
2873          * making assumptions about the indices or vertices
2874          */
2875         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
2876         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
2877         hr = IDirect3DDevice9_EndScene(device);
2878         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2879     }
2880
2881     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2882     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2883
2884     hr = IDirect3DDevice9_SetIndices(device, NULL);
2885     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2886     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2887     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2888
2889     /* Index buffer was already destroyed as part of the test */
2890     IDirect3DVertexBuffer9_Release(vb);
2891 }
2892
2893 static void float_texture_test(IDirect3DDevice9 *device)
2894 {
2895     IDirect3D9 *d3d = NULL;
2896     HRESULT hr;
2897     IDirect3DTexture9 *texture = NULL;
2898     D3DLOCKED_RECT lr;
2899     float *data;
2900     DWORD color;
2901     float quad[] = {
2902         -1.0,      -1.0,       0.1,     0.0,    0.0,
2903         -1.0,       1.0,       0.1,     0.0,    1.0,
2904          1.0,      -1.0,       0.1,     1.0,    0.0,
2905          1.0,       1.0,       0.1,     1.0,    1.0,
2906     };
2907
2908     memset(&lr, 0, sizeof(lr));
2909     IDirect3DDevice9_GetDirect3D(device, &d3d);
2910     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2911                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
2912         skip("D3DFMT_R32F textures not supported\n");
2913         goto out;
2914     }
2915
2916     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
2917                                         D3DPOOL_MANAGED, &texture, NULL);
2918     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2919     if(!texture) {
2920         skip("Failed to create R32F texture\n");
2921         goto out;
2922     }
2923
2924     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2925     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
2926     data = lr.pBits;
2927     *data = 0.0;
2928     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2929     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
2930
2931     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2932     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2933
2934     hr = IDirect3DDevice9_BeginScene(device);
2935     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2936     if(SUCCEEDED(hr))
2937     {
2938         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2939         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2940
2941         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2942         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2943
2944         hr = IDirect3DDevice9_EndScene(device);
2945         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2946     }
2947     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2948     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2949
2950     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2951     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2952
2953     color = getPixelColor(device, 240, 320);
2954     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
2955
2956 out:
2957     if(texture) IDirect3DTexture9_Release(texture);
2958     IDirect3D9_Release(d3d);
2959 }
2960
2961 static void g16r16_texture_test(IDirect3DDevice9 *device)
2962 {
2963     IDirect3D9 *d3d = NULL;
2964     HRESULT hr;
2965     IDirect3DTexture9 *texture = NULL;
2966     D3DLOCKED_RECT lr;
2967     DWORD *data;
2968     DWORD color, red, green, blue;
2969     float quad[] = {
2970        -1.0,      -1.0,       0.1,     0.0,    0.0,
2971        -1.0,       1.0,       0.1,     0.0,    1.0,
2972         1.0,      -1.0,       0.1,     1.0,    0.0,
2973         1.0,       1.0,       0.1,     1.0,    1.0,
2974     };
2975
2976     memset(&lr, 0, sizeof(lr));
2977     IDirect3DDevice9_GetDirect3D(device, &d3d);
2978     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2979        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
2980            skip("D3DFMT_G16R16 textures not supported\n");
2981            goto out;
2982     }
2983
2984     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
2985                                         D3DPOOL_MANAGED, &texture, NULL);
2986     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2987     if(!texture) {
2988         skip("Failed to create D3DFMT_G16R16 texture\n");
2989         goto out;
2990     }
2991
2992     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2993     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
2994     data = lr.pBits;
2995     *data = 0x0f00f000;
2996     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2997     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
2998
2999     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3000     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3001
3002     hr = IDirect3DDevice9_BeginScene(device);
3003     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3004     if(SUCCEEDED(hr))
3005     {
3006         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3007         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3008
3009         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3010         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3011
3012         hr = IDirect3DDevice9_EndScene(device);
3013         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3014     }
3015     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3016     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3017
3018     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3019     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3020
3021     color = getPixelColor(device, 240, 320);
3022     red   = (color & 0x00ff0000) >> 16;
3023     green = (color & 0x0000ff00) >>  8;
3024     blue  = (color & 0x000000ff) >>  0;
3025     ok(blue == 0xff && red >= 0xef && red <= 0xf1 && green >= 0x0e && green <= 0x10,
3026        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00F00FFF\n", color);
3027
3028 out:
3029     if(texture) IDirect3DTexture9_Release(texture);
3030     IDirect3D9_Release(d3d);
3031 }
3032
3033 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3034 {
3035     HRESULT hr;
3036     IDirect3D9 *d3d;
3037     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3038     D3DCAPS9 caps;
3039     IDirect3DTexture9 *texture = NULL;
3040     IDirect3DVolumeTexture9 *volume = NULL;
3041     unsigned int x, y, z;
3042     D3DLOCKED_RECT lr;
3043     D3DLOCKED_BOX lb;
3044     DWORD color;
3045     UINT w, h;
3046     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3047     float identity[16] = {1.0, 0.0, 0.0, 0.0,
3048                            0.0, 1.0, 0.0, 0.0,
3049                            0.0, 0.0, 1.0, 0.0,
3050                            0.0, 0.0, 0.0, 1.0};
3051     static const D3DVERTEXELEMENT9 decl_elements[] = {
3052         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3053         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3054         D3DDECL_END()
3055     };
3056     static const D3DVERTEXELEMENT9 decl_elements2[] = {
3057         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3058         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3059         D3DDECL_END()
3060     };
3061     static const D3DVERTEXELEMENT9 decl_elements3[] = {
3062         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3063         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3064         D3DDECL_END()
3065     };
3066     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3067                                                  0x00, 0xff, 0x00, 0x00,
3068                                                  0x00, 0x00, 0x00, 0x00,
3069                                                  0x00, 0x00, 0x00, 0x00};
3070
3071     memset(&lr, 0, sizeof(lr));
3072     memset(&lb, 0, sizeof(lb));
3073     IDirect3DDevice9_GetDirect3D(device, &d3d);
3074     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3075                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3076         fmt = D3DFMT_A16B16G16R16;
3077     }
3078     IDirect3D9_Release(d3d);
3079
3080     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3081     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3082     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3083     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3084     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3085     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3086     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3087     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3088     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3089     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3090     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3091     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3092     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3093     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3094     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3095     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3096     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3097     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3098     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3099     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3100     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3101     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3102     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3103     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3104
3105     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3106     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3107     w = min(1024, caps.MaxTextureWidth);
3108     h = min(1024, caps.MaxTextureHeight);
3109     hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3110                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3111     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3112     if(!texture) {
3113         skip("Failed to create the test texture\n");
3114         return;
3115     }
3116
3117     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3118      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3119      * 1.0 in red and green for the x and y coords
3120      */
3121     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3122     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3123     for(y = 0; y < h; y++) {
3124         for(x = 0; x < w; x++) {
3125             double r_f = (double) y / (double) h;
3126             double g_f = (double) x / (double) w;
3127             if(fmt == D3DFMT_A16B16G16R16) {
3128                 unsigned short r, g;
3129                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3130                 r = (unsigned short) (r_f * 65536.0);
3131                 g = (unsigned short) (g_f * 65536.0);
3132                 dst[0] = r;
3133                 dst[1] = g;
3134                 dst[2] = 0;
3135                 dst[3] = 65535;
3136             } else {
3137                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3138                 unsigned char r = (unsigned char) (r_f * 255.0);
3139                 unsigned char g = (unsigned char) (g_f * 255.0);
3140                 dst[0] = 0;
3141                 dst[1] = g;
3142                 dst[2] = r;
3143                 dst[3] = 255;
3144             }
3145         }
3146     }
3147     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3148     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3149     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3150     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3151
3152     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3153     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3154     hr = IDirect3DDevice9_BeginScene(device);
3155     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3156     if(SUCCEEDED(hr))
3157     {
3158         float quad1[] = {
3159             -1.0,      -1.0,       0.1,     1.0,    1.0,
3160             -1.0,       0.0,       0.1,     1.0,    1.0,
3161              0.0,      -1.0,       0.1,     1.0,    1.0,
3162              0.0,       0.0,       0.1,     1.0,    1.0,
3163         };
3164         float quad2[] = {
3165             -1.0,       0.0,       0.1,     1.0,    1.0,
3166             -1.0,       1.0,       0.1,     1.0,    1.0,
3167              0.0,       0.0,       0.1,     1.0,    1.0,
3168              0.0,       1.0,       0.1,     1.0,    1.0,
3169         };
3170         float quad3[] = {
3171              0.0,       0.0,       0.1,     0.5,    0.5,
3172              0.0,       1.0,       0.1,     0.5,    0.5,
3173              1.0,       0.0,       0.1,     0.5,    0.5,
3174              1.0,       1.0,       0.1,     0.5,    0.5,
3175         };
3176         float quad4[] = {
3177              320,       480,       0.1,     1.0,    0.0,    1.0,
3178              320,       240,       0.1,     1.0,    0.0,    1.0,
3179              640,       480,       0.1,     1.0,    0.0,    1.0,
3180              640,       240,       0.1,     1.0,    0.0,    1.0,
3181         };
3182         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3183                           0.0, 0.0, 0.0, 0.0,
3184                           0.0, 0.0, 0.0, 0.0,
3185                           0.0, 0.0, 0.0, 0.0};
3186
3187         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3188         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3189         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3190         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3191         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3192
3193         /* What happens with transforms enabled? */
3194         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3195         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3196         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3197         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3198
3199         /* What happens if 4 coords are used, but only 2 given ?*/
3200         mat[8] = 1.0;
3201         mat[13] = 1.0;
3202         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3203         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3204         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3205         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3206         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3207         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3208
3209         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3210          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3211          * due to the coords in the vertices. (turns out red, indeed)
3212          */
3213         memset(mat, 0, sizeof(mat));
3214         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3215         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3216         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3217         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3218         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3219         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3220         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3221         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3222
3223         hr = IDirect3DDevice9_EndScene(device);
3224         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3225     }
3226     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3227     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3228     color = getPixelColor(device, 160, 360);
3229     ok(color == 0x00FFFF00 || color == 0x00FEFE00, "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3230     color = getPixelColor(device, 160, 120);
3231     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3232     color = getPixelColor(device, 480, 120);
3233     ok(color == 0x0000FF00 || color == 0x0000FE00, "quad 3 has color %08x, expected 0x0000FF00\n", color);
3234     color = getPixelColor(device, 480, 360);
3235     ok(color == 0x00FF0000 || 0x00FE0000, "quad 4 has color %08x, expected 0x00FF0000\n", color);
3236
3237     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3238     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3239
3240     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3241     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3242     hr = IDirect3DDevice9_BeginScene(device);
3243     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3244     if(SUCCEEDED(hr))
3245     {
3246         float quad1[] = {
3247             -1.0,      -1.0,       0.1,     0.8,    0.2,
3248             -1.0,       0.0,       0.1,     0.8,    0.2,
3249              0.0,      -1.0,       0.1,     0.8,    0.2,
3250              0.0,       0.0,       0.1,     0.8,    0.2,
3251         };
3252         float quad2[] = {
3253             -1.0,       0.0,       0.1,     0.5,    1.0,
3254             -1.0,       1.0,       0.1,     0.5,    1.0,
3255              0.0,       0.0,       0.1,     0.5,    1.0,
3256              0.0,       1.0,       0.1,     0.5,    1.0,
3257         };
3258         float quad3[] = {
3259              0.0,       0.0,       0.1,     0.5,    1.0,
3260              0.0,       1.0,       0.1,     0.5,    1.0,
3261              1.0,       0.0,       0.1,     0.5,    1.0,
3262              1.0,       1.0,       0.1,     0.5,    1.0,
3263         };
3264         float quad4[] = {
3265              0.0,      -1.0,       0.1,     0.8,    0.2,
3266              0.0,       0.0,       0.1,     0.8,    0.2,
3267              1.0,      -1.0,       0.1,     0.8,    0.2,
3268              1.0,       0.0,       0.1,     0.8,    0.2,
3269         };
3270         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3271                           0.0, 0.0, 0.0, 0.0,
3272                           0.0, 1.0, 0.0, 0.0,
3273                           0.0, 0.0, 0.0, 0.0};
3274
3275         /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3276          */
3277         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3278         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3279         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3280         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3281
3282         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3283         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3284
3285         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3286          * it behaves like COUNT2 because normal textures require 2 coords
3287          */
3288         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3289         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3290         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3291         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3292
3293         /* Just to be sure, the same as quad2 above */
3294         memset(mat, 0, sizeof(mat));
3295         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3296         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3297         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3298         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3299         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3300         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3301
3302         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3303          * used? And what happens to the first?
3304          */
3305         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3306         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3307         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3308         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3309
3310         hr = IDirect3DDevice9_EndScene(device);
3311         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3312     }
3313     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3314     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3315     color = getPixelColor(device, 160, 360);
3316     ok(color == 0x00FF0000 || color == 0x00FE0000, "quad 1 has color %08x, expected 0x00FF0000\n", color);
3317     color = getPixelColor(device, 160, 120);
3318     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3319     color = getPixelColor(device, 480, 120);
3320     ok(color == 0x00ff8000 || color == 0x00fe7f00 || color == 0x00000000,
3321        "quad 3 has color %08x, expected 0x00ff8000\n", color);
3322     color = getPixelColor(device, 480, 360);
3323     ok(color == 0x0033cc00 || color == 0x0032cb00 || color == 0x00FF0000 || color == 0x00FE0000,
3324        "quad 4 has color %08x, expected 0x0033cc00\n", color);
3325
3326     IDirect3DTexture9_Release(texture);
3327
3328     /* Test projected textures, without any fancy matrices */
3329     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3330     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3331     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3332     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3333     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3334     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3335     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3336     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3337
3338     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3339     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3340     for(x = 0; x < 4; x++) {
3341         memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3342     }
3343     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3344     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3345     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3346     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3347
3348     hr = IDirect3DDevice9_BeginScene(device);
3349     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3350     if(SUCCEEDED(hr))
3351     {
3352         const float proj_quads[] = {
3353            -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3354             1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3355            -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3356             1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3357            -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3358             1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3359            -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3360             1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3361         };
3362
3363         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3364         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3365         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3366         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3367
3368         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3369         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3370         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3371         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3372
3373         hr = IDirect3DDevice9_EndScene(device);
3374         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3375     }
3376
3377     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3378     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3379     IDirect3DTexture9_Release(texture);
3380
3381     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3382     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3383     color = getPixelColor(device, 158, 118);
3384     ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3385     color = getPixelColor(device, 162, 118);
3386     ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3387     color = getPixelColor(device, 158, 122);
3388     ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3389     color = getPixelColor(device, 162, 122);
3390     ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3391
3392     color = getPixelColor(device, 158, 178);
3393     ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3394     color = getPixelColor(device, 162, 178);
3395     ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3396     color = getPixelColor(device, 158, 182);
3397     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3398     color = getPixelColor(device, 162, 182);
3399     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3400
3401     color = getPixelColor(device, 318, 118);
3402     ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3403     color = getPixelColor(device, 322, 118);
3404     ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3405     color = getPixelColor(device, 318, 122);
3406     ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3407     color = getPixelColor(device, 322, 122);
3408     ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3409
3410     color = getPixelColor(device, 318, 178);
3411     ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3412     color = getPixelColor(device, 322, 178);
3413     ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3414     color = getPixelColor(device, 318, 182);
3415     ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3416     color = getPixelColor(device, 322, 182);
3417     ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3418
3419     color = getPixelColor(device, 238, 298);
3420     ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3421     color = getPixelColor(device, 242, 298);
3422     ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3423     color = getPixelColor(device, 238, 302);
3424     ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3425     color = getPixelColor(device, 242, 302);
3426     ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3427
3428     color = getPixelColor(device, 238, 388);
3429     ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3430     color = getPixelColor(device, 242, 388);
3431     ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3432     color = getPixelColor(device, 238, 392);
3433     ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3434     color = getPixelColor(device, 242, 392);
3435     ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3436
3437     color = getPixelColor(device, 478, 298);
3438     ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3439     color = getPixelColor(device, 482, 298);
3440     ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3441     color = getPixelColor(device, 478, 302);
3442     ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3443     color = getPixelColor(device, 482, 302);
3444     ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3445
3446     color = getPixelColor(device, 478, 388);
3447     ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3448     color = getPixelColor(device, 482, 388);
3449     ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3450     color = getPixelColor(device, 478, 392);
3451     ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3452     color = getPixelColor(device, 482, 392);
3453     ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3454
3455     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3456     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3457     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3458      * Thus watch out if sampling from texels between 0 and 1.
3459      */
3460     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3461     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3462        "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3463     if(!volume) {
3464         skip("Failed to create a volume texture\n");
3465         goto out;
3466     }
3467
3468     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3469     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3470     for(z = 0; z < 32; z++) {
3471         for(y = 0; y < 32; y++) {
3472             for(x = 0; x < 32; x++) {
3473                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3474                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3475                 float r_f = (float) x / 31.0;
3476                 float g_f = (float) y / 31.0;
3477                 float b_f = (float) z / 31.0;
3478
3479                 if(fmt == D3DFMT_A16B16G16R16) {
3480                     unsigned short *mem_s = mem;
3481                     mem_s[0]  = r_f * 65535.0;
3482                     mem_s[1]  = g_f * 65535.0;
3483                     mem_s[2]  = b_f * 65535.0;
3484                     mem_s[3]  = 65535;
3485                 } else {
3486                     unsigned char *mem_c = mem;
3487                     mem_c[0]  = b_f * 255.0;
3488                     mem_c[1]  = g_f * 255.0;
3489                     mem_c[2]  = r_f * 255.0;
3490                     mem_c[3]  = 255;
3491                 }
3492             }
3493         }
3494     }
3495     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3496     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3497
3498     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3499     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3500
3501     hr = IDirect3DDevice9_BeginScene(device);
3502     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3503     if(SUCCEEDED(hr))
3504     {
3505         float quad1[] = {
3506             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3507             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3508              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3509              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3510         };
3511         float quad2[] = {
3512             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3513             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
3514              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3515              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
3516         };
3517         float quad3[] = {
3518              0.0,       0.0,       0.1,     0.0,    0.0,
3519              0.0,       1.0,       0.1,     0.0,    0.0,
3520              1.0,       0.0,       0.1,     0.0,    0.0,
3521              1.0,       1.0,       0.1,     0.0,    0.0
3522         };
3523         float quad4[] = {
3524              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3525              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3526              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3527              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
3528         };
3529         float mat[16] = {1.0, 0.0, 0.0, 0.0,
3530                          0.0, 0.0, 1.0, 0.0,
3531                          0.0, 1.0, 0.0, 0.0,
3532                          0.0, 0.0, 0.0, 1.0};
3533         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3534         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3535
3536         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3537          * values
3538          */
3539         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3540         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3541         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3542         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3543         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3544         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3545
3546         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3547          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3548          * otherwise the w will be missing(blue).
3549          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3550          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3551          */
3552         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3553         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3554         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3555         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3556
3557         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
3558         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3559         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3560         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3561         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3562         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3563         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3564         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3565         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3566
3567         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3568          * disable. ATI extends it up to the amount of values needed for the volume texture
3569          */
3570         memset(mat, 0, sizeof(mat));
3571         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3572         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3573         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3574         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3575         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3576         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3577         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3578         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3579
3580         hr = IDirect3DDevice9_EndScene(device);
3581         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3582     }
3583     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3584     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3585
3586     color = getPixelColor(device, 160, 360);
3587     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3588     color = getPixelColor(device, 160, 120);
3589     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3590        "quad 2 has color %08x, expected 0x00ffff00\n", color);
3591     color = getPixelColor(device, 480, 120);
3592     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3593     color = getPixelColor(device, 480, 360);
3594     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3595
3596     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3597     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3598     hr = IDirect3DDevice9_BeginScene(device);
3599     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3600     if(SUCCEEDED(hr))
3601     {
3602         float quad1[] = {
3603             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3604             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3605              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3606              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3607         };
3608         float quad2[] = {
3609             -1.0,       0.0,       0.1,
3610             -1.0,       1.0,       0.1,
3611              0.0,       0.0,       0.1,
3612              0.0,       1.0,       0.1,
3613         };
3614         float quad3[] = {
3615              0.0,       0.0,       0.1,     1.0,
3616              0.0,       1.0,       0.1,     1.0,
3617              1.0,       0.0,       0.1,     1.0,
3618              1.0,       1.0,       0.1,     1.0
3619         };
3620         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
3621                            0.0, 0.0, 0.0, 0.0,
3622                            0.0, 0.0, 0.0, 0.0,
3623                            0.0, 1.0, 0.0, 0.0};
3624         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
3625                            1.0, 0.0, 0.0, 0.0,
3626                            0.0, 1.0, 0.0, 0.0,
3627                            0.0, 0.0, 1.0, 0.0};
3628         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3629         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3630
3631         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
3632          */
3633         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3634         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3635         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3636         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3637         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3638         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3639
3640         /* None passed */
3641         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3642         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3643         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3644         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3645         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3646         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3647
3648         /* 4 used, 1 passed */
3649         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
3650         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3651         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
3652         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3653         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
3654         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3655
3656         hr = IDirect3DDevice9_EndScene(device);
3657         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3658     }
3659     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3660     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3661     color = getPixelColor(device, 160, 360);
3662     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
3663     color = getPixelColor(device, 160, 120);
3664     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
3665     color = getPixelColor(device, 480, 120);
3666     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
3667     /* Quad4: unused */
3668
3669     IDirect3DVolumeTexture9_Release(volume);
3670
3671     out:
3672     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3673     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3674     IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
3675     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3676     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3677     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3678     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3679     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3680     IDirect3DVertexDeclaration9_Release(decl);
3681     IDirect3DVertexDeclaration9_Release(decl2);
3682     IDirect3DVertexDeclaration9_Release(decl3);
3683 }
3684
3685 static void texdepth_test(IDirect3DDevice9 *device)
3686 {
3687     IDirect3DPixelShader9 *shader;
3688     HRESULT hr;
3689     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
3690     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
3691     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
3692     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
3693     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
3694     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
3695     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
3696     DWORD shader_code[] = {
3697         0xffff0104,                                                                 /* ps_1_4               */
3698         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
3699         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
3700         0x0000fffd,                                                                 /* phase                */
3701         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
3702         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
3703         0x0000ffff                                                                  /* end                  */
3704     };
3705     DWORD color;
3706     float vertex[] = {
3707        -1.0,   -1.0,    0.0,
3708         1.0,   -1.0,    1.0,
3709        -1.0,    1.0,    0.0,
3710         1.0,    1.0,    1.0
3711     };
3712
3713     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3714     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3715
3716     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
3717     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3718     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3719     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3720     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3721     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3722     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3723     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3724     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3725
3726     /* Fill the depth buffer with a gradient */
3727     hr = IDirect3DDevice9_BeginScene(device);
3728     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3729     if(SUCCEEDED(hr))
3730     {
3731         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3732         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3733         hr = IDirect3DDevice9_EndScene(device);
3734         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3735     }
3736
3737     /* Now perform the actual tests. Same geometry, but with the shader */
3738     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3739     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3740     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3741     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3742     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3743     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3744
3745     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
3746     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3747     hr = IDirect3DDevice9_BeginScene(device);
3748     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3749     if(SUCCEEDED(hr))
3750     {
3751         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3752         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3753
3754         hr = IDirect3DDevice9_EndScene(device);
3755         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3756     }
3757
3758     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3759     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3760     color = getPixelColor(device, 158, 240);
3761     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3762     color = getPixelColor(device, 162, 240);
3763     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
3764
3765     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3766
3767     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
3768     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3769     hr = IDirect3DDevice9_BeginScene(device);
3770     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3771     if(SUCCEEDED(hr))
3772     {
3773         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3774         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3775
3776         hr = IDirect3DDevice9_EndScene(device);
3777         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3778     }
3779
3780     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3781     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3782     color = getPixelColor(device, 318, 240);
3783     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3784     color = getPixelColor(device, 322, 240);
3785     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3786
3787     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3788
3789     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
3790     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3791     hr = IDirect3DDevice9_BeginScene(device);
3792     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3793     if(SUCCEEDED(hr))
3794     {
3795         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3796         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3797
3798         hr = IDirect3DDevice9_EndScene(device);
3799         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3800     }
3801     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3802     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3803
3804     color = getPixelColor(device, 1, 240);
3805     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
3806
3807     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3808
3809     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
3810     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3811     hr = IDirect3DDevice9_BeginScene(device);
3812     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3813     if(SUCCEEDED(hr))
3814     {
3815         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3816         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3817
3818         hr = IDirect3DDevice9_EndScene(device);
3819         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3820     }
3821     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3822     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3823     color = getPixelColor(device, 318, 240);
3824     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3825     color = getPixelColor(device, 322, 240);
3826     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
3827
3828     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3829
3830     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
3831     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3832     hr = IDirect3DDevice9_BeginScene(device);
3833     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3834     if(SUCCEEDED(hr))
3835     {
3836         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3837         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3838
3839         hr = IDirect3DDevice9_EndScene(device);
3840         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3841     }
3842     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3843     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3844
3845     color = getPixelColor(device, 1, 240);
3846     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3847
3848     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3849
3850     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
3851     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3852     hr = IDirect3DDevice9_BeginScene(device);
3853     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3854     if(SUCCEEDED(hr))
3855     {
3856         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3857         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3858
3859         hr = IDirect3DDevice9_EndScene(device);
3860         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3861     }
3862     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3863     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3864
3865     color = getPixelColor(device, 638, 240);
3866     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3867
3868     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3869
3870     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
3871     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3872     hr = IDirect3DDevice9_BeginScene(device);
3873     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3874     if(SUCCEEDED(hr))
3875     {
3876         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3877         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3878
3879         hr = IDirect3DDevice9_EndScene(device);
3880         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3881     }
3882     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3883     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3884
3885     color = getPixelColor(device, 638, 240);
3886     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3887
3888     /* Cleanup */
3889     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3890     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3891     IDirect3DPixelShader9_Release(shader);
3892
3893     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
3894     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3895     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3896     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3897 }
3898
3899 static void texkill_test(IDirect3DDevice9 *device)
3900 {
3901     IDirect3DPixelShader9 *shader;
3902     HRESULT hr;
3903     DWORD color;
3904
3905     const float vertex[] = {
3906     /*                          bottom  top    right    left */
3907         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
3908          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
3909         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
3910          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
3911     };
3912
3913     DWORD shader_code_11[] = {
3914     0xffff0101,                                                             /* ps_1_1                     */
3915     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
3916     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
3917     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
3918     0x0000ffff                                                              /* end                        */
3919     };
3920     DWORD shader_code_20[] = {
3921     0xffff0200,                                                             /* ps_2_0                     */
3922     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
3923     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
3924     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
3925     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
3926     0x0000ffff                                                              /* end                        */
3927     };
3928
3929     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3930     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3931     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
3932     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3933
3934     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3935     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
3936     hr = IDirect3DDevice9_BeginScene(device);
3937     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3938     if(SUCCEEDED(hr))
3939     {
3940         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
3941         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
3942         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3943         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3944         hr = IDirect3DDevice9_EndScene(device);
3945         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3946     }
3947     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3948     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3949     color = getPixelColor(device, 63, 46);
3950     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
3951     color = getPixelColor(device, 66, 46);
3952     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
3953     color = getPixelColor(device, 63, 49);
3954     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
3955     color = getPixelColor(device, 66, 49);
3956     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
3957
3958     color = getPixelColor(device, 578, 46);
3959     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3960     color = getPixelColor(device, 575, 46);
3961     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3962     color = getPixelColor(device, 578, 49);
3963     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
3964     color = getPixelColor(device, 575, 49);
3965     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3966
3967     color = getPixelColor(device, 63, 430);
3968     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3969     color = getPixelColor(device, 63, 433);
3970     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3971     color = getPixelColor(device, 66, 433);
3972     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3973     color = getPixelColor(device, 66, 430);
3974     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3975
3976     color = getPixelColor(device, 578, 430);
3977     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3978     color = getPixelColor(device, 578, 433);
3979     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3980     color = getPixelColor(device, 575, 433);
3981     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3982     color = getPixelColor(device, 575, 430);
3983     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3984
3985     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3986     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
3987     IDirect3DPixelShader9_Release(shader);
3988
3989     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3990     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3991     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
3992     if(FAILED(hr)) {
3993         skip("Failed to create 2.0 test shader, most likely not supported\n");
3994         return;
3995     }
3996
3997     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3998     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
3999     hr = IDirect3DDevice9_BeginScene(device);
4000     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4001     if(SUCCEEDED(hr))
4002     {
4003         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4004         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4005         hr = IDirect3DDevice9_EndScene(device);
4006         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4007     }
4008     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4009
4010     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4011     color = getPixelColor(device, 63, 46);
4012     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4013     color = getPixelColor(device, 66, 46);
4014     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4015     color = getPixelColor(device, 63, 49);
4016     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4017     color = getPixelColor(device, 66, 49);
4018     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4019
4020     color = getPixelColor(device, 578, 46);
4021     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4022     color = getPixelColor(device, 575, 46);
4023     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4024     color = getPixelColor(device, 578, 49);
4025     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4026     color = getPixelColor(device, 575, 49);
4027     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4028
4029     color = getPixelColor(device, 63, 430);
4030     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4031     color = getPixelColor(device, 63, 433);
4032     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4033     color = getPixelColor(device, 66, 433);
4034     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4035     color = getPixelColor(device, 66, 430);
4036     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4037
4038     color = getPixelColor(device, 578, 430);
4039     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4040     color = getPixelColor(device, 578, 433);
4041     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4042     color = getPixelColor(device, 575, 433);
4043     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4044     color = getPixelColor(device, 575, 430);
4045     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4046
4047     /* Cleanup */
4048     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4049     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4050     IDirect3DPixelShader9_Release(shader);
4051 }
4052
4053 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4054 {
4055     IDirect3D9 *d3d9;
4056     HRESULT hr;
4057     IDirect3DTexture9 *texture;
4058     IDirect3DPixelShader9 *shader;
4059     IDirect3DPixelShader9 *shader2;
4060     D3DLOCKED_RECT lr;
4061     DWORD color;
4062     DWORD shader_code[] = {
4063         0xffff0101,                             /* ps_1_1       */
4064         0x00000042, 0xb00f0000,                 /* tex t0       */
4065         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
4066         0x0000ffff                              /* end          */
4067     };
4068     DWORD shader_code2[] = {
4069         0xffff0101,                             /* ps_1_1       */
4070         0x00000042, 0xb00f0000,                 /* tex t0       */
4071         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
4072         0x0000ffff                              /* end          */
4073     };
4074
4075     float quad[] = {
4076        -1.0,   -1.0,   0.1,     0.5,    0.5,
4077         1.0,   -1.0,   0.1,     0.5,    0.5,
4078        -1.0,    1.0,   0.1,     0.5,    0.5,
4079         1.0,    1.0,   0.1,     0.5,    0.5,
4080     };
4081
4082     memset(&lr, 0, sizeof(lr));
4083     IDirect3DDevice9_GetDirect3D(device, &d3d9);
4084     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4085                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4086     IDirect3D9_Release(d3d9);
4087     if(FAILED(hr)) {
4088         skip("No D3DFMT_X8L8V8U8 support\n");
4089     };
4090
4091     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4092     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4093
4094     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4095     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4096     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4097     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4098     *((DWORD *) lr.pBits) = 0x11ca3141;
4099     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4100     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4101
4102     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4103     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4104     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4105     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4106
4107     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4108     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4109     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4110     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4111     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4112     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4113
4114     hr = IDirect3DDevice9_BeginScene(device);
4115     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4116     if(SUCCEEDED(hr))
4117     {
4118         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4119         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4120
4121         hr = IDirect3DDevice9_EndScene(device);
4122         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4123     }
4124     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4125     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4126     color = getPixelColor(device, 578, 430);
4127     ok(color == 0x008262ca || color == 0x008363ca || color == 0x008362ca,
4128        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4129
4130     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4131     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4132     hr = IDirect3DDevice9_BeginScene(device);
4133     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4134     if(SUCCEEDED(hr))
4135     {
4136         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4137         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4138
4139         hr = IDirect3DDevice9_EndScene(device);
4140         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4141     }
4142     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4143     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4144     color = getPixelColor(device, 578, 430);
4145     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4146
4147     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4148     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4149     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4150     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4151     IDirect3DPixelShader9_Release(shader);
4152     IDirect3DPixelShader9_Release(shader2);
4153     IDirect3DTexture9_Release(texture);
4154 }
4155
4156 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4157 {
4158     HRESULT hr;
4159     IDirect3D9 *d3d;
4160     IDirect3DTexture9 *texture = NULL;
4161     IDirect3DSurface9 *surface;
4162     DWORD color;
4163     const RECT r1 = {256, 256, 512, 512};
4164     const RECT r2 = {512, 256, 768, 512};
4165     const RECT r3 = {256, 512, 512, 768};
4166     const RECT r4 = {512, 512, 768, 768};
4167     unsigned int x, y;
4168     D3DLOCKED_RECT lr;
4169     memset(&lr, 0, sizeof(lr));
4170
4171     IDirect3DDevice9_GetDirect3D(device, &d3d);
4172     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4173        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4174         skip("No autogenmipmap support\n");
4175         IDirect3D9_Release(d3d);
4176         return;
4177     }
4178     IDirect3D9_Release(d3d);
4179
4180     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4181     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4182
4183     /* Make the mipmap big, so that a smaller mipmap is used
4184      */
4185     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4186                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4187     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4188
4189     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4190     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4191     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4192     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4193     for(y = 0; y < 1024; y++) {
4194         for(x = 0; x < 1024; x++) {
4195             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4196             POINT pt;
4197
4198             pt.x = x;
4199             pt.y = y;
4200             if(PtInRect(&r1, pt)) {
4201                 *dst = 0xffff0000;
4202             } else if(PtInRect(&r2, pt)) {
4203                 *dst = 0xff00ff00;
4204             } else if(PtInRect(&r3, pt)) {
4205                 *dst = 0xff0000ff;
4206             } else if(PtInRect(&r4, pt)) {
4207                 *dst = 0xff000000;
4208             } else {
4209                 *dst = 0xffffffff;
4210             }
4211         }
4212     }
4213     hr = IDirect3DSurface9_UnlockRect(surface);
4214     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4215     IDirect3DSurface9_Release(surface);
4216
4217     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4218     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4219     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4220     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4221
4222     hr = IDirect3DDevice9_BeginScene(device);
4223     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4224     if(SUCCEEDED(hr)) {
4225         const float quad[] =  {
4226            -0.5,   -0.5,    0.1,    0.0,    0.0,
4227            -0.5,    0.5,    0.1,    0.0,    1.0,
4228             0.5,   -0.5,    0.1,    1.0,    0.0,
4229             0.5,    0.5,    0.1,    1.0,    1.0
4230         };
4231
4232         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4233         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4234         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4235         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4236         hr = IDirect3DDevice9_EndScene(device);
4237         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4238     }
4239     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4240     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4241     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4242     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4243     IDirect3DTexture9_Release(texture);
4244
4245     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4246     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4247     color = getPixelColor(device, 200, 200);
4248     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4249     color = getPixelColor(device, 280, 200);
4250     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4251     color = getPixelColor(device, 360, 200);
4252     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4253     color = getPixelColor(device, 440, 200);
4254     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4255     color = getPixelColor(device, 200, 270);
4256     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4257     color = getPixelColor(device, 280, 270);
4258     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4259     color = getPixelColor(device, 360, 270);
4260     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4261     color = getPixelColor(device, 440, 270);
4262     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4263 }
4264
4265 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4266 {
4267     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4268     IDirect3DVertexDeclaration9 *decl;
4269     HRESULT hr;
4270     DWORD color;
4271     DWORD shader_code_11[] =  {
4272         0xfffe0101,                                         /* vs_1_1           */
4273         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4274         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4275         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4276         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4277         0x0000ffff                                          /* end              */
4278     };
4279     DWORD shader_code_11_2[] =  {
4280         0xfffe0101,                                         /* vs_1_1           */
4281         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4282         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4283         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4284         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4285         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4286         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4287         0x0000ffff                                          /* end              */
4288     };
4289     DWORD shader_code_20[] =  {
4290         0xfffe0200,                                         /* vs_2_0           */
4291         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4292         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4293         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4294         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4295         0x0000ffff                                          /* end              */
4296     };
4297     DWORD shader_code_20_2[] =  {
4298         0xfffe0200,                                         /* vs_2_0           */
4299         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4300         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4301         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4302         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4303         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4304         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4305         0x0000ffff                                          /* end              */
4306     };
4307     static const D3DVERTEXELEMENT9 decl_elements[] = {
4308         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4309         D3DDECL_END()
4310     };
4311     float quad1[] = {
4312         -1.0,   -1.0,   0.1,
4313          0.0,   -1.0,   0.1,
4314         -1.0,    0.0,   0.1,
4315          0.0,    0.0,   0.1
4316     };
4317     float quad2[] = {
4318          0.0,   -1.0,   0.1,
4319          1.0,   -1.0,   0.1,
4320          0.0,    0.0,   0.1,
4321          1.0,    0.0,   0.1
4322     };
4323     float quad3[] = {
4324          0.0,    0.0,   0.1,
4325          1.0,    0.0,   0.1,
4326          0.0,    1.0,   0.1,
4327          1.0,    1.0,   0.1
4328     };
4329     float quad4[] = {
4330         -1.0,    0.0,   0.1,
4331          0.0,    0.0,   0.1,
4332         -1.0,    1.0,   0.1,
4333          0.0,    1.0,   0.1
4334     };
4335     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4336     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4337
4338     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4339     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4340
4341     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4342     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4343     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4344     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4345     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4346     if(FAILED(hr)) shader_20 = NULL;
4347     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4348     if(FAILED(hr)) shader_20_2 = NULL;
4349     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4350     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4351
4352     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4353     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4354     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4355     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4356     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4357     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4358
4359     hr = IDirect3DDevice9_BeginScene(device);
4360     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4361     if(SUCCEEDED(hr))
4362     {
4363         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4364         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4365         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4366         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4367
4368         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4369         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4370         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4371         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4372
4373         if(shader_20) {
4374             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4375             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4376             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4377             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4378         }
4379
4380         if(shader_20_2) {
4381             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4382             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4383             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4384             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4385         }
4386
4387         hr = IDirect3DDevice9_EndScene(device);
4388         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4389     }
4390     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4391     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4392
4393     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4394     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4395     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4396     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4397
4398     color = getPixelColor(device, 160, 360);
4399     ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4400        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4401     color = getPixelColor(device, 480, 360);
4402     ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4403        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4404     if(shader_20) {
4405         color = getPixelColor(device, 160, 120);
4406         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4407            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4408     }
4409     if(shader_20_2) {
4410         color = getPixelColor(device, 480, 120);
4411         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4412            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4413     }
4414
4415     IDirect3DVertexDeclaration9_Release(decl);
4416     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4417     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4418     IDirect3DVertexShader9_Release(shader_11_2);
4419     IDirect3DVertexShader9_Release(shader_11);
4420 }
4421
4422 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4423 {
4424     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4425     HRESULT hr;
4426     DWORD color;
4427     DWORD shader_code_11[] =  {
4428         0xffff0101,                                         /* ps_1_1           */
4429         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4430         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4431         0x0000ffff                                          /* end              */
4432     };
4433     DWORD shader_code_12[] =  {
4434         0xffff0102,                                         /* ps_1_2           */
4435         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4436         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4437         0x0000ffff                                          /* end              */
4438     };
4439     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4440      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4441      * During development of this test, 1.3 shaders were verified too
4442      */
4443     DWORD shader_code_14[] =  {
4444         0xffff0104,                                         /* ps_1_4           */
4445         /* Try to make one constant local. It gets clamped too, although the binary contains
4446          * the bigger numbers
4447          */
4448         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4449         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4450         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4451         0x0000ffff                                          /* end              */
4452     };
4453     DWORD shader_code_20[] =  {
4454         0xffff0200,                                         /* ps_2_0           */
4455         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4456         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4457         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
4458         0x0000ffff                                          /* end              */
4459     };
4460     float quad1[] = {
4461         -1.0,   -1.0,   0.1,
4462          0.0,   -1.0,   0.1,
4463         -1.0,    0.0,   0.1,
4464          0.0,    0.0,   0.1
4465     };
4466     float quad2[] = {
4467          0.0,   -1.0,   0.1,
4468          1.0,   -1.0,   0.1,
4469          0.0,    0.0,   0.1,
4470          1.0,    0.0,   0.1
4471     };
4472     float quad3[] = {
4473          0.0,    0.0,   0.1,
4474          1.0,    0.0,   0.1,
4475          0.0,    1.0,   0.1,
4476          1.0,    1.0,   0.1
4477     };
4478     float quad4[] = {
4479         -1.0,    0.0,   0.1,
4480          0.0,    0.0,   0.1,
4481         -1.0,    1.0,   0.1,
4482          0.0,    1.0,   0.1
4483     };
4484     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4485     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4486
4487     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4488     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4489
4490     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4491     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4492     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4493     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4494     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4495     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4496     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4497     if(FAILED(hr)) shader_20 = NULL;
4498
4499     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4500     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4501     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4502     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4503     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4504     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4505
4506     hr = IDirect3DDevice9_BeginScene(device);
4507     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4508     if(SUCCEEDED(hr))
4509     {
4510         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4511         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4512         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4513         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4514
4515         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4516         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4517         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4518         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4519
4520         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4521         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4522         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4523         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4524
4525         if(shader_20) {
4526             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4527             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4528             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4529             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4530         }
4531
4532         hr = IDirect3DDevice9_EndScene(device);
4533         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4534     }
4535     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4536     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4537
4538     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4539     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4540
4541     color = getPixelColor(device, 160, 360);
4542     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4543        "quad 1 has color %08x, expected 0x00808000\n", color);
4544     color = getPixelColor(device, 480, 360);
4545     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4546        "quad 2 has color %08x, expected 0x00808000\n", color);
4547     color = getPixelColor(device, 480, 120);
4548     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4549        "quad 3 has color %08x, expected 0x00808000\n", color);
4550     if(shader_20) {
4551         color = getPixelColor(device, 160, 120);
4552         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4553            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4554     }
4555
4556     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4557     IDirect3DPixelShader9_Release(shader_14);
4558     IDirect3DPixelShader9_Release(shader_12);
4559     IDirect3DPixelShader9_Release(shader_11);
4560 }
4561
4562 static void dp2add_ps_test(IDirect3DDevice9 *device)
4563 {
4564     IDirect3DPixelShader9 *shader_dp2add = NULL;
4565     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4566     HRESULT hr;
4567     DWORD color;
4568
4569     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
4570      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4571      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
4572      * r0 first.
4573      * The result here for the r,g,b components should be roughly 0.5:
4574      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4575     static const DWORD shader_code_dp2add[] =  {
4576         0xffff0200,                                                             /* ps_2_0                       */
4577         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
4578
4579         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
4580         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
4581
4582         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
4583         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
4584         0x0000ffff                                                              /* end                          */
4585     };
4586
4587     /* Test the _sat modifier, too.  Result here should be:
4588      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4589      *      _SAT: ==> 1.0
4590      *   ADD: (1.0 + -0.5) = 0.5
4591      */
4592     static const DWORD shader_code_dp2add_sat[] =  {
4593         0xffff0200,                                                             /* ps_2_0                           */
4594         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
4595
4596         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
4597         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
4598         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
4599
4600         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
4601         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
4602         0x0000ffff                                                              /* end                              */
4603     };
4604
4605     const float quad[] = {
4606         -1.0,   -1.0,   0.1,
4607          1.0,   -1.0,   0.1,
4608         -1.0,    1.0,   0.1,
4609          1.0,    1.0,   0.1
4610     };
4611
4612
4613     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
4614     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4615
4616     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
4617     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4618
4619     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
4620     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4621
4622     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4623     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4624
4625     if (shader_dp2add) {
4626
4627         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
4628         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4629
4630         hr = IDirect3DDevice9_BeginScene(device);
4631         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4632         if(SUCCEEDED(hr))
4633         {
4634             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4635             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4636
4637             hr = IDirect3DDevice9_EndScene(device);
4638             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4639         }
4640         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4641         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4642
4643         color = getPixelColor(device, 360, 240);
4644         ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4645
4646         IDirect3DPixelShader9_Release(shader_dp2add);
4647     } else {
4648         skip("dp2add shader creation failed\n");
4649     }
4650
4651     if (shader_dp2add_sat) {
4652
4653         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
4654         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4655
4656         hr = IDirect3DDevice9_BeginScene(device);
4657         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4658         if(SUCCEEDED(hr))
4659         {
4660             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4661             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4662
4663             hr = IDirect3DDevice9_EndScene(device);
4664             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4665         }
4666         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4667         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4668
4669         color = getPixelColor(device, 360, 240);
4670         ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4671
4672         IDirect3DPixelShader9_Release(shader_dp2add_sat);
4673     } else {
4674         skip("dp2add shader creation failed\n");
4675     }
4676
4677     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4678     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4679 }
4680
4681 static void cnd_test(IDirect3DDevice9 *device)
4682 {
4683     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
4684     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
4685     HRESULT hr;
4686     DWORD color;
4687     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
4688      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
4689      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
4690      */
4691     DWORD shader_code_11[] =  {
4692         0xffff0101,                                                                 /* ps_1_1               */
4693         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4694         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4695         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
4696         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
4697         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4698         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4699         0x0000ffff                                                                  /* end                  */
4700     };
4701     DWORD shader_code_12[] =  {
4702         0xffff0102,                                                                 /* ps_1_2               */
4703         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4704         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4705         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
4706         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
4707         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4708         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4709         0x0000ffff                                                                  /* end                  */
4710     };
4711     DWORD shader_code_13[] =  {
4712         0xffff0103,                                                                 /* ps_1_3               */
4713         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4714         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4715         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
4716         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
4717         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4718         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4719         0x0000ffff                                                                  /* end                  */
4720     };
4721     DWORD shader_code_14[] =  {
4722         0xffff0104,                                                                 /* ps_1_3               */
4723         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
4724         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
4725         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
4726         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
4727         0x0000ffff                                                                  /* end                  */
4728     };
4729
4730     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
4731      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
4732      * set by the compiler, it was added manually after compilation. It isn't always allowed,
4733      * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
4734      * native CreatePixelShader returns an error.
4735      *
4736      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
4737      * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
4738      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
4739      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
4740      */
4741     DWORD shader_code_11_coissue[] =  {
4742         0xffff0101,                                                             /* ps_1_1                   */
4743         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4744         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4745         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4746         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4747         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4748         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4749         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4750         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4751         /* 0x40000000 = D3DSI_COISSUE */
4752         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4753         0x0000ffff                                                              /* end                      */
4754     };
4755     DWORD shader_code_12_coissue[] =  {
4756         0xffff0102,                                                             /* ps_1_2                   */
4757         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4758         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4759         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4760         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4761         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4762         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4763         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4764         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4765         /* 0x40000000 = D3DSI_COISSUE */
4766         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4767         0x0000ffff                                                              /* end                      */
4768     };
4769     DWORD shader_code_13_coissue[] =  {
4770         0xffff0103,                                                             /* ps_1_3                   */
4771         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4772         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4773         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4774         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4775         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4776         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4777         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4778         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4779         /* 0x40000000 = D3DSI_COISSUE */
4780         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4781         0x0000ffff                                                              /* end                      */
4782     };
4783     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
4784      * compare against 0.5
4785      */
4786     DWORD shader_code_14_coissue[] =  {
4787         0xffff0104,                                                             /* ps_1_4                   */
4788         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
4789         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
4790         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
4791         /* 0x40000000 = D3DSI_COISSUE */
4792         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
4793         0x0000ffff                                                              /* end                      */
4794     };
4795     float quad1[] = {
4796         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
4797          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
4798         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
4799          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
4800     };
4801     float quad2[] = {
4802          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
4803          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
4804          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
4805          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
4806     };
4807     float quad3[] = {
4808          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
4809          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
4810          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
4811          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
4812     };
4813     float quad4[] = {
4814         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
4815          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
4816         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
4817          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
4818     };
4819     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
4820     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
4821     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
4822     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
4823
4824     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4825     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4826
4827     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4828     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4829     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4830     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4831     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
4832     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4833     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4834     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4835     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
4836     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4837     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
4838     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4839     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
4840     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4841     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
4842     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4843
4844     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4845     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4846     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4847     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4848     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4849     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4850
4851     hr = IDirect3DDevice9_BeginScene(device);
4852     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4853     if(SUCCEEDED(hr))
4854     {
4855         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4856         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4857         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4858         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4859
4860         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4861         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4862         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4863         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4864
4865         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
4866         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4867         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4868         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4869
4870         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4871         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4872         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4873         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4874
4875         hr = IDirect3DDevice9_EndScene(device);
4876         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4877     }
4878     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4879     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4880
4881     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4882     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4883
4884     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
4885     color = getPixelColor(device, 158, 118);
4886     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
4887     color = getPixelColor(device, 162, 118);
4888     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
4889     color = getPixelColor(device, 158, 122);
4890     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
4891     color = getPixelColor(device, 162, 122);
4892     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
4893
4894     /* 1.1 shader. All 3 components get set, based on the .w comparison */
4895     color = getPixelColor(device, 158, 358);
4896     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
4897     color = getPixelColor(device, 162, 358);
4898     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4899         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
4900     color = getPixelColor(device, 158, 362);
4901     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
4902     color = getPixelColor(device, 162, 362);
4903     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4904         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
4905
4906     /* 1.2 shader */
4907     color = getPixelColor(device, 478, 358);
4908     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
4909     color = getPixelColor(device, 482, 358);
4910     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4911         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
4912     color = getPixelColor(device, 478, 362);
4913     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
4914     color = getPixelColor(device, 482, 362);
4915     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4916         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
4917
4918     /* 1.3 shader */
4919     color = getPixelColor(device, 478, 118);
4920     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
4921     color = getPixelColor(device, 482, 118);
4922     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4923         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
4924     color = getPixelColor(device, 478, 122);
4925     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
4926     color = getPixelColor(device, 482, 122);
4927     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4928         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
4929
4930     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4931     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4932     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
4933     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4934     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
4935     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4936
4937     hr = IDirect3DDevice9_BeginScene(device);
4938     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4939     if(SUCCEEDED(hr))
4940     {
4941         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
4942         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4943         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4944         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4945
4946         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
4947         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4948         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4949         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4950
4951         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
4952         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4953         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4954         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4955
4956         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
4957         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4958         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4959         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4960
4961         hr = IDirect3DDevice9_EndScene(device);
4962         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4963     }
4964     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4965     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4966
4967     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4968     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4969
4970     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
4971      * that we swapped the values in c1 and c2 to make the other tests return some color
4972      */
4973     color = getPixelColor(device, 158, 118);
4974     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
4975     color = getPixelColor(device, 162, 118);
4976     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
4977     color = getPixelColor(device, 158, 122);
4978     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
4979     color = getPixelColor(device, 162, 122);
4980     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
4981
4982     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
4983     color = getPixelColor(device, 158, 358);
4984     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4985         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
4986     color = getPixelColor(device, 162, 358);
4987     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4988         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
4989     color = getPixelColor(device, 158, 362);
4990     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4991         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
4992     color = getPixelColor(device, 162, 362);
4993     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4994         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
4995
4996     /* 1.2 shader */
4997     color = getPixelColor(device, 478, 358);
4998     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4999         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5000     color = getPixelColor(device, 482, 358);
5001     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5002         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5003     color = getPixelColor(device, 478, 362);
5004     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5005         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5006     color = getPixelColor(device, 482, 362);
5007     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5008         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5009
5010     /* 1.3 shader */
5011     color = getPixelColor(device, 478, 118);
5012     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5013         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5014     color = getPixelColor(device, 482, 118);
5015     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5016         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5017     color = getPixelColor(device, 478, 122);
5018     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5019         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5020     color = getPixelColor(device, 482, 122);
5021     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5022         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5023
5024     IDirect3DPixelShader9_Release(shader_14_coissue);
5025     IDirect3DPixelShader9_Release(shader_13_coissue);
5026     IDirect3DPixelShader9_Release(shader_12_coissue);
5027     IDirect3DPixelShader9_Release(shader_11_coissue);
5028     IDirect3DPixelShader9_Release(shader_14);
5029     IDirect3DPixelShader9_Release(shader_13);
5030     IDirect3DPixelShader9_Release(shader_12);
5031     IDirect3DPixelShader9_Release(shader_11);
5032 }
5033
5034 static void nested_loop_test(IDirect3DDevice9 *device) {
5035     const DWORD shader_code[] = {
5036         0xffff0300,                                                             /* ps_3_0               */
5037         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
5038         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5039         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
5040         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
5041         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5042         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5043         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
5044         0x0000001d,                                                             /* endloop              */
5045         0x0000001d,                                                             /* endloop              */
5046         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
5047         0x0000ffff                                                              /* end                  */
5048     };
5049     IDirect3DPixelShader9 *shader;
5050     HRESULT hr;
5051     DWORD color;
5052     const float quad[] = {
5053         -1.0,   -1.0,   0.1,
5054          1.0,   -1.0,   0.1,
5055         -1.0,    1.0,   0.1,
5056          1.0,    1.0,   0.1
5057     };
5058
5059     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5060     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5061     hr = IDirect3DDevice9_SetPixelShader(device, shader);
5062     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5063     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5064     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5065     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5066     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5067
5068     hr = IDirect3DDevice9_BeginScene(device);
5069     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5070     if(SUCCEEDED(hr))
5071     {
5072         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5073         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5074         hr = IDirect3DDevice9_EndScene(device);
5075         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5076     }
5077     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5078     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5079
5080     color = getPixelColor(device, 360, 240);
5081     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5082        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5083
5084     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5085     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5086     IDirect3DPixelShader9_Release(shader);
5087 }
5088
5089 struct varying_test_struct
5090 {
5091     const DWORD             *shader_code;
5092     IDirect3DPixelShader9   *shader;
5093     DWORD                   color, color_rhw;
5094     const char              *name;
5095     BOOL                    todo, todo_rhw;
5096 };
5097
5098 struct hugeVertex
5099 {
5100     float pos_x,        pos_y,      pos_z,      rhw;
5101     float weight_1,     weight_2,   weight_3,   weight_4;
5102     float index_1,      index_2,    index_3,    index_4;
5103     float normal_1,     normal_2,   normal_3,   normal_4;
5104     float fog_1,        fog_2,      fog_3,      fog_4;
5105     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
5106     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
5107     float binormal_1,   binormal_2, binormal_3, binormal_4;
5108     float depth_1,      depth_2,    depth_3,    depth_4;
5109     DWORD diffuse, specular;
5110 };
5111
5112 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5113     /* dcl_position: fails to compile */
5114     const DWORD blendweight_code[] = {
5115         0xffff0300,                             /* ps_3_0                   */
5116         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
5117         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5118         0x0000ffff                              /* end                      */
5119     };
5120     const DWORD blendindices_code[] = {
5121         0xffff0300,                             /* ps_3_0                   */
5122         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
5123         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5124         0x0000ffff                              /* end                      */
5125     };
5126     const DWORD normal_code[] = {
5127         0xffff0300,                             /* ps_3_0                   */
5128         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
5129         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5130         0x0000ffff                              /* end                      */
5131     };
5132     /* psize: fails? */
5133     const DWORD texcoord0_code[] = {
5134         0xffff0300,                             /* ps_3_0                   */
5135         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
5136         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5137         0x0000ffff                              /* end                      */
5138     };
5139     const DWORD tangent_code[] = {
5140         0xffff0300,                             /* ps_3_0                   */
5141         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
5142         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5143         0x0000ffff                              /* end                      */
5144     };
5145     const DWORD binormal_code[] = {
5146         0xffff0300,                             /* ps_3_0                   */
5147         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
5148         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5149         0x0000ffff                              /* end                      */
5150     };
5151     /* tessfactor: fails */
5152     /* positiont: fails */
5153     const DWORD color_code[] = {
5154         0xffff0300,                             /* ps_3_0                   */
5155         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
5156         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5157         0x0000ffff                              /* end                      */
5158     };
5159     const DWORD fog_code[] = {
5160         0xffff0300,                             /* ps_3_0                   */
5161         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
5162         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5163         0x0000ffff                              /* end                      */
5164     };
5165     const DWORD depth_code[] = {
5166         0xffff0300,                             /* ps_3_0                   */
5167         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
5168         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5169         0x0000ffff                              /* end                      */
5170     };
5171     const DWORD specular_code[] = {
5172         0xffff0300,                             /* ps_3_0                   */
5173         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
5174         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5175         0x0000ffff                              /* end                      */
5176     };
5177     /* sample: fails */
5178
5179     struct varying_test_struct tests[] = {
5180        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
5181        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
5182        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
5183        /* Why does dx not forward the texcoord? */
5184        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
5185        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
5186        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
5187        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
5188        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
5189        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
5190        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
5191     };
5192     /* Declare a monster vertex type :-) */
5193     static const D3DVERTEXELEMENT9 decl_elements[] = {
5194         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5195         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5196         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5197         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5198         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5199         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5200         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5201         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5202         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5203         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5204         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5205         D3DDECL_END()
5206     };
5207     static const D3DVERTEXELEMENT9 decl_elements2[] = {
5208         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
5209         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5210         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5211         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5212         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5213         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5214         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5215         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5216         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5217         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5218         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5219         D3DDECL_END()
5220     };
5221     struct hugeVertex data[4] = {
5222         {
5223             -1.0,   -1.0,   0.1,    1.0,
5224              0.1,    0.1,   0.1,    0.1,
5225              0.2,    0.2,   0.2,    0.2,
5226              0.3,    0.3,   0.3,    0.3,
5227              0.4,    0.4,   0.4,    0.4,
5228              0.50,   0.55,  0.55,   0.55,
5229              0.6,    0.6,   0.6,    0.7,
5230              0.7,    0.7,   0.7,    0.6,
5231              0.8,    0.8,   0.8,    0.8,
5232              0xe6e6e6e6, /* 0.9 * 256 */
5233              0x224488ff  /* Nothing special */
5234         },
5235         {
5236              1.0,   -1.0,   0.1,    1.0,
5237              0.1,    0.1,   0.1,    0.1,
5238              0.2,    0.2,   0.2,    0.2,
5239              0.3,    0.3,   0.3,    0.3,
5240              0.4,    0.4,   0.4,    0.4,
5241              0.50,   0.55,  0.55,   0.55,
5242              0.6,    0.6,   0.6,    0.7,
5243              0.7,    0.7,   0.7,    0.6,
5244              0.8,    0.8,   0.8,    0.8,
5245              0xe6e6e6e6, /* 0.9 * 256 */
5246              0x224488ff /* Nothing special */
5247         },
5248         {
5249             -1.0,    1.0,   0.1,    1.0,
5250              0.1,    0.1,   0.1,    0.1,
5251              0.2,    0.2,   0.2,    0.2,
5252              0.3,    0.3,   0.3,    0.3,
5253              0.4,    0.4,   0.4,    0.4,
5254              0.50,   0.55,  0.55,   0.55,
5255              0.6,    0.6,   0.6,    0.7,
5256              0.7,    0.7,   0.7,    0.6,
5257              0.8,    0.8,   0.8,    0.8,
5258              0xe6e6e6e6, /* 0.9 * 256 */
5259              0x224488ff /* Nothing special */
5260         },
5261         {
5262              1.0,    1.0,   0.1,    1.0,
5263              0.1,    0.1,   0.1,    0.1,
5264              0.2,    0.2,   0.2,    0.2,
5265              0.3,    0.3,   0.3,    0.3,
5266              0.4,    0.4,   0.4,    0.4,
5267              0.50,   0.55,  0.55,   0.55,
5268              0.6,    0.6,   0.6,    0.7,
5269              0.7,    0.7,   0.7,    0.6,
5270              0.8,    0.8,   0.8,    0.8,
5271              0xe6e6e6e6, /* 0.9 * 256 */
5272              0x224488ff /* Nothing special */
5273         },
5274     };
5275     struct hugeVertex data2[4];
5276     IDirect3DVertexDeclaration9 *decl;
5277     IDirect3DVertexDeclaration9 *decl2;
5278     HRESULT hr;
5279     unsigned int i;
5280     DWORD color, r, g, b, r_e, g_e, b_e;
5281     BOOL drawok;
5282
5283     memcpy(data2, data, sizeof(data2));
5284     data2[0].pos_x = 0;     data2[0].pos_y = 0;
5285     data2[1].pos_x = 640;   data2[1].pos_y = 0;
5286     data2[2].pos_x = 0;     data2[2].pos_y = 480;
5287     data2[3].pos_x = 640;   data2[3].pos_y = 480;
5288
5289     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5290     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5291     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5292     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5293     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5294     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5295
5296     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5297     {
5298         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5299         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5300            tests[i].name, hr);
5301     }
5302
5303     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5304     {
5305         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5306         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5307
5308         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5309         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5310
5311         hr = IDirect3DDevice9_BeginScene(device);
5312         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5313         drawok = FALSE;
5314         if(SUCCEEDED(hr))
5315         {
5316             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5317             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5318             drawok = SUCCEEDED(hr);
5319             hr = IDirect3DDevice9_EndScene(device);
5320             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5321         }
5322         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5323         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5324
5325         /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5326          * the failure and do not check the color if it failed
5327          */
5328         if(!drawok) {
5329             continue;
5330         }
5331
5332         color = getPixelColor(device, 360, 240);
5333         r = color & 0x00ff0000 >> 16;
5334         g = color & 0x0000ff00 >>  8;
5335         b = color & 0x000000ff;
5336         r_e = tests[i].color & 0x00ff0000 >> 16;
5337         g_e = tests[i].color & 0x0000ff00 >>  8;
5338         b_e = tests[i].color & 0x000000ff;
5339
5340         if(tests[i].todo) {
5341             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5342                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5343                          tests[i].name, color, tests[i].color);
5344         } else {
5345             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5346                "Test %s returned color 0x%08x, expected 0x%08x\n",
5347                tests[i].name, color, tests[i].color);
5348         }
5349     }
5350
5351     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5352     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5353     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5354     {
5355         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5356         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5357
5358         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5359         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5360
5361         hr = IDirect3DDevice9_BeginScene(device);
5362         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5363         if(SUCCEEDED(hr))
5364         {
5365             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5366             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5367             hr = IDirect3DDevice9_EndScene(device);
5368             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5369         }
5370         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5371         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5372
5373         color = getPixelColor(device, 360, 240);
5374         r = color & 0x00ff0000 >> 16;
5375         g = color & 0x0000ff00 >>  8;
5376         b = color & 0x000000ff;
5377         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5378         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
5379         b_e = tests[i].color_rhw & 0x000000ff;
5380
5381         if(tests[i].todo_rhw) {
5382             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5383              * pipeline
5384              */
5385             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5386                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5387                          tests[i].name, color, tests[i].color_rhw);
5388         } else {
5389             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5390                "Test %s returned color 0x%08x, expected 0x%08x\n",
5391                tests[i].name, color, tests[i].color_rhw);
5392         }
5393     }
5394
5395     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5396     {
5397         IDirect3DPixelShader9_Release(tests[i].shader);
5398     }
5399
5400     IDirect3DVertexDeclaration9_Release(decl2);
5401     IDirect3DVertexDeclaration9_Release(decl);
5402 }
5403
5404 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5405     static const DWORD ps_code[] = {
5406     0xffff0300,                                                             /* ps_3_0                       */
5407     0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0          */
5408     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5409     0x0200001f, 0x8001000a, 0x900f0003,                                     /* dcl_color1 v3                */
5410     0x0200001f, 0x8000000b, 0x900f0004,                                     /* dcl_fog v4                   */
5411     0x0200001f, 0x80030005, 0x900f0005,                                     /* dcl_texcoord3 v5             */
5412     0x0200001f, 0x80000003, 0x900f0006,                                     /* dcl_normal v6                */
5413     0x0200001f, 0x80000006, 0x900f0007,                                     /* dcl_tangent v7               */
5414     0x0200001f, 0x80000001, 0x900f0008,                                     /* dcl_blendweight v8           */
5415     0x0200001f, 0x8000000c, 0x900f0009,                                     /* dcl_depth v9                 */
5416
5417     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5418     0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0                  */
5419     0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800,             /* add r0, r0, v0[aL]           */
5420     0x0000001d,                                                             /* endloop                      */
5421     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5422     0x0000ffff                                                              /* end                          */
5423     };
5424     static const DWORD vs_1_code[] = {
5425     0xfffe0101,                                                             /* vs_1_1                       */
5426     0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5427     0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5428     0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5429     0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5430     0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5431     0x00000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5432     0x00000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5433     0x00000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5434     0x00000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5435     0x00000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5436     0x00000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5437     0x00000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5438     0x00000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5439     0x00000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5440     0x00000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5441     0x00000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5442     0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5443     0x0000ffff
5444     };
5445     DWORD vs_2_code[] = {
5446     0xfffe0200,                                                             /* vs_2_0                       */
5447     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5448     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5449     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5450     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5451     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5452     0x02000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5453     0x02000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5454     0x02000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5455     0x02000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5456     0x02000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5457     0x02000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5458     0x02000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5459     0x02000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5460     0x02000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5461     0x02000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5462     0x02000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5463     0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5464     0x0000ffff                                                              /* end                          */
5465     };
5466     /* TODO: Define normal, tangent, blendweight and depth here */
5467     static const DWORD vs_3_code[] = {
5468     0xfffe0300,                                                             /* vs_3_0                       */
5469     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5470     0x0200001f, 0x8001000a, 0xe00f0009,                                     /* dcl_color1 o9                */
5471     0x0200001f, 0x8000000b, 0xe00f0002,                                     /* dcl_fog o2                   */
5472     0x0200001f, 0x80030005, 0xe00f0005,                                     /* dcl_texcoord3 o5             */
5473     0x0200001f, 0x80000000, 0xe00f000b,                                     /* dcl_position o11             */
5474     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5475     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5476     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5477     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5478     0x02000001, 0xe00f0009, 0xa0e40000,                                     /* mov o9, c0                   */
5479     0x02000001, 0xe00f0002, 0xa0e40001,                                     /* mov o2, c1                   */
5480     0x02000001, 0xe00f0005, 0xa0e40002,                                     /* mov o5, c2                   */
5481     0x02000001, 0xe00f000b, 0x90e40000,                                     /* mov o11, v0                  */
5482     0x0000ffff                                                              /* end                          */
5483     };
5484     float quad1[] =  {
5485         -1.0,   -1.0,   0.1,
5486          0.0,   -1.0,   0.1,
5487         -1.0,    0.0,   0.1,
5488          0.0,    0.0,   0.1
5489     };
5490     float quad2[] =  {
5491          0.0,   -1.0,   0.1,
5492          1.0,   -1.0,   0.1,
5493          0.0,    0.0,   0.1,
5494          1.0,    0.0,   0.1
5495     };
5496     float quad3[] =  {
5497         -1.0,    0.0,   0.1,
5498          0.0,    0.0,   0.1,
5499         -1.0,    1.0,   0.1,
5500          0.0,    1.0,   0.1
5501     };
5502
5503     HRESULT hr;
5504     DWORD color;
5505     IDirect3DPixelShader9 *pixelshader = NULL;
5506     IDirect3DVertexShader9 *vs_1_shader = NULL;
5507     IDirect3DVertexShader9 *vs_2_shader = NULL;
5508     IDirect3DVertexShader9 *vs_3_shader = NULL;
5509
5510     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5511
5512     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5513     ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %08x\n", hr);
5514     hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5515     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5516     hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5517     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5518     hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5519     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5520     hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5521     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5522     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5523
5524     hr = IDirect3DDevice9_BeginScene(device);
5525     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5526     if(SUCCEEDED(hr))
5527     {
5528         hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5529         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5530         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5531         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5532
5533         hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5534         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5535         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5536         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5537
5538         hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5539         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5540         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5541         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5542
5543         hr = IDirect3DDevice9_EndScene(device);
5544         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5545     }
5546     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5547     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5548
5549     color = getPixelColor(device, 160, 120);
5550     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x1a, 0x34, 0x67), 1),
5551        "vs_3_0 returned color 0x%08x, expected 0x00193366\n", color);
5552     color = getPixelColor(device, 160, 360);
5553     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1),
5554        "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5555     color = getPixelColor(device, 480, 360);
5556     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1),
5557        "vs_2_0 returned color 0x%08x, expected 0x004c0066\n", color);
5558
5559     /* cleanup */
5560     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5561     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5562     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5563     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5564     if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5565     if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5566     if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5567     if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5568 }
5569
5570 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5571     static const DWORD vs_code[] = {
5572     0xfffe0300,                                                             /* vs_3_0                       */
5573     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5574     0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0              */
5575     0x0200001f, 0x8000000a, 0xe00f0001,                                     /* dcl_color0 o1                */
5576     0x0200001f, 0x80000005, 0xe00f0002,                                     /* dcl_texcoord0 o2             */
5577     0x0200001f, 0x8000000b, 0xe00f0003,                                     /* dcl_fog o3                   */
5578     0x0200001f, 0x80000003, 0xe00f0004,                                     /* dcl_normal o4                */
5579     0x0200001f, 0x8000000c, 0xe00f0005,                                     /* dcl_depth o5                 */
5580     0x0200001f, 0x80000006, 0xe00f0006,                                     /* dcl_tangent o6               */
5581     0x0200001f, 0x80000001, 0xe00f0007,                                     /* dcl_blendweight o7           */
5582     0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0   */
5583     0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0   */
5584     0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0   */
5585     0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0   */
5586
5587     0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                   */
5588     0x02000001, 0xe00f0001, 0xa0e40001,                                     /* mov o1, c1                   */
5589     0x02000001, 0xe00f0002, 0xa0e40002,                                     /* mov o2, c2                   */
5590     0x02000001, 0xe00f0003, 0xa0e40003,                                     /* mov o3, c3                   */
5591     0x02000001, 0xe00f0004, 0xa0e40000,                                     /* mov o4, c0                   */
5592     0x02000001, 0xe00f0005, 0xa0e40000,                                     /* mov o5, c0                   */
5593     0x02000001, 0xe00f0006, 0xa0e40000,                                     /* mov o6, c0                   */
5594     0x02000001, 0xe00f0007, 0xa0e40000,                                     /* mov o7, c0                   */
5595     0x0000ffff                                                              /* end                          */
5596     };
5597     static const DWORD ps_1_code[] = {
5598     0xffff0104,                                                             /* ps_1_4                       */
5599     0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5600     0x00000040, 0x80070001, 0xb0e40000,                                     /* texcrd r1.xyz, t0            */
5601     0x00000001, 0x80080001, 0xa0ff0000,                                     /* mov r1.a, c0.a               */
5602     0x00000002, 0x800f0000, 0x90e40000, 0x80e40001,                         /* add r0, v0, r1               */
5603     0x0000ffff                                                              /* end                          */
5604     };
5605     static const DWORD ps_2_code[] = {
5606     0xffff0200,                                                             /* ps_2_0                       */
5607     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
5608     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl v0                       */
5609     0x0200001f, 0x80000000, 0x900f0001,                                     /* dcl v1                       */
5610
5611     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
5612     0x03000002, 0x800f0000, 0x80e40000,0xb0e40000,                          /* add r0, r0, t0               */
5613     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5614     0x0000ffff                                                              /* end                          */
5615     };
5616     static const DWORD ps_3_code[] = {
5617     0xffff0300,                                                             /* ps_3_0                       */
5618     0x0200001f, 0x80000005, 0x900f0000,                                     /* dcl_texcoord0 v0             */
5619     0x0200001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
5620     0x0200001f, 0x8000000b, 0x900f0002,                                     /* dcl_fog v2                   */
5621
5622     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
5623     0x03000002, 0x800f0000, 0x80e40000, 0x90e40001,                         /* add r0, r0, v1               */
5624     0x03000002, 0x800f0000, 0x80e40000, 0x90e40002,                         /* mov r0, r0, v2               */
5625     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5626     0x0000ffff                                                              /* end                          */
5627     };
5628
5629     float quad1[] =  {
5630         -1.0,   -1.0,   0.1,
5631          0.0,   -1.0,   0.1,
5632         -1.0,    0.0,   0.1,
5633          0.0,    0.0,   0.1
5634     };
5635     float quad2[] =  {
5636          0.0,   -1.0,   0.1,
5637          1.0,   -1.0,   0.1,
5638          0.0,    0.0,   0.1,
5639          1.0,    0.0,   0.1
5640     };
5641     float quad3[] =  {
5642         -1.0,    0.0,   0.1,
5643          0.0,    0.0,   0.1,
5644         -1.0,    1.0,   0.1,
5645          0.0,    1.0,   0.1
5646     };
5647     float quad4[] =  {
5648          0.0,    0.0,   0.1,
5649          1.0,    0.0,   0.1,
5650          0.0,    1.0,   0.1,
5651          1.0,    1.0,   0.1
5652     };
5653
5654     HRESULT hr;
5655     DWORD color;
5656     IDirect3DVertexShader9 *vertexshader = NULL;
5657     IDirect3DPixelShader9 *ps_1_shader = NULL;
5658     IDirect3DPixelShader9 *ps_2_shader = NULL;
5659     IDirect3DPixelShader9 *ps_3_shader = NULL;
5660     IDirect3DTexture9 *texture = NULL;
5661     D3DLOCKED_RECT lr;
5662     unsigned int x, y;
5663
5664     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5665
5666     hr = IDirect3DDevice9_CreateTexture(device, 512,  512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
5667     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5668     if(FAILED(hr)) {
5669         skip("D3DFMT_A16B16G16R16 textures not supported\n");
5670         return;
5671     }
5672     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5673     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
5674     for(y = 0; y < 512; y++) {
5675         for(x = 0; x < 512; x++) {
5676             double r_f = (double) x / (double) 512;
5677             double g_f = (double) y / (double) 512;
5678             unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
5679             unsigned short r = (unsigned short) (r_f * 65535.0);
5680             unsigned short g = (unsigned short) (g_f * 65535.0);
5681             dst[0] = r;
5682             dst[1] = g;
5683             dst[2] = 0;
5684             dst[3] = 65535;
5685         }
5686     }
5687     hr = IDirect3DTexture9_UnlockRect(texture, 0);
5688     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
5689
5690     hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
5691     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5692     hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
5693     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5694     hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
5695     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5696     hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
5697     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5698     hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
5699     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5700     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5701
5702     hr = IDirect3DDevice9_BeginScene(device);
5703     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5704     if(SUCCEEDED(hr))
5705     {
5706         hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
5707         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5708         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5709         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5710
5711         hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
5712         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5713         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5714         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5715
5716         hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
5717         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5718         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5719         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5720
5721         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5722         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5723         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5724         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5725         hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5726         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
5727         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5728         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
5729         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5730         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5731
5732         hr = IDirect3DDevice9_EndScene(device);
5733         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5734     }
5735     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5736     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5737
5738     color = getPixelColor(device, 160, 120);
5739     ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
5740        (color & 0x0000ff00) == 0x0000ff00 &&
5741        (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
5742        "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
5743     color = getPixelColor(device, 160, 360);
5744     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5745        (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
5746        (color & 0x000000ff) == 0x00000000,
5747        "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
5748     color = getPixelColor(device, 480, 360);
5749     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5750        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5751        (color & 0x000000ff) == 0x00000000,
5752        "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
5753     color = getPixelColor(device, 480, 160);
5754     ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
5755        (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5756        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5757        (color & 0x000000ff) == 0x00000000),
5758        "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
5759
5760     /* cleanup */
5761     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5762     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5763     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5764     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5765     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5766     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5767     if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
5768     if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
5769     if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
5770     if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
5771     if(texture) IDirect3DTexture9_Release(texture);
5772 }
5773
5774 void test_compare_instructions(IDirect3DDevice9 *device)
5775 {
5776     DWORD shader_sge_vec_code[] = {
5777         0xfffe0101,                                         /* vs_1_1                   */
5778         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5779         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5780         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5781         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
5782         0x0000ffff                                          /* end                      */
5783     };
5784     DWORD shader_slt_vec_code[] = {
5785         0xfffe0101,                                         /* vs_1_1                   */
5786         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5787         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5788         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5789         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
5790         0x0000ffff                                          /* end                      */
5791     };
5792     DWORD shader_sge_scalar_code[] = {
5793         0xfffe0101,                                         /* vs_1_1                   */
5794         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5795         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5796         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5797         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
5798         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
5799         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
5800         0x0000ffff                                          /* end                      */
5801     };
5802     DWORD shader_slt_scalar_code[] = {
5803         0xfffe0101,                                         /* vs_1_1                   */
5804         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5805         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5806         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5807         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
5808         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
5809         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
5810         0x0000ffff                                          /* end                      */
5811     };
5812     IDirect3DVertexShader9 *shader_sge_vec;
5813     IDirect3DVertexShader9 *shader_slt_vec;
5814     IDirect3DVertexShader9 *shader_sge_scalar;
5815     IDirect3DVertexShader9 *shader_slt_scalar;
5816     HRESULT hr, color;
5817     float quad1[] =  {
5818         -1.0,   -1.0,   0.1,
5819          0.0,   -1.0,   0.1,
5820         -1.0,    0.0,   0.1,
5821          0.0,    0.0,   0.1
5822     };
5823     float quad2[] =  {
5824          0.0,   -1.0,   0.1,
5825          1.0,   -1.0,   0.1,
5826          0.0,    0.0,   0.1,
5827          1.0,    0.0,   0.1
5828     };
5829     float quad3[] =  {
5830         -1.0,    0.0,   0.1,
5831          0.0,    0.0,   0.1,
5832         -1.0,    1.0,   0.1,
5833          0.0,    1.0,   0.1
5834     };
5835     float quad4[] =  {
5836          0.0,    0.0,   0.1,
5837          1.0,    0.0,   0.1,
5838          0.0,    1.0,   0.1,
5839          1.0,    1.0,   0.1
5840     };
5841     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5842     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5843
5844     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5845
5846     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5847     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5848     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5849     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5850     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5851     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5852     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5853     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5854     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5855     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5856     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5857     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5858     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5859     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5860
5861     hr = IDirect3DDevice9_BeginScene(device);
5862     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5863     if(SUCCEEDED(hr))
5864     {
5865         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5866         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5867         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5868         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5869
5870         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5871         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5872         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5873         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5874
5875         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5876         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5877         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5878         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5879
5880         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5881         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5882
5883         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5884         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5885         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5886         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5887
5888         hr = IDirect3DDevice9_EndScene(device);
5889         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5890     }
5891
5892     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5893     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5894     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5895     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5896
5897     color = getPixelColor(device, 160, 360);
5898     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
5899     color = getPixelColor(device, 480, 360);
5900     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
5901     color = getPixelColor(device, 160, 120);
5902     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
5903     color = getPixelColor(device, 480, 160);
5904     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
5905
5906     IDirect3DVertexShader9_Release(shader_sge_vec);
5907     IDirect3DVertexShader9_Release(shader_slt_vec);
5908     IDirect3DVertexShader9_Release(shader_sge_scalar);
5909     IDirect3DVertexShader9_Release(shader_slt_scalar);
5910 }
5911
5912 void test_vshader_input(IDirect3DDevice9 *device)
5913 {
5914     DWORD swapped_shader_code_3[] = {
5915         0xfffe0300,                                         /* vs_3_0               */
5916         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5917         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5918         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5919         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5920         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5921         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5922         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5923         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5924         0x0000ffff                                          /* end                  */
5925     };
5926     DWORD swapped_shader_code_1[] = {
5927         0xfffe0101,                                         /* vs_1_1               */
5928         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5929         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5930         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5931         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
5932         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5933         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5934         0x0000ffff                                          /* end                  */
5935     };
5936     DWORD swapped_shader_code_2[] = {
5937         0xfffe0200,                                         /* vs_2_0               */
5938         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5939         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5940         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5941         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
5942         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5943         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5944         0x0000ffff                                          /* end                  */
5945     };
5946     DWORD texcoord_color_shader_code_3[] = {
5947         0xfffe0300,                                         /* vs_3_0               */
5948         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5949         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5950         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5951         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
5952         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5953         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
5954         0x0000ffff                                          /* end                  */
5955     };
5956     DWORD texcoord_color_shader_code_2[] = {
5957         0xfffe0200,                                         /* vs_2_0               */
5958         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5959         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
5960         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5961         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
5962         0x0000ffff                                          /* end                  */
5963     };
5964     DWORD texcoord_color_shader_code_1[] = {
5965         0xfffe0101,                                         /* vs_1_1               */
5966         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5967         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
5968         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5969         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
5970         0x0000ffff                                          /* end                  */
5971     };
5972     DWORD color_color_shader_code_3[] = {
5973         0xfffe0300,                                         /* vs_3_0               */
5974         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5975         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5976         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5977         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
5978         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5979         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
5980         0x0000ffff                                          /* end                  */
5981     };
5982     DWORD color_color_shader_code_2[] = {
5983         0xfffe0200,                                         /* vs_2_0               */
5984         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5985         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
5986         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5987         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
5988         0x0000ffff                                          /* end                  */
5989     };
5990     DWORD color_color_shader_code_1[] = {
5991         0xfffe0101,                                         /* vs_1_1               */
5992         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5993         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
5994         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
5995         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
5996         0x0000ffff                                          /* end                  */
5997     };
5998     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
5999     HRESULT hr;
6000     DWORD color;
6001     float quad1[] =  {
6002         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6003          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6004         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6005          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6006     };
6007     float quad2[] =  {
6008          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6009          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6010          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6011          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6012     };
6013     float quad3[] =  {
6014         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
6015          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
6016         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
6017          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6018     };
6019     float quad4[] =  {
6020          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6021          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6022          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6023          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6024     };
6025     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6026         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6027         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6028         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6029         D3DDECL_END()
6030     };
6031     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6032         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6033         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6034         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6035         D3DDECL_END()
6036     };
6037     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6038         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6039         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6040         D3DDECL_END()
6041     };
6042     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6043         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6044         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6045         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
6046         D3DDECL_END()
6047     };
6048     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6049         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6050         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6051         D3DDECL_END()
6052     };
6053     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6054         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6055         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6056         D3DDECL_END()
6057     };
6058     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6059         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6060         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6061         D3DDECL_END()
6062     };
6063     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6064         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6065         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6066         D3DDECL_END()
6067     };
6068     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6069     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6070     unsigned int i;
6071     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6072     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6073
6074     struct vertex quad1_color[] =  {
6075        {-1.0,   -1.0,   0.1,    0x00ff8040},
6076        { 0.0,   -1.0,   0.1,    0x00ff8040},
6077        {-1.0,    0.0,   0.1,    0x00ff8040},
6078        { 0.0,    0.0,   0.1,    0x00ff8040}
6079     };
6080     struct vertex quad2_color[] =  {
6081        { 0.0,   -1.0,   0.1,    0x00ff8040},
6082        { 1.0,   -1.0,   0.1,    0x00ff8040},
6083        { 0.0,    0.0,   0.1,    0x00ff8040},
6084        { 1.0,    0.0,   0.1,    0x00ff8040}
6085     };
6086     struct vertex quad3_color[] =  {
6087        {-1.0,    0.0,   0.1,    0x00ff8040},
6088        { 0.0,    0.0,   0.1,    0x00ff8040},
6089        {-1.0,    1.0,   0.1,    0x00ff8040},
6090        { 0.0,    1.0,   0.1,    0x00ff8040}
6091     };
6092     float quad4_color[] =  {
6093          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6094          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6095          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6096          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6097     };
6098
6099     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6100     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6101     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6102     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6103     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6104     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6105     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6106     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6107
6108     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6109     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6110     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6111     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6112     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6113     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6114     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6115     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6116
6117     for(i = 1; i <= 3; i++) {
6118         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6119         if(i == 3) {
6120             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6121             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6122         } else if(i == 2){
6123             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6124             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6125         } else if(i == 1) {
6126             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6127             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6128         }
6129
6130         hr = IDirect3DDevice9_BeginScene(device);
6131         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6132         if(SUCCEEDED(hr))
6133         {
6134             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6135             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6136
6137             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6138             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6139             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6140             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6141
6142             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6143             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6144             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6145             if(i == 3 || i == 2) {
6146                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6147             } else if(i == 1) {
6148                 /* Succeeds or fails, depending on SW or HW vertex processing */
6149                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6150             }
6151
6152             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6153             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6154             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6155             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6156
6157             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6158             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6159             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6160             if(i == 3 || i == 2) {
6161                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6162             } else if(i == 1) {
6163                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6164             }
6165
6166             hr = IDirect3DDevice9_EndScene(device);
6167             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6168         }
6169
6170         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6171         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6172
6173         if(i == 3 || i == 2) {
6174             color = getPixelColor(device, 160, 360);
6175             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6176                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6177
6178             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6179             color = getPixelColor(device, 480, 360);
6180             ok(color == 0x00FFFF00 || color ==0x00FF0000,
6181                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6182             color = getPixelColor(device, 160, 120);
6183             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6184             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6185                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6186
6187             color = getPixelColor(device, 480, 160);
6188             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6189         } else if(i == 1) {
6190             color = getPixelColor(device, 160, 360);
6191             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6192                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6193             color = getPixelColor(device, 480, 360);
6194             /* Accept the clear color as well in this case, since SW VP returns an error */
6195             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6196             color = getPixelColor(device, 160, 120);
6197             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6198                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
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         }
6202
6203         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6204         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6205
6206         /* Now find out if the whole streams are re-read, or just the last active value for the
6207          * vertices is used.
6208          */
6209         hr = IDirect3DDevice9_BeginScene(device);
6210         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6211         if(SUCCEEDED(hr))
6212         {
6213             float quad1_modified[] =  {
6214                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6215                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6216                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6217                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6218             };
6219             float quad2_modified[] =  {
6220                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6221                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6222                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6223                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6224             };
6225
6226             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6227             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6228
6229             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6230             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6231             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6232             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6233
6234             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6235             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6236             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6237             if(i == 3 || i == 2) {
6238                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6239             } else if(i == 1) {
6240                 /* Succeeds or fails, depending on SW or HW vertex processing */
6241                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6242             }
6243
6244             hr = IDirect3DDevice9_EndScene(device);
6245             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6246         }
6247         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6248         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6249
6250         color = getPixelColor(device, 480, 350);
6251         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6252          * as well.
6253          *
6254          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6255          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6256          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6257          * refrast's result.
6258          *
6259          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6260          */
6261         ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6262            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6263         color = getPixelColor(device, 160, 120);
6264
6265         IDirect3DDevice9_SetVertexShader(device, NULL);
6266         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6267
6268         IDirect3DVertexShader9_Release(swapped_shader);
6269     }
6270
6271     for(i = 1; i <= 3; i++) {
6272         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6273         if(i == 3) {
6274             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6275             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6276             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6277             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6278         } else if(i == 2){
6279             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6280             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6281             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6282             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6283         } else if(i == 1) {
6284             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6285             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6286             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6287             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6288         }
6289
6290         hr = IDirect3DDevice9_BeginScene(device);
6291         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6292         if(SUCCEEDED(hr))
6293         {
6294             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6295             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6296             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6297             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6298             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6299             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6300
6301             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6302             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6303
6304             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6305             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6306             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6307             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6308             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6309             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6310
6311             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6312             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6313             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6314             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6315             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6316             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6317
6318             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6319             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6320             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6321             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6322
6323             hr = IDirect3DDevice9_EndScene(device);
6324             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6325         }
6326         IDirect3DDevice9_SetVertexShader(device, NULL);
6327         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6328
6329         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6330         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6331
6332         color = getPixelColor(device, 160, 360);
6333         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6334            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6335         color = getPixelColor(device, 480, 360);
6336         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6337            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6338         color = getPixelColor(device, 160, 120);
6339         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6340            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6341         color = getPixelColor(device, 480, 160);
6342         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6343            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6344
6345         IDirect3DVertexShader9_Release(texcoord_color_shader);
6346         IDirect3DVertexShader9_Release(color_color_shader);
6347     }
6348
6349     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6350     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6351     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6352     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6353
6354     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6355     IDirect3DVertexDeclaration9_Release(decl_color_color);
6356     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6357     IDirect3DVertexDeclaration9_Release(decl_color_float);
6358 }
6359
6360 static void srgbtexture_test(IDirect3DDevice9 *device)
6361 {
6362     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6363      * texture stage state to render a quad using that texture.  The resulting
6364      * color components should be 0x36 (~ 0.21), per this formula:
6365      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6366      * This is true where srgb_color > 0.04045.
6367      */
6368     IDirect3D9 *d3d = NULL;
6369     HRESULT hr;
6370     LPDIRECT3DTEXTURE9 texture = NULL;
6371     LPDIRECT3DSURFACE9 surface = NULL;
6372     D3DLOCKED_RECT lr;
6373     DWORD color;
6374     float quad[] = {
6375         -1.0,       1.0,       0.0,     0.0,    0.0,
6376          1.0,       1.0,       0.0,     1.0,    0.0,
6377         -1.0,      -1.0,       0.0,     0.0,    1.0,
6378          1.0,      -1.0,       0.0,     1.0,    1.0,
6379     };
6380
6381
6382     memset(&lr, 0, sizeof(lr));
6383     IDirect3DDevice9_GetDirect3D(device, &d3d);
6384     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6385                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6386                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6387         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6388         goto out;
6389     }
6390
6391     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6392                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6393                                         &texture, NULL);
6394     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6395     if(!texture) {
6396         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6397         goto out;
6398     }
6399     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6400     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6401
6402     fill_surface(surface, 0xff7f7f7f);
6403     IDirect3DSurface9_Release(surface);
6404
6405     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6406     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6407     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6408     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6409
6410     hr = IDirect3DDevice9_BeginScene(device);
6411     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6412     if(SUCCEEDED(hr))
6413     {
6414         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6415         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6416
6417         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6418         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6419
6420
6421         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6422         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6423
6424         hr = IDirect3DDevice9_EndScene(device);
6425         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6426     }
6427
6428     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6429     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6430     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6431     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6432
6433     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6434     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6435
6436     color = getPixelColor(device, 320, 240);
6437     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6438
6439 out:
6440     if(texture) IDirect3DTexture9_Release(texture);
6441     IDirect3D9_Release(d3d);
6442 }
6443
6444 static void shademode_test(IDirect3DDevice9 *device)
6445 {
6446     /* Render a quad and try all of the different fixed function shading models. */
6447     HRESULT hr;
6448     DWORD color0, color1;
6449     DWORD color0_gouraud = 0, color1_gouraud = 0;
6450     DWORD shademode = D3DSHADE_FLAT;
6451     DWORD primtype = D3DPT_TRIANGLESTRIP;
6452     LPVOID data = NULL;
6453     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6454     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6455     UINT i, j;
6456     struct vertex quad_strip[] =
6457     {
6458         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6459         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6460         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6461         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6462     };
6463     struct vertex quad_list[] =
6464     {
6465         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6466         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6467         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6468
6469         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6470         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6471         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6472     };
6473
6474     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6475                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6476     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6477     if (FAILED(hr)) goto bail;
6478
6479     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6480                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6481     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6482     if (FAILED(hr)) goto bail;
6483
6484     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6485     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6486
6487     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6488     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6489
6490     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), (void **) &data, 0);
6491     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6492     memcpy(data, quad_strip, sizeof(quad_strip));
6493     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6494     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6495
6496     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), (void **) &data, 0);
6497     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6498     memcpy(data, quad_list, sizeof(quad_list));
6499     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6500     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6501
6502     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
6503      * the color fixups we have to do for FLAT shading will be dependent on that. */
6504     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6505     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6506
6507     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6508     for (j=0; j<2; j++) {
6509
6510         /* Inner loop just changes the D3DRS_SHADEMODE */
6511         for (i=0; i<3; i++) {
6512             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6513             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6514
6515             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6516             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6517
6518             hr = IDirect3DDevice9_BeginScene(device);
6519             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6520             if(SUCCEEDED(hr))
6521             {
6522                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6523                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6524
6525                 hr = IDirect3DDevice9_EndScene(device);
6526                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6527             }
6528
6529             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6530             ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6531
6532             /* Sample two spots from the output */
6533             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6534             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6535             switch(shademode) {
6536                 case D3DSHADE_FLAT:
6537                     /* Should take the color of the first vertex of each triangle */
6538                     todo_wine ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000 (todo)\n", color0);
6539                     todo_wine ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00 (todo)\n", color1);
6540                     shademode = D3DSHADE_GOURAUD;
6541                     break;
6542                 case D3DSHADE_GOURAUD:
6543                     /* Should be an interpolated blend */
6544
6545                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6546                        "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6547                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6548                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6549
6550                     color0_gouraud = color0;
6551                     color1_gouraud = color1;
6552
6553                     shademode = D3DSHADE_PHONG;
6554                     break;
6555                 case D3DSHADE_PHONG:
6556                     /* Should be the same as GOURAUD, since no hardware implements this */
6557                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6558                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6559                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6560                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6561
6562                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6563                             color0_gouraud, color0);
6564                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6565                             color1_gouraud, color1);
6566                     break;
6567             }
6568         }
6569         /* Now, do it all over again with a TRIANGLELIST */
6570         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6571         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6572         primtype = D3DPT_TRIANGLELIST;
6573         shademode = D3DSHADE_FLAT;
6574     }
6575
6576 bail:
6577     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6578     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6579     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6580     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6581
6582     if (vb_strip)
6583         IDirect3DVertexBuffer9_Release(vb_strip);
6584     if (vb_list)
6585         IDirect3DVertexBuffer9_Release(vb_list);
6586 }
6587
6588
6589 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
6590 {
6591     /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
6592      * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
6593      * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
6594      * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
6595      * 0.73
6596      *
6597      * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
6598      * so use shaders for this task
6599      */
6600     IDirect3DPixelShader9 *pshader;
6601     IDirect3DVertexShader9 *vshader;
6602     IDirect3D9 *d3d;
6603     DWORD vshader_code[] = {
6604         0xfffe0101,                                                             /* vs_1_1                       */
6605         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
6606         0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0   */
6607         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
6608         0x00000001, 0xc00f0001, 0xa0000000,                                     /* mov oFog, c0.x               */
6609         0x0000ffff                                                              /* end                          */
6610     };
6611     DWORD pshader_code[] = {
6612         0xffff0101,                                                             /* ps_1_1                       */
6613         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
6614         0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
6615         0x0000ffff                                                              /* end                          */
6616     };
6617     const float quad[] = {
6618        -1.0,   -1.0,    0.1,
6619         1.0,   -1.0,    0.1,
6620        -1.0,    1.0,    0.1,
6621         1.0,    1.0,    0.1
6622     };
6623     HRESULT hr;
6624     DWORD color;
6625
6626     IDirect3DDevice9_GetDirect3D(device, &d3d);
6627     /* Ask for srgb writing on D3DRTYPE_TEXTURE. Some Windows drivers do not report it on surfaces.
6628      * For some not entirely understood reasons D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE
6629      * passes on surfaces, while asking for SRGBWRITE alone fails. Textures advertize srgb writing
6630      * alone as well, so use that since it is not the point of this test to show how CheckDeviceFormat
6631      * works
6632      */
6633     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6634                                     D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
6635                                     D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK) {
6636         skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
6637         IDirect3D9_Release(d3d);
6638         return;
6639     }
6640     IDirect3D9_Release(d3d);
6641
6642     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6643     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6644
6645     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6646     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6647     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
6648     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6649     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
6650     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6651     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
6652     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6653     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
6654     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6655
6656     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6657     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6658     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
6659     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6660     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6661     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6662     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6663     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6664     hr = IDirect3DDevice9_SetPixelShader(device, pshader);
6665     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6666
6667     hr = IDirect3DDevice9_BeginScene(device);
6668     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6669     if(SUCCEEDED(hr)) {
6670         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
6671         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6672
6673         hr = IDirect3DDevice9_EndScene(device);
6674         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6675     }
6676
6677     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6678     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6679     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6680     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6681     IDirect3DPixelShader9_Release(pshader);
6682     IDirect3DVertexShader9_Release(vshader);
6683
6684     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
6685     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6686     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
6687     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6688
6689     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6690     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6691     color = getPixelColor(device, 160, 360);
6692     ok(color == 0x00808080 || color == 0x007f7f7f || color == 0x00818181,
6693        "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
6694 }
6695
6696 static void alpha_test(IDirect3DDevice9 *device)
6697 {
6698     HRESULT hr;
6699     IDirect3DTexture9 *offscreenTexture;
6700     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6701     DWORD color;
6702
6703     struct vertex quad1[] =
6704     {
6705         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
6706         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
6707         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
6708         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
6709     };
6710     struct vertex quad2[] =
6711     {
6712         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
6713         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
6714         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
6715         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
6716     };
6717     static const float composite_quad[][5] = {
6718         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6719         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
6720         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6721         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
6722     };
6723
6724     /* Clear the render target with alpha = 0.5 */
6725     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6726     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6727
6728     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6729     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6730
6731     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6732     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6733     if(!backbuffer) {
6734         goto out;
6735     }
6736
6737     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6738     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6739     if(!offscreen) {
6740         goto out;
6741     }
6742
6743     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6744     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6745
6746     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6747     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6748     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6749     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6750     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6751     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6752     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6753     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6754     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6755     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6756
6757     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6758     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6759     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6760
6761         /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6762         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6763         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6764         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6765         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6766         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6767         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6768
6769         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6770         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6771         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6772         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6773         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6774         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6775
6776         /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6777          * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6778          * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6779         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6780         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6781         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6782         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6783
6784         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6785         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6786         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6787         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6788         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6789         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6790
6791         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6792         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6793         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6794         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6795         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6796         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6797
6798         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6799         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6800
6801         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6802          * Disable alpha blending for the final composition
6803          */
6804         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6805         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6806         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6807         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6808
6809         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6810         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6811         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6812         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6813         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6814         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6815
6816         hr = IDirect3DDevice9_EndScene(device);
6817         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6818     }
6819
6820     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6821
6822     color = getPixelColor(device, 160, 360);
6823     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6824        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6825
6826     color = getPixelColor(device, 160, 120);
6827     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
6828        "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
6829
6830     color = getPixelColor(device, 480, 360);
6831     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6832        "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
6833
6834     color = getPixelColor(device, 480, 120);
6835     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
6836        "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
6837
6838     out:
6839     /* restore things */
6840     if(backbuffer) {
6841         IDirect3DSurface9_Release(backbuffer);
6842     }
6843     if(offscreenTexture) {
6844         IDirect3DTexture9_Release(offscreenTexture);
6845     }
6846     if(offscreen) {
6847         IDirect3DSurface9_Release(offscreen);
6848     }
6849 }
6850
6851 struct vertex_shortcolor {
6852     float x, y, z;
6853     unsigned short r, g, b, a;
6854 };
6855 struct vertex_floatcolor {
6856     float x, y, z;
6857     float r, g, b, a;
6858 };
6859
6860 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6861 {
6862     HRESULT hr;
6863     BOOL s_ok, ub_ok, f_ok;
6864     DWORD color, size, i;
6865     void *data;
6866     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6867         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6868         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6869         D3DDECL_END()
6870     };
6871     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6872         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6873         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6874         D3DDECL_END()
6875     };
6876     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6877         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6878         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6879         D3DDECL_END()
6880     };
6881     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6882         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6883         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6884         D3DDECL_END()
6885     };
6886     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6887         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6888         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6889         D3DDECL_END()
6890     };
6891     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6892         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6893         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6894         D3DDECL_END()
6895     };
6896     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6897         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
6898         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6899         D3DDECL_END()
6900     };
6901     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6902     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6903     IDirect3DVertexBuffer9 *vb, *vb2;
6904     struct vertex quad1[] =                             /* D3DCOLOR */
6905     {
6906         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
6907         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6908         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
6909         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6910     };
6911     struct vertex quad2[] =                             /* UBYTE4N */
6912     {
6913         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6914         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
6915         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6916         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
6917     };
6918     struct vertex_shortcolor quad3[] =                  /* short */
6919     {
6920         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6921         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6922         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6923         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6924     };
6925     struct vertex_floatcolor quad4[] =
6926     {
6927         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6928         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6929         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6930         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6931     };
6932     DWORD colors[] = {
6933         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6934         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6935         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6936         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6937         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6938         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6939         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6940         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6941         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6942         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6943         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6944         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6945         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6946         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6947         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6948         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6949     };
6950     float quads[] = {
6951         -1.0,   -1.0,     0.1,
6952         -1.0,    0.0,     0.1,
6953          0.0,   -1.0,     0.1,
6954          0.0,    0.0,     0.1,
6955
6956          0.0,   -1.0,     0.1,
6957          0.0,    0.0,     0.1,
6958          1.0,   -1.0,     0.1,
6959          1.0,    0.0,     0.1,
6960
6961          0.0,    0.0,     0.1,
6962          0.0,    1.0,     0.1,
6963          1.0,    0.0,     0.1,
6964          1.0,    1.0,     0.1,
6965
6966         -1.0,    0.0,     0.1,
6967         -1.0,    1.0,     0.1,
6968          0.0,    0.0,     0.1,
6969          0.0,    1.0,     0.1
6970     };
6971     struct tvertex quad_transformed[] = {
6972        {  90,    110,     0.1,      2.0,        0x00ffff00},
6973        { 570,    110,     0.1,      2.0,        0x00ffff00},
6974        {  90,    300,     0.1,      2.0,        0x00ffff00},
6975        { 570,    300,     0.1,      2.0,        0x00ffff00}
6976     };
6977     D3DCAPS9 caps;
6978
6979     memset(&caps, 0, sizeof(caps));
6980     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6981     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
6982
6983     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6984     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6985
6986     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
6987     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6988     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
6989     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
6990     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
6991     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6992     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
6993         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
6994         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6995         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
6996         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6997     } else {
6998         trace("D3DDTCAPS_UBYTE4N not supported\n");
6999         dcl_ubyte_2 = NULL;
7000         dcl_ubyte = NULL;
7001     }
7002     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7003     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7004     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7005     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7006
7007     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7008     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7009                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
7010     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7011
7012     hr = IDirect3DDevice9_BeginScene(device);
7013     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7014     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7015     if(SUCCEEDED(hr)) {
7016         if(dcl_color) {
7017             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7018             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7019             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7020             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7021         }
7022
7023         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7024          * accepts them, the nvidia driver accepts them all. All those differences even though we're
7025          * using software vertex processing. Doh!
7026          */
7027         if(dcl_ubyte) {
7028             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7029             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7030             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7031             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7032             ub_ok = SUCCEEDED(hr);
7033         }
7034
7035         if(dcl_short) {
7036             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7037             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7038             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7039             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7040             s_ok = SUCCEEDED(hr);
7041         }
7042
7043         if(dcl_float) {
7044             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7045             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7046             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7047             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7048             f_ok = SUCCEEDED(hr);
7049         }
7050
7051         hr = IDirect3DDevice9_EndScene(device);
7052         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7053     }
7054
7055     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7056     if(dcl_short) {
7057         color = getPixelColor(device, 480, 360);
7058         ok(color == 0x000000ff || !s_ok,
7059            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7060     }
7061     if(dcl_ubyte) {
7062         color = getPixelColor(device, 160, 120);
7063         ok(color == 0x0000ffff || !ub_ok,
7064            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7065     }
7066     if(dcl_color) {
7067         color = getPixelColor(device, 160, 360);
7068         ok(color == 0x00ffff00,
7069            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7070     }
7071     if(dcl_float) {
7072         color = getPixelColor(device, 480, 120);
7073         ok(color == 0x00ff0000 || !f_ok,
7074            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7075     }
7076
7077     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7078      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7079      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7080      * whether the immediate mode code works
7081      */
7082     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7083     hr = IDirect3DDevice9_BeginScene(device);
7084     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7085     if(SUCCEEDED(hr)) {
7086         if(dcl_color) {
7087             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), (void **) &data, 0);
7088             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7089             memcpy(data, quad1, sizeof(quad1));
7090             hr = IDirect3DVertexBuffer9_Unlock(vb);
7091             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7092             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7093             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7094             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7095             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7096             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7097             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7098         }
7099
7100         if(dcl_ubyte) {
7101             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), (void **) &data, 0);
7102             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7103             memcpy(data, quad2, sizeof(quad2));
7104             hr = IDirect3DVertexBuffer9_Unlock(vb);
7105             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7106             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7107             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7108             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7109             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7110             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7111             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7112                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7113             ub_ok = SUCCEEDED(hr);
7114         }
7115
7116         if(dcl_short) {
7117             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), (void **) &data, 0);
7118             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7119             memcpy(data, quad3, sizeof(quad3));
7120             hr = IDirect3DVertexBuffer9_Unlock(vb);
7121             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7122             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7123             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7124             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7125             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7126             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7127             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7128                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7129             s_ok = SUCCEEDED(hr);
7130         }
7131
7132         if(dcl_float) {
7133             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), (void **) &data, 0);
7134             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7135             memcpy(data, quad4, sizeof(quad4));
7136             hr = IDirect3DVertexBuffer9_Unlock(vb);
7137             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7138             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7139             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7140             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7141             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7142             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7143             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7144                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7145             f_ok = SUCCEEDED(hr);
7146         }
7147
7148         hr = IDirect3DDevice9_EndScene(device);
7149         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7150     }
7151
7152     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7153     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7154     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7155     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7156
7157     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7158     if(dcl_short) {
7159         color = getPixelColor(device, 480, 360);
7160         ok(color == 0x000000ff || !s_ok,
7161            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7162     }
7163     if(dcl_ubyte) {
7164         color = getPixelColor(device, 160, 120);
7165         ok(color == 0x0000ffff || !ub_ok,
7166            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7167     }
7168     if(dcl_color) {
7169         color = getPixelColor(device, 160, 360);
7170         ok(color == 0x00ffff00,
7171            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7172     }
7173     if(dcl_float) {
7174         color = getPixelColor(device, 480, 120);
7175         ok(color == 0x00ff0000 || !f_ok,
7176            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7177     }
7178
7179     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7180     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7181
7182     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), (void **) &data, 0);
7183     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7184     memcpy(data, quad_transformed, sizeof(quad_transformed));
7185     hr = IDirect3DVertexBuffer9_Unlock(vb);
7186     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7187
7188     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7189     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7190
7191     hr = IDirect3DDevice9_BeginScene(device);
7192     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7193     if(SUCCEEDED(hr)) {
7194         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7195         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7196         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7197         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7198
7199         hr = IDirect3DDevice9_EndScene(device);
7200         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7201     }
7202
7203     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7204     color = getPixelColor(device, 88, 108);
7205     ok(color == 0x000000ff,
7206        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7207     color = getPixelColor(device, 92, 108);
7208     ok(color == 0x000000ff,
7209        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7210     color = getPixelColor(device, 88, 112);
7211     ok(color == 0x000000ff,
7212        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7213     color = getPixelColor(device, 92, 112);
7214     ok(color == 0x00ffff00,
7215        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7216
7217     color = getPixelColor(device, 568, 108);
7218     ok(color == 0x000000ff,
7219        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7220     color = getPixelColor(device, 572, 108);
7221     ok(color == 0x000000ff,
7222        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7223     color = getPixelColor(device, 568, 112);
7224     ok(color == 0x00ffff00,
7225        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7226     color = getPixelColor(device, 572, 112);
7227     ok(color == 0x000000ff,
7228        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7229
7230     color = getPixelColor(device, 88, 298);
7231     ok(color == 0x000000ff,
7232        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7233     color = getPixelColor(device, 92, 298);
7234     ok(color == 0x00ffff00,
7235        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7236     color = getPixelColor(device, 88, 302);
7237     ok(color == 0x000000ff,
7238        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7239     color = getPixelColor(device, 92, 302);
7240     ok(color == 0x000000ff,
7241        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7242
7243     color = getPixelColor(device, 568, 298);
7244     ok(color == 0x00ffff00,
7245        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7246     color = getPixelColor(device, 572, 298);
7247     ok(color == 0x000000ff,
7248        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7249     color = getPixelColor(device, 568, 302);
7250     ok(color == 0x000000ff,
7251        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7252     color = getPixelColor(device, 572, 302);
7253     ok(color == 0x000000ff,
7254        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7255
7256     /* This test is pointless without those two declarations: */
7257     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7258         skip("color-ubyte switching test declarations aren't supported\n");
7259         goto out;
7260     }
7261
7262     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), (void **) &data, 0);
7263     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7264     memcpy(data, quads, sizeof(quads));
7265     hr = IDirect3DVertexBuffer9_Unlock(vb);
7266     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7267     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7268                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7269     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7270     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), (void **) &data, 0);
7271     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7272     memcpy(data, colors, sizeof(colors));
7273     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7274     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7275
7276     for(i = 0; i < 2; i++) {
7277         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7278         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7279
7280         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7281         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7282         if(i == 0) {
7283             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7284         } else {
7285             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7286         }
7287         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7288
7289         hr = IDirect3DDevice9_BeginScene(device);
7290         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7291         ub_ok = FALSE;
7292         if(SUCCEEDED(hr)) {
7293             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7294             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7295             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7296             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7297                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7298             ub_ok = SUCCEEDED(hr);
7299
7300             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7301             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7302             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7303             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7304
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, 8, 2);
7308             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7309                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7310             ub_ok = (SUCCEEDED(hr) && ub_ok);
7311
7312             hr = IDirect3DDevice9_EndScene(device);
7313             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7314         }
7315
7316         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7317         if(i == 0) {
7318             color = getPixelColor(device, 480, 360);
7319             ok(color == 0x00ff0000,
7320                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7321             color = getPixelColor(device, 160, 120);
7322             ok(color == 0x00ffffff,
7323                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7324             color = getPixelColor(device, 160, 360);
7325             ok(color == 0x000000ff || !ub_ok,
7326                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7327             color = getPixelColor(device, 480, 120);
7328             ok(color == 0x000000ff || !ub_ok,
7329                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7330         } else {
7331             color = getPixelColor(device, 480, 360);
7332             ok(color == 0x000000ff,
7333                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7334             color = getPixelColor(device, 160, 120);
7335             ok(color == 0x00ffffff,
7336                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7337             color = getPixelColor(device, 160, 360);
7338             ok(color == 0x00ff0000 || !ub_ok,
7339                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7340             color = getPixelColor(device, 480, 120);
7341             ok(color == 0x00ff0000 || !ub_ok,
7342                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7343         }
7344     }
7345
7346     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7347     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7348     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7349     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7350     IDirect3DVertexBuffer9_Release(vb2);
7351
7352     out:
7353     IDirect3DVertexBuffer9_Release(vb);
7354     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7355     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7356     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7357     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7358     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7359     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7360     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7361 }
7362
7363 struct vertex_float16color {
7364     float x, y, z;
7365     DWORD c1, c2;
7366 };
7367
7368 static void test_vshader_float16(IDirect3DDevice9 *device)
7369 {
7370     HRESULT hr;
7371     DWORD color;
7372     void *data;
7373     static const D3DVERTEXELEMENT9 decl_elements[] = {
7374         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7375         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7376         D3DDECL_END()
7377     };
7378     IDirect3DVertexDeclaration9 *vdecl = NULL;
7379     IDirect3DVertexBuffer9 *buffer = NULL;
7380     IDirect3DVertexShader9 *shader;
7381     DWORD shader_code[] = {
7382         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7383         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7384         0x90e40001, 0x0000ffff
7385     };
7386     struct vertex_float16color quad[] = {
7387         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7388         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7389         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7390         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7391
7392         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7393         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7394         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7395         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7396
7397         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7398         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7399         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7400         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7401
7402         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7403         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7404         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7405         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7406     };
7407
7408     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7409     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7410
7411     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7412     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7413     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7414     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7415     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7416     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7417
7418     hr = IDirect3DDevice9_BeginScene(device);
7419     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7420     if(SUCCEEDED(hr)) {
7421         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7422         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7423         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7424         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7425         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7426         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7427         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7428         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7429         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7430         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7431
7432         hr = IDirect3DDevice9_EndScene(device);
7433         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7434     }
7435     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7436     color = getPixelColor(device, 480, 360);
7437     ok(color == 0x00ff0000,
7438        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7439     color = getPixelColor(device, 160, 120);
7440     ok(color == 0x00000000,
7441        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7442     color = getPixelColor(device, 160, 360);
7443     ok(color == 0x0000ff00,
7444        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7445     color = getPixelColor(device, 480, 120);
7446     ok(color == 0x000000ff,
7447        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7448
7449     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7450     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7451
7452     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7453                                              D3DPOOL_MANAGED, &buffer, NULL);
7454     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7455     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), (void **) &data, 0);
7456     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7457     memcpy(data, quad, sizeof(quad));
7458     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7459     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7460     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7461     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7462
7463     hr = IDirect3DDevice9_BeginScene(device);
7464     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7465     if(SUCCEEDED(hr)) {
7466             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7467             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7468             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7469             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7470             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7471             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7472             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7473             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7474
7475             hr = IDirect3DDevice9_EndScene(device);
7476             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7477     }
7478
7479     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7480     color = getPixelColor(device, 480, 360);
7481     ok(color == 0x00ff0000,
7482        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7483     color = getPixelColor(device, 160, 120);
7484     ok(color == 0x00000000,
7485        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7486     color = getPixelColor(device, 160, 360);
7487     ok(color == 0x0000ff00,
7488        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7489     color = getPixelColor(device, 480, 120);
7490     ok(color == 0x000000ff,
7491        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7492
7493     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7494     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7495     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7496     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7497     IDirect3DDevice9_SetVertexShader(device, NULL);
7498     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7499
7500     IDirect3DVertexDeclaration9_Release(vdecl);
7501     IDirect3DVertexShader9_Release(shader);
7502     IDirect3DVertexBuffer9_Release(buffer);
7503 }
7504
7505 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7506 {
7507     D3DCAPS9 caps;
7508     IDirect3DTexture9 *texture;
7509     HRESULT hr;
7510     D3DLOCKED_RECT rect;
7511     unsigned int x, y;
7512     DWORD *dst, color;
7513     const float quad[] = {
7514         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
7515          1.0,   -1.0,   0.1,    1.2,   -0.2,
7516         -1.0,    1.0,   0.1,   -0.2,    1.2,
7517          1.0,    1.0,   0.1,    1.2,    1.2
7518     };
7519     memset(&caps, 0, sizeof(caps));
7520
7521     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7522     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7523     if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7524         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7525         ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7526            "Card has conditional NP2 support without power of two restriction set\n");
7527         skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7528         return;
7529     } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7530         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7531         return;
7532     }
7533
7534     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7535     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7536
7537     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7538     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7539
7540     memset(&rect, 0, sizeof(rect));
7541     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7542     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7543     for(y = 0; y < 10; y++) {
7544         for(x = 0; x < 10; x++) {
7545             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7546             if(x == 0 || x == 9 || y == 0 || y == 9) {
7547                 *dst = 0x00ff0000;
7548             } else {
7549                 *dst = 0x000000ff;
7550             }
7551         }
7552     }
7553     hr = IDirect3DTexture9_UnlockRect(texture, 0);
7554     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7555
7556     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7557     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7558     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7559     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7560     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7561     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7562     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7563     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7564
7565     hr = IDirect3DDevice9_BeginScene(device);
7566     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7567     if(SUCCEEDED(hr)) {
7568         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7569         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7570
7571         hr = IDirect3DDevice9_EndScene(device);
7572         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7573     }
7574
7575     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7576
7577     color = getPixelColor(device,    1,  1);
7578     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
7579     color = getPixelColor(device, 639, 479);
7580     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7581
7582     color = getPixelColor(device, 135, 101);
7583     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7584     color = getPixelColor(device, 140, 101);
7585     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7586     color = getPixelColor(device, 135, 105);
7587     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7588     color = getPixelColor(device, 140, 105);
7589     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7590
7591     color = getPixelColor(device, 135, 376);
7592     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7593     color = getPixelColor(device, 140, 376);
7594     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7595     color = getPixelColor(device, 135, 379);
7596     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7597     color = getPixelColor(device, 140, 379);
7598     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7599
7600     color = getPixelColor(device, 500, 101);
7601     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7602     color = getPixelColor(device, 504, 101);
7603     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7604     color = getPixelColor(device, 500, 105);
7605     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7606     color = getPixelColor(device, 504, 105);
7607     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7608
7609     color = getPixelColor(device, 500, 376);
7610     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7611     color = getPixelColor(device, 504, 376);
7612     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7613     color = getPixelColor(device, 500, 380);
7614     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7615     color = getPixelColor(device, 504, 380);
7616     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7617
7618     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7619     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7620     IDirect3DTexture9_Release(texture);
7621 }
7622
7623 static void vFace_register_test(IDirect3DDevice9 *device)
7624 {
7625     HRESULT hr;
7626     DWORD color;
7627     const DWORD shader_code[] = {
7628         0xffff0300,                                                             /* ps_3_0                     */
7629         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7630         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7631         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
7632         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
7633         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
7634         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
7635         0x0000ffff                                                              /* END                        */
7636     };
7637     IDirect3DPixelShader9 *shader;
7638     IDirect3DTexture9 *texture;
7639     IDirect3DSurface9 *surface, *backbuffer;
7640     const float quad[] = {
7641         -1.0,   -1.0,   0.1,
7642          1.0,   -1.0,   0.1,
7643         -1.0,    0.0,   0.1,
7644
7645          1.0,   -1.0,   0.1,
7646          1.0,    0.0,   0.1,
7647         -1.0,    0.0,   0.1,
7648
7649         -1.0,    0.0,   0.1,
7650         -1.0,    1.0,   0.1,
7651          1.0,    0.0,   0.1,
7652
7653          1.0,    0.0,   0.1,
7654         -1.0,    1.0,   0.1,
7655          1.0,    1.0,   0.1,
7656     };
7657     const float blit[] = {
7658          0.0,   -1.0,   0.1,    0.0,    0.0,
7659          1.0,   -1.0,   0.1,    1.0,    0.0,
7660          0.0,    1.0,   0.1,    0.0,    1.0,
7661          1.0,    1.0,   0.1,    1.0,    1.0,
7662     };
7663
7664     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7665     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7666     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7667     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7668     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7669     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7670     hr = IDirect3DDevice9_SetPixelShader(device, shader);
7671     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7672     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7673     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7674     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7675     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7676
7677     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7678     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7679
7680     hr = IDirect3DDevice9_BeginScene(device);
7681     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7682     if(SUCCEEDED(hr)) {
7683         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7684         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7685         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7686         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7687         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7688         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7689         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7690         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7691         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7692         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7693         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7694
7695         /* Blit the texture onto the back buffer to make it visible */
7696         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7697         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7698         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7699         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7700         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7701         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7702         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7703         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7704         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7705         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7706
7707         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7708         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7709
7710         hr = IDirect3DDevice9_EndScene(device);
7711         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7712     }
7713
7714     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7715     color = getPixelColor(device, 160, 360);
7716     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7717     color = getPixelColor(device, 160, 120);
7718     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7719     color = getPixelColor(device, 480, 360);
7720     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7721     color = getPixelColor(device, 480, 120);
7722     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7723
7724     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7725     IDirect3DDevice9_SetTexture(device, 0, NULL);
7726     IDirect3DPixelShader9_Release(shader);
7727     IDirect3DSurface9_Release(surface);
7728     IDirect3DSurface9_Release(backbuffer);
7729     IDirect3DTexture9_Release(texture);
7730 }
7731
7732 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7733 {
7734     HRESULT hr;
7735     DWORD color;
7736     int i;
7737     D3DCAPS9 caps;
7738     BOOL L6V5U5_supported = FALSE;
7739     IDirect3DTexture9 *tex1, *tex2;
7740     D3DLOCKED_RECT locked_rect;
7741
7742     static const float quad[][7] = {
7743         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7744         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7745         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7746         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7747     };
7748
7749     static const D3DVERTEXELEMENT9 decl_elements[] = {
7750         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7751         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7752         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7753         D3DDECL_END()
7754     };
7755
7756     /* use asymmetric matrix to test loading */
7757     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7758     float scale, offset;
7759
7760     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7761     IDirect3DTexture9           *texture            = NULL;
7762
7763     memset(&caps, 0, sizeof(caps));
7764     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7765     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7766     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7767         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7768         return;
7769     } else {
7770         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7771          * They report that it is not supported, but after that bump mapping works properly. So just test
7772          * if the format is generally supported, and check the BUMPENVMAP flag
7773          */
7774         IDirect3D9 *d3d9;
7775
7776         IDirect3DDevice9_GetDirect3D(device, &d3d9);
7777         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7778                                           D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
7779         L6V5U5_supported = SUCCEEDED(hr);
7780         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7781                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7782         IDirect3D9_Release(d3d9);
7783         if(FAILED(hr)) {
7784             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7785             return;
7786         }
7787     }
7788
7789     /* Generate the textures */
7790     generate_bumpmap_textures(device);
7791
7792     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7793     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7794     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7795     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7796     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7797     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7798     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7799     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7800
7801     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7802     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7803     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7804     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7805     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7806     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7807
7808     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7809     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7810     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7811     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7812     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7813     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7814
7815     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7816     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7817
7818     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7819     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7820
7821     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7822     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7823
7824
7825     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7826     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7827     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7828     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7829
7830     hr = IDirect3DDevice9_BeginScene(device);
7831     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7832
7833     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7834     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7835
7836     hr = IDirect3DDevice9_EndScene(device);
7837     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7838
7839     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7840     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7841
7842     /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
7843      * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
7844      * But since testing the color match is not the purpose of the test don't be too picky
7845      */
7846     color = getPixelColor(device, 320-32, 240);
7847     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7848     color = getPixelColor(device, 320+32, 240);
7849     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7850     color = getPixelColor(device, 320, 240-32);
7851     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7852     color = getPixelColor(device, 320, 240+32);
7853     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7854     color = getPixelColor(device, 320, 240);
7855     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7856     color = getPixelColor(device, 320+32, 240+32);
7857     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7858     color = getPixelColor(device, 320-32, 240+32);
7859     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7860     color = getPixelColor(device, 320+32, 240-32);
7861     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7862     color = getPixelColor(device, 320-32, 240-32);
7863     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7864
7865     for(i = 0; i < 2; i++) {
7866         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7867         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7868         IDirect3DTexture9_Release(texture); /* For the GetTexture */
7869         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7870         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7871         IDirect3DTexture9_Release(texture); /* To destroy it */
7872     }
7873
7874     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
7875         skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
7876         goto cleanup;
7877     }
7878     if(L6V5U5_supported == FALSE) {
7879         skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
7880         goto cleanup;
7881     }
7882
7883     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
7884     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7885     /* This test only tests the luminance part. The bumpmapping part was already tested above and
7886      * would only make this test more complicated
7887      */
7888     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
7889     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7890     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
7891     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7892
7893     memset(&locked_rect, 0, sizeof(locked_rect));
7894     hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
7895     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7896     *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
7897     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
7898     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7899
7900     memset(&locked_rect, 0, sizeof(locked_rect));
7901     hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
7902     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7903     *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
7904     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
7905     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7906
7907     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
7908     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7909     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
7910     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7911
7912     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
7913     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7914     scale = 2.0;
7915     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7916     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7917     offset = 0.1;
7918     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7919     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7920
7921     hr = IDirect3DDevice9_BeginScene(device);
7922     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7923     if(SUCCEEDED(hr)) {
7924         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7925         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7926         hr = IDirect3DDevice9_EndScene(device);
7927         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7928     }
7929
7930     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7931     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7932     color = getPixelColor(device, 320, 240);
7933     /* red:   1.0  * (0.25 * 2.0 + 0.1) = 1.0  * 0.6 = 0.6  = 0x99
7934      * green: 0.5  * (0.25 * 2.0 + 0.1) = 0.5  * 0.6 = 0.3  = 0x4c
7935      * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
7936      */
7937     ok(color_match(color, 0x00994c72, 3), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
7938
7939     /* Check a result scale factor > 1.0 */
7940     scale = 10;
7941     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7942     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7943     offset = 10;
7944     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7945     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7946
7947     hr = IDirect3DDevice9_BeginScene(device);
7948     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7949     if(SUCCEEDED(hr)) {
7950         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7951         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7952         hr = IDirect3DDevice9_EndScene(device);
7953         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7954     }
7955     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7956     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7957     color = getPixelColor(device, 320, 240);
7958     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7959
7960     /* Check clamping in the scale factor calculation */
7961     scale = 1000;
7962     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7963     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7964     offset = -1;
7965     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7966     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7967
7968     hr = IDirect3DDevice9_BeginScene(device);
7969     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7970     if(SUCCEEDED(hr)) {
7971         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7972         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7973         hr = IDirect3DDevice9_EndScene(device);
7974         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7975     }
7976     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7977     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7978     color = getPixelColor(device, 320, 240);
7979     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7980
7981     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7982     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7983     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
7984     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7985
7986     IDirect3DTexture9_Release(tex1);
7987     IDirect3DTexture9_Release(tex2);
7988
7989 cleanup:
7990     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
7991     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7992     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
7993     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7994
7995     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7996     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
7997     IDirect3DVertexDeclaration9_Release(vertex_declaration);
7998 }
7999
8000 static void stencil_cull_test(IDirect3DDevice9 *device) {
8001     HRESULT hr;
8002     IDirect3DSurface9 *depthstencil = NULL;
8003     D3DSURFACE_DESC desc;
8004     float quad1[] = {
8005         -1.0,   -1.0,   0.1,
8006          0.0,   -1.0,   0.1,
8007         -1.0,    0.0,   0.1,
8008          0.0,    0.0,   0.1,
8009     };
8010     float quad2[] = {
8011          0.0,   -1.0,   0.1,
8012          1.0,   -1.0,   0.1,
8013          0.0,    0.0,   0.1,
8014          1.0,    0.0,   0.1,
8015     };
8016     float quad3[] = {
8017         0.0,    0.0,   0.1,
8018         1.0,    0.0,   0.1,
8019         0.0,    1.0,   0.1,
8020         1.0,    1.0,   0.1,
8021     };
8022     float quad4[] = {
8023         -1.0,    0.0,   0.1,
8024          0.0,    0.0,   0.1,
8025         -1.0,    1.0,   0.1,
8026          0.0,    1.0,   0.1,
8027     };
8028     struct vertex painter[] = {
8029        {-1.0,   -1.0,   0.0,    0x00000000},
8030        { 1.0,   -1.0,   0.0,    0x00000000},
8031        {-1.0,    1.0,   0.0,    0x00000000},
8032        { 1.0,    1.0,   0.0,    0x00000000},
8033     };
8034     WORD indices_cw[]  = {0, 1, 3};
8035     WORD indices_ccw[] = {0, 2, 3};
8036     unsigned int i;
8037     DWORD color;
8038
8039     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8040     if(depthstencil == NULL) {
8041         skip("No depth stencil buffer\n");
8042         return;
8043     }
8044     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8045     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8046     IDirect3DSurface9_Release(depthstencil);
8047     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8048         skip("No 4 or 8 bit stencil surface\n");
8049         return;
8050     }
8051
8052     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8053     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8054     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8055
8056     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8057     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8058     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8059     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8060     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8061     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8062     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8063     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8064
8065     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8066     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8067     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8068     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8069     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8070     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8071
8072     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8073     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8074     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8075     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8076
8077     /* First pass: Fill the stencil buffer with some values... */
8078     hr = IDirect3DDevice9_BeginScene(device);
8079     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8080     if(SUCCEEDED(hr))
8081     {
8082         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8083         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8084         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8085                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8086         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8087                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8088
8089         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8090         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8091         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8092         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8093         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8094                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8095         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8096                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8097
8098         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8099         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8100         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8101                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8102         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8103                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8104
8105         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8106         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8107         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8108                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8109         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8110                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8111
8112         hr = IDirect3DDevice9_EndScene(device);
8113         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8114     }
8115
8116     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8117     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8118     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8119     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8120     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8121     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8122     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8123     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8124     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8125     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8126     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8127     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8128     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8129
8130     /* 2nd pass: Make the stencil values visible */
8131     hr = IDirect3DDevice9_BeginScene(device);
8132     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8133     if(SUCCEEDED(hr))
8134     {
8135         IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8136         for(i = 0; i < 16; i++) {
8137             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8138             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8139
8140             painter[0].diffuse = (i * 16); /* Creates shades of blue */
8141             painter[1].diffuse = (i * 16);
8142             painter[2].diffuse = (i * 16);
8143             painter[3].diffuse = (i * 16);
8144             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8145             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8146         }
8147         hr = IDirect3DDevice9_EndScene(device);
8148         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8149     }
8150
8151     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8152     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8153
8154     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8155     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8156
8157     color = getPixelColor(device, 160, 420);
8158     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8159     color = getPixelColor(device, 160, 300);
8160     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8161
8162     color = getPixelColor(device, 480, 420);
8163     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8164     color = getPixelColor(device, 480, 300);
8165     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8166
8167     color = getPixelColor(device, 160, 180);
8168     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8169     color = getPixelColor(device, 160, 60);
8170     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8171
8172     color = getPixelColor(device, 480, 180);
8173     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8174     color = getPixelColor(device, 480, 60);
8175     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8176 }
8177
8178 static void vpos_register_test(IDirect3DDevice9 *device)
8179 {
8180     HRESULT hr;
8181     DWORD color;
8182     const DWORD shader_code[] = {
8183     0xffff0300,                                                             /* ps_3_0                     */
8184     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8185     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8186     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8187     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8188     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8189     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8190     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8191     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8192     0x0000ffff                                                              /* end                        */
8193     };
8194     const DWORD shader_frac_code[] = {
8195     0xffff0300,                                                             /* ps_3_0                     */
8196     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8197     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8198     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8199     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8200     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8201     0x0000ffff                                                              /* end                        */
8202     };
8203     IDirect3DPixelShader9 *shader, *shader_frac;
8204     IDirect3DSurface9 *surface = NULL, *backbuffer;
8205     const float quad[] = {
8206         -1.0,   -1.0,   0.1,    0.0,    0.0,
8207          1.0,   -1.0,   0.1,    1.0,    0.0,
8208         -1.0,    1.0,   0.1,    0.0,    1.0,
8209          1.0,    1.0,   0.1,    1.0,    1.0,
8210     };
8211     D3DLOCKED_RECT lr;
8212     float constant[4] = {1.0, 0.0, 320, 240};
8213     DWORD *pos;
8214
8215     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8216     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8217     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8218     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8219     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8220     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8221     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8222     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8223     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8224     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8225     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8226     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8227
8228     hr = IDirect3DDevice9_BeginScene(device);
8229     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8230     if(SUCCEEDED(hr)) {
8231         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8232         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8233         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8234         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8235         hr = IDirect3DDevice9_EndScene(device);
8236         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8237     }
8238
8239     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8240     /* This has to be pixel exact */
8241     color = getPixelColor(device, 319, 239);
8242     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8243     color = getPixelColor(device, 320, 239);
8244     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8245     color = getPixelColor(device, 319, 240);
8246     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8247     color = getPixelColor(device, 320, 240);
8248     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8249
8250     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8251                                              &surface, NULL);
8252     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8253     hr = IDirect3DDevice9_BeginScene(device);
8254     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8255     if(SUCCEEDED(hr)) {
8256         constant[2] = 16; constant[3] = 16;
8257         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8258         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8259         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8260         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8261         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8262         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8263         hr = IDirect3DDevice9_EndScene(device);
8264         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8265     }
8266     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8267     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8268
8269     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8270     color = *pos & 0x00ffffff;
8271     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8272     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8273     color = *pos & 0x00ffffff;
8274     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8275     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8276     color = *pos & 0x00ffffff;
8277     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8278     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8279     color = *pos & 0x00ffffff;
8280     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8281
8282     hr = IDirect3DSurface9_UnlockRect(surface);
8283     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8284
8285     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8286      * have full control over the multisampling setting inside this test
8287      */
8288     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8289     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8290     hr = IDirect3DDevice9_BeginScene(device);
8291     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8292     if(SUCCEEDED(hr)) {
8293         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8294         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8295         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8296         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8297         hr = IDirect3DDevice9_EndScene(device);
8298         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8299     }
8300     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8301     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8302
8303     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8304     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8305
8306     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8307     color = *pos & 0x00ffffff;
8308     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8309
8310     hr = IDirect3DSurface9_UnlockRect(surface);
8311     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8312
8313     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8314     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8315     IDirect3DPixelShader9_Release(shader);
8316     IDirect3DPixelShader9_Release(shader_frac);
8317     if(surface) IDirect3DSurface9_Release(surface);
8318     IDirect3DSurface9_Release(backbuffer);
8319 }
8320
8321 static void pointsize_test(IDirect3DDevice9 *device)
8322 {
8323     HRESULT hr;
8324     D3DCAPS9 caps;
8325     D3DMATRIX matrix;
8326     D3DMATRIX identity;
8327     float ptsize, ptsize_orig;
8328     DWORD color;
8329
8330     const float vertices[] = {
8331         64,     64,     0.1,
8332         128,    64,     0.1,
8333         192,    64,     0.1,
8334         256,    64,     0.1,
8335         320,    64,     0.1,
8336         384,    64,     0.1
8337     };
8338
8339     /* 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 */
8340     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;
8341     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;
8342     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;
8343     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;
8344
8345     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;
8346     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;
8347     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;
8348     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;
8349
8350     memset(&caps, 0, sizeof(caps));
8351     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8352     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8353     if(caps.MaxPointSize < 32.0) {
8354         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8355         return;
8356     }
8357
8358     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8359     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8360     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8361     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8362     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8363     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8364     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8365     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8366
8367     hr = IDirect3DDevice9_BeginScene(device);
8368     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8369     if(SUCCEEDED(hr)) {
8370         ptsize = 16.0;
8371         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8372         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8373         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8374         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8375
8376         ptsize = 32.0;
8377         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8378         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8379         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8380         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8381
8382         ptsize = 31.5;
8383         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8384         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8385         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8386         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8387
8388         if(caps.MaxPointSize >= 64.0) {
8389             ptsize = 64.0;
8390             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8391             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8392             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8393             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8394
8395             ptsize = 63.75;
8396             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8397             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8398             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8399             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8400         }
8401
8402         ptsize = 1.0;
8403         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8404         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8405         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8406         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8407
8408         hr = IDirect3DDevice9_EndScene(device);
8409         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8410     }
8411     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8412     color = getPixelColor(device, 64-9, 64-9);
8413     ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
8414     color = getPixelColor(device, 64-8, 64-8);
8415     todo_wine ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
8416     color = getPixelColor(device, 64-7, 64-7);
8417     ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
8418     color = getPixelColor(device, 64+7, 64+7);
8419     ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
8420     color = getPixelColor(device, 64+8, 64+8);
8421     ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
8422     color = getPixelColor(device, 64+9, 64+9);
8423     ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
8424
8425     color = getPixelColor(device, 128-17, 64-17);
8426     ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8427     color = getPixelColor(device, 128-16, 64-16);
8428     todo_wine ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
8429     color = getPixelColor(device, 128-15, 64-15);
8430     ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8431     color = getPixelColor(device, 128+15, 64+15);
8432     ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8433     color = getPixelColor(device, 128+16, 64+16);
8434     ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8435     color = getPixelColor(device, 128+17, 64+17);
8436     ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8437
8438     color = getPixelColor(device, 192-17, 64-17);
8439     ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8440     color = getPixelColor(device, 192-16, 64-16);
8441     ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
8442     color = getPixelColor(device, 192-15, 64-15);
8443     ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8444     color = getPixelColor(device, 192+15, 64+15);
8445     ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8446     color = getPixelColor(device, 192+16, 64+16);
8447     ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8448     color = getPixelColor(device, 192+17, 64+17);
8449     ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8450
8451     if(caps.MaxPointSize >= 64.0) {
8452         color = getPixelColor(device, 256-33, 64-33);
8453         ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8454         color = getPixelColor(device, 256-32, 64-32);
8455         todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
8456         color = getPixelColor(device, 256-31, 64-31);
8457         ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8458         color = getPixelColor(device, 256+31, 64+31);
8459         ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8460         color = getPixelColor(device, 256+32, 64+32);
8461         ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8462         color = getPixelColor(device, 256+33, 64+33);
8463         ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8464
8465         color = getPixelColor(device, 384-33, 64-33);
8466         ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8467         color = getPixelColor(device, 384-32, 64-32);
8468         ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
8469         color = getPixelColor(device, 384-31, 64-31);
8470         ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8471         color = getPixelColor(device, 384+31, 64+31);
8472         ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8473         color = getPixelColor(device, 384+32, 64+32);
8474         ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8475         color = getPixelColor(device, 384+33, 64+33);
8476         ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8477     }
8478
8479     color = getPixelColor(device, 320-1, 64-1);
8480     ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
8481     color = getPixelColor(device, 320-0, 64-0);
8482     ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
8483     color = getPixelColor(device, 320+1, 64+1);
8484     ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
8485
8486     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8487     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8488     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8489     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8490 }
8491
8492 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8493 {
8494     HRESULT hr;
8495     IDirect3DPixelShader9 *ps;
8496     IDirect3DTexture9 *tex1, *tex2;
8497     IDirect3DSurface9 *surf1, *surf2, *backbuf;
8498     D3DCAPS9 caps;
8499     DWORD color;
8500     DWORD shader_code[] = {
8501     0xffff0300,                                                             /* ps_3_0             */
8502     0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
8503     0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
8504     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0        */
8505     0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1        */
8506     0x0000ffff                                                              /* END                */
8507     };
8508     float quad[] = {
8509        -1.0,   -1.0,    0.1,
8510         1.0,   -1.0,    0.1,
8511        -1.0,    1.0,    0.1,
8512         1.0,    1.0,    0.1,
8513     };
8514     float texquad[] = {
8515        -1.0,   -1.0,    0.1,    0.0,    0.0,
8516         0.0,   -1.0,    0.1,    1.0,    0.0,
8517        -1.0,    1.0,    0.1,    0.0,    1.0,
8518         0.0,    1.0,    0.1,    1.0,    1.0,
8519
8520         0.0,   -1.0,    0.1,    0.0,    0.0,
8521         1.0,   -1.0,    0.1,    1.0,    0.0,
8522         0.0,    1.0,    0.1,    0.0,    1.0,
8523         1.0,    1.0,    0.1,    1.0,    1.0,
8524     };
8525
8526     memset(&caps, 0, sizeof(caps));
8527     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8528     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8529     if(caps.NumSimultaneousRTs < 2) {
8530         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8531         return;
8532     }
8533
8534     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8535     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8536
8537     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8538     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8539     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8540     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8541     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
8542     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
8543
8544     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8545     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8546     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8547     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8548     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8549     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8550
8551     hr = IDirect3DDevice9_SetPixelShader(device, ps);
8552     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8553     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8554     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8555     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8556     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8557     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8558     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8559
8560     hr = IDirect3DDevice9_BeginScene(device);
8561     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8562     if(SUCCEEDED(hr)) {
8563         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8564         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8565
8566         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8567         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8568         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8569         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8570         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8571         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8572         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8573         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8574
8575         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8576         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8577         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8578         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8579
8580         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8581         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8582         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8583         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8584
8585         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8586         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8587
8588         hr = IDirect3DDevice9_EndScene(device);
8589         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8590     }
8591
8592     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8593     color = getPixelColor(device, 160, 240);
8594     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8595     color = getPixelColor(device, 480, 240);
8596     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8597
8598     IDirect3DPixelShader9_Release(ps);
8599     IDirect3DTexture9_Release(tex1);
8600     IDirect3DTexture9_Release(tex2);
8601     IDirect3DSurface9_Release(surf1);
8602     IDirect3DSurface9_Release(surf2);
8603     IDirect3DSurface9_Release(backbuf);
8604 }
8605
8606 struct formats {
8607     const char *fmtName;
8608     D3DFORMAT textureFormat;
8609     DWORD resultColorBlending;
8610     DWORD resultColorNoBlending;
8611 };
8612
8613 const struct formats test_formats[] = {
8614   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x00181800, 0x002010ff},
8615   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8616   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8617   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8618   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8619   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8620   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8621   { NULL, 0 }
8622 };
8623
8624 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8625 {
8626     HRESULT hr;
8627     IDirect3DTexture9 *offscreenTexture = NULL;
8628     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8629     IDirect3D9 *d3d = NULL;
8630     DWORD color;
8631     DWORD r0, g0, b0, r1, g1, b1;
8632     int fmt_index;
8633
8634     static const float quad[][5] = {
8635         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8636         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
8637         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8638         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
8639     };
8640
8641     /* Quad with R=0x10, G=0x20 */
8642     static const struct vertex quad1[] = {
8643         {-1.0f, -1.0f, 0.1f, 0x80102000},
8644         {-1.0f,  1.0f, 0.1f, 0x80102000},
8645         { 1.0f, -1.0f, 0.1f, 0x80102000},
8646         { 1.0f,  1.0f, 0.1f, 0x80102000},
8647     };
8648
8649     /* Quad with R=0x20, G=0x10 */
8650     static const struct vertex quad2[] = {
8651         {-1.0f, -1.0f, 0.1f, 0x80201000},
8652         {-1.0f,  1.0f, 0.1f, 0x80201000},
8653         { 1.0f, -1.0f, 0.1f, 0x80201000},
8654         { 1.0f,  1.0f, 0.1f, 0x80201000},
8655     };
8656
8657     IDirect3DDevice9_GetDirect3D(device, &d3d);
8658
8659     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8660     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8661     if(!backbuffer) {
8662         goto out;
8663     }
8664
8665     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8666     {
8667         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8668         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
8669            skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
8670            continue;
8671         }
8672
8673         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8674         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8675
8676         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8677         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
8678         if(!offscreenTexture) {
8679             continue;
8680         }
8681
8682         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8683         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8684         if(!offscreen) {
8685             continue;
8686         }
8687
8688         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8689         ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8690
8691         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8692         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8693         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8694         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8695         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8696         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8697         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8698         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8699         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8700         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8701
8702         /* Below we will draw two quads with different colors and try to blend them together.
8703          * The result color is compared with the expected outcome.
8704          */
8705         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8706             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8707             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8708             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8709             ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8710
8711             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8712             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8713
8714             /* Draw a quad using color 0x0010200 */
8715             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8716             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8717             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8718             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8719             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8720             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8721
8722             /* Draw a quad using color 0x0020100 */
8723             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8724             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8725             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8726             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8727             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8728             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8729
8730             /* We don't want to blend the result on the backbuffer */
8731             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8732             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8733
8734             /* Prepare rendering the 'blended' texture quad to the backbuffer */
8735             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8736             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8737             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8738             ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
8739
8740             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8741             ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8742
8743             /* This time with the texture */
8744             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8745             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
8746
8747             IDirect3DDevice9_EndScene(device);
8748         }
8749         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8750
8751
8752         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
8753             /* Compare the color of the center quad with our expectation */
8754             color = getPixelColor(device, 320, 240);
8755             r0 = (color & 0x00ff0000) >> 16;
8756             g0 = (color & 0x0000ff00) >>  8;
8757             b0 = (color & 0x000000ff) >>  0;
8758
8759             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
8760             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
8761             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
8762
8763             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
8764                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
8765                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
8766                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
8767         } else {
8768             /* No pixel shader blending is supported so expected garbage.The type of 'garbage' depends on the driver version and OS.
8769              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
8770              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
8771             color = getPixelColor(device, 320, 240);
8772             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);
8773         }
8774
8775         IDirect3DDevice9_SetTexture(device, 0, NULL);
8776         if(offscreenTexture) {
8777             IDirect3DTexture9_Release(offscreenTexture);
8778         }
8779         if(offscreen) {
8780             IDirect3DSurface9_Release(offscreen);
8781         }
8782     }
8783
8784 out:
8785     /* restore things */
8786     if(backbuffer) {
8787         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8788         IDirect3DSurface9_Release(backbuffer);
8789     }
8790 }
8791
8792 static void tssargtemp_test(IDirect3DDevice9 *device)
8793 {
8794     HRESULT hr;
8795     DWORD color;
8796     static const struct vertex quad[] = {
8797         {-1.0,     -1.0,    0.1,    0x00ff0000},
8798         { 1.0,     -1.0,    0.1,    0x00ff0000},
8799         {-1.0,      1.0,    0.1,    0x00ff0000},
8800         { 1.0,      1.0,    0.1,    0x00ff0000}
8801     };
8802     D3DCAPS9 caps;
8803
8804     memset(&caps, 0, sizeof(caps));
8805     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8806     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
8807     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
8808         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
8809         return;
8810     }
8811
8812     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
8813     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
8814
8815     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8816     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8817     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
8818     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8819
8820     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8821     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8822     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
8823     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8824     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
8825     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8826
8827     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
8828     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8829     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
8830     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8831     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
8832     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8833
8834     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8835     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8836
8837     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
8838     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8839     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8840     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
8841
8842     hr = IDirect3DDevice9_BeginScene(device);
8843     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
8844     if(SUCCEEDED(hr)) {
8845
8846         hr = IDirect3DDevice9_EndScene(device);
8847         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
8848         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8849         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
8850     }
8851     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8852     color = getPixelColor(device, 320, 240);
8853     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
8854
8855     /* Set stage 1 back to default */
8856     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
8857     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8858     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8859     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8860     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8861     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8862     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8863     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8864     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8865     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8866 }
8867
8868 struct testdata
8869 {
8870     DWORD idxVertex; /* number of instances in the first stream */
8871     DWORD idxColor; /* number of instances in the second stream */
8872     DWORD idxInstance; /* should be 1 ?? */
8873     DWORD color1; /* color 1 instance */
8874     DWORD color2; /* color 2 instance */
8875     DWORD color3; /* color 3 instance */
8876     DWORD color4; /* color 4 instance */
8877     WORD strVertex; /* specify which stream to use 0-2*/
8878     WORD strColor;
8879     WORD strInstance;
8880 };
8881
8882 static const struct testdata testcases[]=
8883 {
8884     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
8885     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
8886     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
8887     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
8888     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  4 */
8889     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
8890     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
8891     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
8892     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  8 */
8893     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  9 */
8894     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
8895     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
8896     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
8897     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
8898     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
8899 /*
8900     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
8901     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
8902 */
8903 };
8904
8905 /* Drawing Indexed Geometry with instances*/
8906 static void stream_test(IDirect3DDevice9 *device)
8907 {
8908     IDirect3DVertexBuffer9 *vb = NULL;
8909     IDirect3DVertexBuffer9 *vb2 = NULL;
8910     IDirect3DVertexBuffer9 *vb3 = NULL;
8911     IDirect3DIndexBuffer9 *ib = NULL;
8912     IDirect3DVertexDeclaration9 *pDecl = NULL;
8913     IDirect3DVertexShader9 *shader = NULL;
8914     HRESULT hr;
8915     BYTE *data;
8916     DWORD color;
8917     DWORD ind;
8918     unsigned i;
8919
8920     const DWORD shader_code[] =
8921     {
8922         0xfffe0101,                                     /* vs_1_1 */
8923         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
8924         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
8925         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
8926         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
8927         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
8928         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
8929         0x0000ffff
8930     };
8931
8932     const float quad[][3] =
8933     {
8934         {-0.5f, -0.5f,  1.1f}, /*0 */
8935         {-0.5f,  0.5f,  1.1f}, /*1 */
8936         { 0.5f, -0.5f,  1.1f}, /*2 */
8937         { 0.5f,  0.5f,  1.1f}, /*3 */
8938     };
8939
8940     const float vertcolor[][4] =
8941     {
8942         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
8943         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
8944         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
8945         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
8946     };
8947
8948     /* 4 position for 4 instances */
8949     const float instancepos[][3] =
8950     {
8951         {-0.6f,-0.6f, 0.0f},
8952         { 0.6f,-0.6f, 0.0f},
8953         { 0.6f, 0.6f, 0.0f},
8954         {-0.6f, 0.6f, 0.0f},
8955     };
8956
8957     short indices[] = {0, 1, 2, 1, 2, 3};
8958
8959     D3DVERTEXELEMENT9 decl[] =
8960     {
8961         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8962         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8963         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8964         D3DDECL_END()
8965     };
8966
8967     /* set the default value because it isn't done in wine? */
8968     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
8969     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8970
8971     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
8972     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
8973     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8974
8975     /* check wrong cases */
8976     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
8977     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8978     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8979     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
8980     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
8981     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8982     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8983     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
8984     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
8985     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8986     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8987     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
8988     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
8989     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8990     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8991     ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
8992     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
8993     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
8994     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8995     ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
8996
8997     /* set the default value back */
8998     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
8999     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9000
9001     /* create all VertexBuffers*/
9002     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9003     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9004     if(!vb) {
9005         skip("Failed to create a vertex buffer\n");
9006         return;
9007     }
9008     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9009     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9010     if(!vb2) {
9011         skip("Failed to create a vertex buffer\n");
9012         goto out;
9013     }
9014     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9015     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9016     if(!vb3) {
9017         skip("Failed to create a vertex buffer\n");
9018         goto out;
9019     }
9020
9021     /* create IndexBuffer*/
9022     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9023     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9024     if(!ib) {
9025         skip("Failed to create a index buffer\n");
9026         goto out;
9027     }
9028
9029     /* copy all Buffers (Vertex + Index)*/
9030     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9031     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9032     memcpy(data, quad, sizeof(quad));
9033     hr = IDirect3DVertexBuffer9_Unlock(vb);
9034     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9035     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9036     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9037     memcpy(data, vertcolor, sizeof(vertcolor));
9038     hr = IDirect3DVertexBuffer9_Unlock(vb2);
9039     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9040     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9041     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9042     memcpy(data, instancepos, sizeof(instancepos));
9043     hr = IDirect3DVertexBuffer9_Unlock(vb3);
9044     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9045     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9046     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9047     memcpy(data, indices, sizeof(indices));
9048     hr = IDirect3DIndexBuffer9_Unlock(ib);
9049     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9050
9051     /* create VertexShader */
9052     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9053     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9054     if(!shader) {
9055         skip("Failed to create a vetex shader\n");
9056         goto out;
9057     }
9058
9059     hr = IDirect3DDevice9_SetVertexShader(device, shader);
9060     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9061
9062     hr = IDirect3DDevice9_SetIndices(device, ib);
9063     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9064
9065     /* run all tests */
9066     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9067     {
9068         struct testdata act = testcases[i];
9069         decl[0].Stream = act.strVertex;
9070         decl[1].Stream = act.strColor;
9071         decl[2].Stream = act.strInstance;
9072         /* create VertexDeclarations */
9073         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9074         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9075
9076         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9077         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9078
9079         hr = IDirect3DDevice9_BeginScene(device);
9080         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9081         if(SUCCEEDED(hr))
9082         {
9083             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9084             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9085
9086             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9087             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9088             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9089             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9090
9091             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9092             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9093             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9094             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9095
9096             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9097             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9098             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9099             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9100
9101             /* don't know if this is right (1*3 and 4*1)*/
9102             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
9103             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9104             hr = IDirect3DDevice9_EndScene(device);
9105             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9106
9107             /* set all StreamSource && StreamSourceFreq back to default */
9108             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9109             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9110             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9111             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9112             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9113             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9114             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9115             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9116             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9117             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9118             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9119             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9120         }
9121
9122         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9123         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9124
9125         hr = IDirect3DVertexDeclaration9_Release(pDecl);
9126         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9127
9128         color = getPixelColor(device, 160, 360);
9129         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9130         color = getPixelColor(device, 480, 360);
9131         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9132         color = getPixelColor(device, 480, 120);
9133         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9134         color = getPixelColor(device, 160, 120);
9135         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9136     }
9137
9138     hr = IDirect3DDevice9_SetIndices(device, NULL);
9139     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9140
9141 out:
9142     if(vb) IDirect3DVertexBuffer9_Release(vb);
9143     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9144     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9145     if(ib)IDirect3DIndexBuffer9_Release(ib);
9146     if(shader)IDirect3DVertexShader9_Release(shader);
9147 }
9148
9149 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9150     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9151     IDirect3DTexture9 *dsttex = NULL;
9152     HRESULT hr;
9153     DWORD color;
9154     D3DRECT r1 = {0,  0,  50,  50 };
9155     D3DRECT r2 = {50, 0,  100, 50 };
9156     D3DRECT r3 = {50, 50, 100, 100};
9157     D3DRECT r4 = {0,  50,  50, 100};
9158     const float quad[] = {
9159         -1.0,   -1.0,   0.1,    0.0,    0.0,
9160          1.0,   -1.0,   0.1,    1.0,    0.0,
9161         -1.0,    1.0,   0.1,    0.0,    1.0,
9162          1.0,    1.0,   0.1,    1.0,    1.0,
9163     };
9164
9165     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9166     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9167
9168     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9169     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9170     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9171     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9172
9173     if(!src || !dsttex) {
9174         skip("One or more test resources could not be created\n");
9175         goto cleanup;
9176     }
9177
9178     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9179     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9180
9181     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9182     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9183
9184     /* Clear the StretchRect destination for debugging */
9185     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9186     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9187     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9188     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9189
9190     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9191     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9192
9193     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9194     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9195     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9196     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9197     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9198     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9199     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9200     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9201
9202     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9203      * the target -> texture GL blit path
9204      */
9205     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9206     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9207     IDirect3DSurface9_Release(dst);
9208
9209     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9210     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9211
9212     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9213     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9214     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9215     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9216     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9217     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9218     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9219     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9220
9221     hr = IDirect3DDevice9_BeginScene(device);
9222     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9223     if(SUCCEEDED(hr)) {
9224         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9225         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9226         hr = IDirect3DDevice9_EndScene(device);
9227         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9228     }
9229
9230     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9231     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9232     color = getPixelColor(device, 160, 360);
9233     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9234     color = getPixelColor(device, 480, 360);
9235     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9236     color = getPixelColor(device, 480, 120);
9237     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9238     color = getPixelColor(device, 160, 120);
9239     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9240
9241     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9242     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9243     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9244     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9245
9246 cleanup:
9247     if(src) IDirect3DSurface9_Release(src);
9248     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9249     if(dsttex) IDirect3DTexture9_Release(dsttex);
9250 }
9251
9252 static void texop_test(IDirect3DDevice9 *device)
9253 {
9254     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9255     IDirect3DTexture9 *texture = NULL;
9256     D3DLOCKED_RECT locked_rect;
9257     D3DCOLOR color;
9258     D3DCAPS9 caps;
9259     HRESULT hr;
9260     unsigned i;
9261
9262     static const struct {
9263         float x, y, z;
9264         float s, t;
9265         D3DCOLOR diffuse;
9266     } quad[] = {
9267         {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9268         {-1.0f,  1.0f, 0.1f, -1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9269         { 1.0f, -1.0f, 0.1f,  1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9270         { 1.0f,  1.0f, 0.1f,  1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9271     };
9272
9273     static const D3DVERTEXELEMENT9 decl_elements[] = {
9274         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9275         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9276         {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9277         D3DDECL_END()
9278     };
9279
9280     static const struct {
9281         D3DTEXTUREOP op;
9282         const char *name;
9283         DWORD caps_flag;
9284         D3DCOLOR result;
9285     } test_data[] = {
9286         {D3DTOP_SELECTARG1,                "SELECTARG1",                D3DTEXOPCAPS_SELECTARG1,                D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9287         {D3DTOP_SELECTARG2,                "SELECTARG2",                D3DTEXOPCAPS_SELECTARG2,                D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9288         {D3DTOP_MODULATE,                  "MODULATE",                  D3DTEXOPCAPS_MODULATE,                  D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9289         {D3DTOP_MODULATE2X,                "MODULATE2X",                D3DTEXOPCAPS_MODULATE2X,                D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9290         {D3DTOP_MODULATE4X,                "MODULATE4X",                D3DTEXOPCAPS_MODULATE4X,                D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9291         {D3DTOP_ADD,                       "ADD",                       D3DTEXOPCAPS_ADD,                       D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9292         {D3DTOP_ADDSIGNED,                 "ADDSIGNED",                 D3DTEXOPCAPS_ADDSIGNED,                 D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9293         {D3DTOP_ADDSIGNED2X,               "ADDSIGNED2X",               D3DTEXOPCAPS_ADDSIGNED2X,               D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9294         {D3DTOP_SUBTRACT,                  "SUBTRACT",                  D3DTEXOPCAPS_SUBTRACT,                  D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9295         {D3DTOP_ADDSMOOTH,                 "ADDSMOOTH",                 D3DTEXOPCAPS_ADDSMOOTH,                 D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9296         {D3DTOP_BLENDDIFFUSEALPHA,         "BLENDDIFFUSEALPHA",         D3DTEXOPCAPS_BLENDDIFFUSEALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9297         {D3DTOP_BLENDTEXTUREALPHA,         "BLENDTEXTUREALPHA",         D3DTEXOPCAPS_BLENDTEXTUREALPHA,         D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9298         {D3DTOP_BLENDFACTORALPHA,          "BLENDFACTORALPHA",          D3DTEXOPCAPS_BLENDFACTORALPHA,          D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9299         {D3DTOP_BLENDTEXTUREALPHAPM,       "BLENDTEXTUREALPHAPM",       D3DTEXOPCAPS_BLENDTEXTUREALPHAPM,       D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9300         {D3DTOP_BLENDCURRENTALPHA,         "BLENDCURRENTALPHA",         D3DTEXOPCAPS_BLENDCURRENTALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9301         {D3DTOP_MODULATEALPHA_ADDCOLOR,    "MODULATEALPHA_ADDCOLOR",    D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR,    D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9302         {D3DTOP_MODULATECOLOR_ADDALPHA,    "MODULATECOLOR_ADDALPHA",    D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA,    D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9303         {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9304         {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9305         /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9306         {D3DTOP_DOTPRODUCT3,               "DOTPRODUCT2",               D3DTEXOPCAPS_DOTPRODUCT3,               D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9307         {D3DTOP_MULTIPLYADD,               "MULTIPLYADD",               D3DTEXOPCAPS_MULTIPLYADD,               D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9308         {D3DTOP_LERP,                      "LERP",                      D3DTEXOPCAPS_LERP,                      D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9309     };
9310
9311     memset(&caps, 0, sizeof(caps));
9312     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9313     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9314
9315     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9316     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9317     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9318     ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9319
9320     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9321     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9322     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9323     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9324     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9325     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9326     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9327     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9328     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9329
9330     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9331     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9332     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9333     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9334     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9335     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9336
9337     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9338     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9339
9340     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9341     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9342     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9343     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9344     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9345     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9346
9347     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9348     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9349
9350     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9351     {
9352         if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9353         {
9354             skip("tex operation %s not supported\n", test_data[i].name);
9355             continue;
9356         }
9357
9358         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9359         ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9360
9361         hr = IDirect3DDevice9_BeginScene(device);
9362         ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9363
9364         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9365         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9366
9367         hr = IDirect3DDevice9_EndScene(device);
9368         ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9369
9370         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9371         ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9372
9373         color = getPixelColor(device, 320, 240);
9374         ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9375                 test_data[i].name, color, test_data[i].result);
9376     }
9377
9378     if (texture) IDirect3DTexture9_Release(texture);
9379     if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9380 }
9381
9382 static void yuv_color_test(IDirect3DDevice9 *device) {
9383     HRESULT hr;
9384     IDirect3DSurface9 *surface = NULL, *target = NULL;
9385     unsigned int fmt, i;
9386     D3DFORMAT format;
9387     const char *fmt_string;
9388     D3DLOCKED_RECT lr;
9389     IDirect3D9 *d3d;
9390     HRESULT color;
9391     DWORD ref_color_left, ref_color_right;
9392
9393     struct {
9394         DWORD in;           /* The input color */
9395         DWORD uyvy_left;    /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9396         DWORD uyvy_right;   /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9397         DWORD yuy2_left;    /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9398         DWORD yuy2_right;   /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9399     } test_data[] = {
9400     /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9401      * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9402      * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9403      * that
9404      */
9405       { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9406       { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9407       { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9408       { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9409       { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9410       { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9411       { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9412       { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9413       { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9414       { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9415       { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9416       { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9417       { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9418       { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9419
9420       { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9421       { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9422       { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9423       { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9424     };
9425
9426     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9427     ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9428     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9429     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9430
9431     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9432     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9433
9434     for(fmt = 0; fmt < 2; fmt++) {
9435         if(fmt == 0) {
9436             format = D3DFMT_UYVY;
9437             fmt_string = "D3DFMT_UYVY";
9438         } else {
9439             format = D3DFMT_YUY2;
9440             fmt_string = "D3DFMT_YUY2";
9441         }
9442
9443         /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9444                        * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9445                        */
9446         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9447                                         D3DRTYPE_SURFACE, format) != D3D_OK) {
9448             skip("%s is not supported\n", fmt_string);
9449             continue;
9450         }
9451
9452         /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9453         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9454         ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9455
9456         for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9457             if(fmt == 0) {
9458                 ref_color_left = test_data[i].uyvy_left;
9459                 ref_color_right = test_data[i].uyvy_right;
9460             } else {
9461                 ref_color_left = test_data[i].yuy2_left;
9462                 ref_color_right = test_data[i].yuy2_right;
9463             }
9464
9465             memset(&lr, 0, sizeof(lr));
9466             hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9467             ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9468             *((DWORD *) lr.pBits) = test_data[i].in;
9469             hr = IDirect3DSurface9_UnlockRect(surface);
9470             ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9471
9472             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9473             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9474             hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9475             ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9476             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9477             ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9478
9479             /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9480              * prevent running into precision problems, read a far left and far right pixel. In the future we may
9481              * want to add tests for the filtered pixels as well.
9482              *
9483              * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9484              * differently, so we need a max diff of 16
9485              */
9486             color = getPixelColor(device, 40, 240);
9487             ok(color_match(color, ref_color_left, 16),
9488                "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9489                test_data[i].in, color, ref_color_left, fmt_string);
9490             color = getPixelColor(device, 600, 240);
9491             ok(color_match(color, ref_color_right, 16),
9492                "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9493                test_data[i].in, color, ref_color_left, fmt_string);
9494         }
9495         IDirect3DSurface9_Release(surface);
9496     }
9497     IDirect3DSurface9_Release(target);
9498     IDirect3D9_Release(d3d);
9499 }
9500
9501 static void texop_range_test(IDirect3DDevice9 *device)
9502 {
9503     static const struct {
9504         float x, y, z;
9505         D3DCOLOR diffuse;
9506     } quad[] = {
9507         {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9508         {-1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9509         { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9510         { 1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
9511     };
9512     HRESULT hr;
9513     IDirect3DTexture9 *texture;
9514     D3DLOCKED_RECT locked_rect;
9515     D3DCAPS9 caps;
9516     DWORD color;
9517
9518     /* We need ADD and SUBTRACT operations */
9519     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9520     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9521     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
9522         skip("D3DTOP_ADD is not supported, skipping value range test\n");
9523     }
9524     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
9525         skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
9526     }
9527
9528     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9529     ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
9530     /* Stage 1: result = diffuse(=1.0) + diffuse
9531      * stage 2: result = result - tfactor(= 0.5)
9532      */
9533     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9534     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9535     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9536     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9537     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9538     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9539     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9540     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9541     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9542     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9543     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9544     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9545     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9546     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9547
9548     hr = IDirect3DDevice9_BeginScene(device);
9549     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9550     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9551     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9552     hr = IDirect3DDevice9_EndScene(device);
9553     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9554     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9555     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9556
9557     color = getPixelColor(device, 320, 240);
9558     ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
9559        color);
9560
9561     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9562     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9563     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9564     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9565     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
9566     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9567     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9568     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9569     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9570
9571     /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
9572      * stage 2: result = result + diffuse(1.0)
9573      */
9574     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9575     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9576     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9577     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9578     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9579     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9580     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9581     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9582     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9583     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9584     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9585     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9586     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9587     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9588
9589     hr = IDirect3DDevice9_BeginScene(device);
9590     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9591     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9592     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9593     hr = IDirect3DDevice9_EndScene(device);
9594     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9595     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9596     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9597
9598     color = getPixelColor(device, 320, 240);
9599     ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
9600        color);
9601
9602     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9603     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9604     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9605     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9606     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
9607     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9608     IDirect3DTexture9_Release(texture);
9609 }
9610
9611 static void alphareplicate_test(IDirect3DDevice9 *device) {
9612     struct vertex quad[] = {
9613         { -1.0,    -1.0,    0.1,    0x80ff00ff },
9614         {  1.0,    -1.0,    0.1,    0x80ff00ff },
9615         { -1.0,     1.0,    0.1,    0x80ff00ff },
9616         {  1.0,     1.0,    0.1,    0x80ff00ff },
9617     };
9618     HRESULT hr;
9619     DWORD color;
9620
9621     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9622     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9623
9624     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9625     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9626
9627     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9628     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9629     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
9630     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9631
9632     hr = IDirect3DDevice9_BeginScene(device);
9633     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9634     if(SUCCEEDED(hr)) {
9635         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9636         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9637         hr = IDirect3DDevice9_EndScene(device);
9638         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9639     }
9640
9641     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9642     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9643
9644     color = getPixelColor(device, 320, 240);
9645     ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
9646        color);
9647
9648     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9649     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9650
9651 }
9652
9653 static void dp3_alpha_test(IDirect3DDevice9 *device) {
9654     HRESULT hr;
9655     D3DCAPS9 caps;
9656     DWORD color;
9657     struct vertex quad[] = {
9658         { -1.0,    -1.0,    0.1,    0x408080c0 },
9659         {  1.0,    -1.0,    0.1,    0x408080c0 },
9660         { -1.0,     1.0,    0.1,    0x408080c0 },
9661         {  1.0,     1.0,    0.1,    0x408080c0 },
9662     };
9663
9664     memset(&caps, 0, sizeof(caps));
9665     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9666     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9667     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
9668         skip("D3DTOP_DOTPRODUCT3 not supported\n");
9669         return;
9670     }
9671
9672     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9673     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9674
9675     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9676     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9677
9678     /* dp3_x4 r0, diffuse_bias, tfactor_bias
9679      * mov r0.a, diffuse.a
9680      * mov r0, r0.a
9681      *
9682      * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
9683      * 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
9684      * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
9685      */
9686     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
9687     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9688     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9689     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9690     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9691     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9692     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
9693     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9694     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
9695     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9696     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9697     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9698     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
9699     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9700     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9701     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9702     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
9703     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9704
9705     hr = IDirect3DDevice9_BeginScene(device);
9706     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9707     if(SUCCEEDED(hr)) {
9708         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9709         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9710         hr = IDirect3DDevice9_EndScene(device);
9711         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9712     }
9713
9714     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9715     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9716
9717     color = getPixelColor(device, 320, 240);
9718     ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
9719        color);
9720
9721     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9722     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9723     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9724     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9725     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9726     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9727 }
9728
9729 static void zwriteenable_test(IDirect3DDevice9 *device) {
9730     HRESULT hr;
9731     DWORD color;
9732     struct vertex quad1[] = {
9733         { -1.0,  -1.0,  0.1,    0x00ff0000},
9734         { -1.0,   1.0,  0.1,    0x00ff0000},
9735         {  1.0,  -1.0,  0.1,    0x00ff0000},
9736         {  1.0,   1.0,  0.1,    0x00ff0000},
9737     };
9738     struct vertex quad2[] = {
9739         { -1.0,  -1.0,  0.9,    0x0000ff00},
9740         { -1.0,   1.0,  0.9,    0x0000ff00},
9741         {  1.0,  -1.0,  0.9,    0x0000ff00},
9742         {  1.0,   1.0,  0.9,    0x0000ff00},
9743     };
9744
9745     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
9746     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9747
9748     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9749     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9750     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9751     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9752     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
9753     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9754     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
9755     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9756
9757     hr = IDirect3DDevice9_BeginScene(device);
9758     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9759     if(SUCCEEDED(hr)) {
9760         /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
9761          * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
9762          * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
9763          * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
9764          * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
9765          * the screen is green, so zenable = D3DZB_FALSE and zwriteenable  = TRUE does NOT write to the z buffer.
9766          */
9767         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
9768         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9769         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
9770         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9771         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
9772         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9773
9774         hr = IDirect3DDevice9_EndScene(device);
9775         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9776     }
9777
9778     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9779     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9780     color = getPixelColor(device, 320, 240);
9781     ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
9782        color);
9783
9784     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9785     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9786 }
9787
9788 START_TEST(visual)
9789 {
9790     IDirect3DDevice9 *device_ptr;
9791     D3DCAPS9 caps;
9792     HRESULT hr;
9793     DWORD color;
9794
9795     d3d9_handle = LoadLibraryA("d3d9.dll");
9796     if (!d3d9_handle)
9797     {
9798         skip("Could not load d3d9.dll\n");
9799         return;
9800     }
9801
9802     device_ptr = init_d3d9();
9803     if (!device_ptr)
9804     {
9805         skip("Creating the device failed\n");
9806         return;
9807     }
9808
9809     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
9810
9811     /* Check for the reliability of the returned data */
9812     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9813     if(FAILED(hr))
9814     {
9815         skip("Clear failed, can't assure correctness of the test results, skipping\n");
9816         goto cleanup;
9817     }
9818     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
9819
9820     color = getPixelColor(device_ptr, 1, 1);
9821     if(color !=0x00ff0000)
9822     {
9823         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
9824         goto cleanup;
9825     }
9826
9827     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
9828     if(FAILED(hr))
9829     {
9830         skip("Clear failed, can't assure correctness of the test results, skipping\n");
9831         goto cleanup;
9832     }
9833     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
9834
9835     color = getPixelColor(device_ptr, 639, 479);
9836     if(color != 0x0000ddee)
9837     {
9838         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
9839         goto cleanup;
9840     }
9841
9842     /* Now execute the real tests */
9843     stretchrect_test(device_ptr);
9844     lighting_test(device_ptr);
9845     clear_test(device_ptr);
9846     fog_test(device_ptr);
9847     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
9848     {
9849         test_cube_wrap(device_ptr);
9850     } else {
9851         skip("No cube texture support\n");
9852     }
9853     z_range_test(device_ptr);
9854     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
9855     {
9856         maxmip_test(device_ptr);
9857     }
9858     else
9859     {
9860         skip("No mipmap support\n");
9861     }
9862     offscreen_test(device_ptr);
9863     alpha_test(device_ptr);
9864     shademode_test(device_ptr);
9865     srgbtexture_test(device_ptr);
9866     release_buffer_test(device_ptr);
9867     float_texture_test(device_ptr);
9868     g16r16_texture_test(device_ptr);
9869     pixelshader_blending_test(device_ptr);
9870     texture_transform_flags_test(device_ptr);
9871     autogen_mipmap_test(device_ptr);
9872     fixed_function_decl_test(device_ptr);
9873     conditional_np2_repeat_test(device_ptr);
9874     fixed_function_bumpmap_test(device_ptr);
9875     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
9876         stencil_cull_test(device_ptr);
9877     } else {
9878         skip("No two sided stencil support\n");
9879     }
9880     pointsize_test(device_ptr);
9881     tssargtemp_test(device_ptr);
9882     np2_stretch_rect_test(device_ptr);
9883     yuv_color_test(device_ptr);
9884     zwriteenable_test(device_ptr);
9885
9886     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
9887     {
9888         test_constant_clamp_vs(device_ptr);
9889         test_compare_instructions(device_ptr);
9890     }
9891     else skip("No vs_1_1 support\n");
9892
9893     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
9894     {
9895         test_mova(device_ptr);
9896         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
9897             test_vshader_input(device_ptr);
9898             test_vshader_float16(device_ptr);
9899             stream_test(device_ptr);
9900         } else {
9901             skip("No vs_3_0 support\n");
9902         }
9903     }
9904     else skip("No vs_2_0 support\n");
9905
9906     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9907     {
9908         fog_with_shader_test(device_ptr);
9909         fog_srgbwrite_test(device_ptr);
9910     }
9911     else skip("No vs_1_1 and ps_1_1 support\n");
9912
9913     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9914     {
9915         texbem_test(device_ptr);
9916         texdepth_test(device_ptr);
9917         texkill_test(device_ptr);
9918         x8l8v8u8_test(device_ptr);
9919         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
9920             constant_clamp_ps_test(device_ptr);
9921             cnd_test(device_ptr);
9922             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
9923                 dp2add_ps_test(device_ptr);
9924                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
9925                     nested_loop_test(device_ptr);
9926                     fixed_function_varying_test(device_ptr);
9927                     vFace_register_test(device_ptr);
9928                     vpos_register_test(device_ptr);
9929                     multiple_rendertargets_test(device_ptr);
9930                     if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
9931                         vshader_version_varying_test(device_ptr);
9932                         pshader_version_varying_test(device_ptr);
9933                     } else {
9934                         skip("No vs_3_0 support\n");
9935                     }
9936                 } else {
9937                     skip("No ps_3_0 support\n");
9938                 }
9939             } else {
9940                 skip("No ps_2_0 support\n");
9941             }
9942         }
9943     }
9944     else skip("No ps_1_1 support\n");
9945
9946     texop_test(device_ptr);
9947     texop_range_test(device_ptr);
9948     alphareplicate_test(device_ptr);
9949     dp3_alpha_test(device_ptr);
9950
9951 cleanup:
9952     if(device_ptr) {
9953         ULONG ref;
9954
9955         D3DPRESENT_PARAMETERS present_parameters;
9956         IDirect3DSwapChain9 *swapchain;
9957         IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
9958         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
9959         IDirect3DSwapChain9_Release(swapchain);
9960         ref = IDirect3DDevice9_Release(device_ptr);
9961         DestroyWindow(present_parameters.hDeviceWindow);
9962         ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
9963     }
9964 }