hlink/tests: Comment out a test for an uninitialized return value.
[wine] / dlls / d3d9 / tests / visual.c
1 /*
2  * Copyright 2005, 2007-2008 Henri Verbeet
3  * Copyright (C) 2007-2008 Stefan Dösinger(for CodeWeavers)
4  * Copyright (C) 2008 Jason Green(for TransGaming)
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 /* This test framework allows limited testing of rendering results. Things are rendered, shown on
22  * the framebuffer, read back from there and compared to expected colors.
23  *
24  * However, neither d3d nor opengl is guaranteed to be pixel exact, and thus the capability of this test
25  * is rather limited. As a general guideline for adding tests, do not rely on corner pixels. Draw a big enough
26  * area which shows specific behavior(like a quad on the whole screen), and try to get resulting colors with
27  * all bits set or unset in all channels(like pure red, green, blue, white, black). Hopefully everything that
28  * causes visible results in games can be tested in a way that does not depend on pixel exactness
29  */
30
31 #define COBJMACROS
32 #include <d3d9.h>
33 #include "wine/test.h"
34
35 static HMODULE d3d9_handle = 0;
36
37 static HWND create_window(void)
38 {
39     WNDCLASS wc = {0};
40     HWND ret;
41     wc.lpfnWndProc = DefWindowProc;
42     wc.lpszClassName = "d3d9_test_wc";
43     RegisterClass(&wc);
44
45     ret = CreateWindow("d3d9_test_wc", "d3d9_test",
46                         WS_SYSMENU | WS_POPUP , 0, 0, 640, 480, 0, 0, 0, 0);
47     ShowWindow(ret, SW_SHOW);
48     return ret;
49 }
50
51 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
52 {
53     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
54     c1 >>= 8; c2 >>= 8;
55     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
56     c1 >>= 8; c2 >>= 8;
57     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
58     c1 >>= 8; c2 >>= 8;
59     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
60     return TRUE;
61 }
62
63 /* Locks a given surface and returns the color at (x,y).  It's the caller's
64  * responsibility to only pass in lockable surfaces and valid x,y coordinates */
65 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
66 {
67     DWORD color;
68     HRESULT hr;
69     D3DSURFACE_DESC desc;
70     RECT rectToLock = {x, y, x+1, y+1};
71     D3DLOCKED_RECT lockedRect;
72
73     hr = IDirect3DSurface9_GetDesc(surface, &desc);
74     if(FAILED(hr))  /* This is not a test */
75     {
76         trace("Can't get the surface description, hr=%08x\n", hr);
77         return 0xdeadbeef;
78     }
79
80     hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
81     if(FAILED(hr))  /* This is not a test */
82     {
83         trace("Can't lock the surface, hr=%08x\n", hr);
84         return 0xdeadbeef;
85     }
86     switch(desc.Format) {
87         case D3DFMT_A8R8G8B8:
88         {
89             color = ((DWORD *) lockedRect.pBits)[0] & 0xffffffff;
90             break;
91         }
92         default:
93             trace("Error: unknown surface format: %d\n", desc.Format);
94             color = 0xdeadbeef;
95             break;
96     }
97     hr = IDirect3DSurface9_UnlockRect(surface);
98     if(FAILED(hr))
99     {
100         trace("Can't unlock the surface, hr=%08x\n", hr);
101     }
102     return color;
103 }
104
105 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
106 {
107     DWORD ret;
108     IDirect3DSurface9 *surf = NULL, *target = NULL;
109     HRESULT hr;
110     D3DLOCKED_RECT lockedRect;
111     RECT rectToLock = {x, y, x+1, y+1};
112
113     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8, 0, 0, TRUE, &surf, NULL);
114     if(FAILED(hr) || !surf )  /* This is not a test */
115     {
116         trace("Can't create an offscreen plain surface to read the render target data, hr=%08x\n", hr);
117         return 0xdeadbeef;
118     }
119
120     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
121     if(FAILED(hr))
122     {
123         trace("Can't get the render target, hr=%08x\n", hr);
124         ret = 0xdeadbeed;
125         goto out;
126     }
127
128     hr = IDirect3DDevice9_StretchRect(device, target, NULL, surf, NULL, D3DTEXF_POINT);
129     if(FAILED(hr))
130     {
131         trace("Can't read the render target data, hr=%08x\n", hr);
132         ret = 0xdeadbeec;
133         goto out;
134     }
135
136     hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
137     if(FAILED(hr))
138     {
139         trace("Can't lock the offscreen surface, hr=%08x\n", hr);
140         ret = 0xdeadbeeb;
141         goto out;
142     }
143
144     /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
145      * really important for these tests
146      */
147     ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
148     hr = IDirect3DSurface9_UnlockRect(surf);
149     if(FAILED(hr))
150     {
151         trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
152     }
153
154 out:
155     if(target) IDirect3DSurface9_Release(target);
156     if(surf) IDirect3DSurface9_Release(surf);
157     return ret;
158 }
159
160 static IDirect3DDevice9 *init_d3d9(void)
161 {
162     IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
163     IDirect3D9 *d3d9_ptr = 0;
164     IDirect3DDevice9 *device_ptr = 0;
165     D3DPRESENT_PARAMETERS present_parameters;
166     HRESULT hr;
167     D3DADAPTER_IDENTIFIER9 identifier;
168
169     d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
170     ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
171     if (!d3d9_create) return NULL;
172
173     d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
174     if (!d3d9_ptr)
175     {
176         skip("could not create D3D9\n");
177         return NULL;
178     }
179
180     ZeroMemory(&present_parameters, sizeof(present_parameters));
181     present_parameters.Windowed = TRUE;
182     present_parameters.hDeviceWindow = create_window();
183     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
184     present_parameters.BackBufferWidth = 640;
185     present_parameters.BackBufferHeight = 480;
186     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
187     present_parameters.EnableAutoDepthStencil = TRUE;
188     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
189
190     memset(&identifier, 0, sizeof(identifier));
191     hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
192     ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
193     trace("Driver string: \"%s\"\n", identifier.Driver);
194     trace("Description string: \"%s\"\n", identifier.Description);
195     ok(identifier.Description[0] != '\0', "Empty driver description\n");
196     trace("Device name string: \"%s\"\n", identifier.DeviceName);
197     ok(identifier.DeviceName[0]  != '\0', "Empty device name\n");
198     trace("Driver version %d.%d.%d.%d\n",
199           HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
200           HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
201
202     hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
203     if(FAILED(hr)) {
204         present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
205         hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
206         if(FAILED(hr)) {
207             hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
208         }
209     }
210     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %08x\n", hr);
211
212     return device_ptr;
213 }
214
215 struct vertex
216 {
217     float x, y, z;
218     DWORD diffuse;
219 };
220
221 struct tvertex
222 {
223     float x, y, z, rhw;
224     DWORD diffuse;
225 };
226
227 struct nvertex
228 {
229     float x, y, z;
230     float nx, ny, nz;
231     DWORD diffuse;
232 };
233
234 static void lighting_test(IDirect3DDevice9 *device)
235 {
236     HRESULT hr;
237     DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
238     DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
239     DWORD color;
240     D3DMATERIAL9 material, old_material;
241     DWORD cop, carg;
242
243     float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
244                       0.0f, 1.0f, 0.0f, 0.0f,
245                       0.0f, 0.0f, 1.0f, 0.0f,
246                       0.0f, 0.0f, 0.0f, 1.0f };
247
248     struct vertex unlitquad[] =
249     {
250         {-1.0f, -1.0f,   0.1f,                          0xffff0000},
251         {-1.0f,  0.0f,   0.1f,                          0xffff0000},
252         { 0.0f,  0.0f,   0.1f,                          0xffff0000},
253         { 0.0f, -1.0f,   0.1f,                          0xffff0000},
254     };
255     struct vertex litquad[] =
256     {
257         {-1.0f,  0.0f,   0.1f,                          0xff00ff00},
258         {-1.0f,  1.0f,   0.1f,                          0xff00ff00},
259         { 0.0f,  1.0f,   0.1f,                          0xff00ff00},
260         { 0.0f,  0.0f,   0.1f,                          0xff00ff00},
261     };
262     struct nvertex unlitnquad[] =
263     {
264         { 0.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
265         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
266         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
267         { 1.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
268     };
269     struct nvertex litnquad[] =
270     {
271         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
272         { 0.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
273         { 1.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
274         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
275     };
276     WORD Indices[] = {0, 1, 2, 2, 3, 0};
277
278     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
279     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
280
281     /* Setup some states that may cause issues */
282     hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
283     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
284     hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
285     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
286     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
287     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
288     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
289     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
290     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
291     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
292     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
293     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
294     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
295     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
296     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
297     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
298     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
299     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
300     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
301     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
302     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
303     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
304     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
305     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
306
307     hr = IDirect3DDevice9_SetFVF(device, 0);
308     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
309
310     hr = IDirect3DDevice9_SetFVF(device, fvf);
311     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
312
313     hr = IDirect3DDevice9_BeginScene(device);
314     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
315     if(hr == D3D_OK)
316     {
317         /* No lights are defined... That means, lit vertices should be entirely black */
318         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
319         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
320         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
321                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
322         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
323
324         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
325         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
326         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
327                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
328         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
329
330         hr = IDirect3DDevice9_SetFVF(device, nfvf);
331         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
332
333         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
334         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
335         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
336                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
337         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
338
339         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
340         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
341         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
342                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
343         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
344
345         IDirect3DDevice9_EndScene(device);
346         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
347     }
348
349     color = getPixelColor(device, 160, 360); /* lower left quad - unlit without normals */
350     ok(color == 0x00ff0000, "Unlit quad without normals has color %08x\n", color);
351     color = getPixelColor(device, 160, 120); /* upper left quad - lit without normals */
352     ok(color == 0x00000000, "Lit quad without normals has color %08x\n", color);
353     color = getPixelColor(device, 480, 360); /* lower left quad - unlit with normals */
354     ok(color == 0x000000ff, "Unlit quad with normals has color %08x\n", color);
355     color = getPixelColor(device, 480, 120); /* upper left quad - lit with normals */
356     ok(color == 0x00000000, "Lit quad with normals has color %08x\n", color);
357
358     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
359
360     hr = IDirect3DDevice9_GetMaterial(device, &old_material);
361     ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
362     memset(&material, 0, sizeof(material));
363     material.Diffuse.r = 0.0;
364     material.Diffuse.g = 0.0;
365     material.Diffuse.b = 0.0;
366     material.Diffuse.a = 1.0;
367     material.Ambient.r = 0.0;
368     material.Ambient.g = 0.0;
369     material.Ambient.b = 0.0;
370     material.Ambient.a = 0.0;
371     material.Specular.r = 0.0;
372     material.Specular.g = 0.0;
373     material.Specular.b = 0.0;
374     material.Specular.a = 0.0;
375     material.Emissive.r = 0.0;
376     material.Emissive.g = 0.0;
377     material.Emissive.b = 0.0;
378     material.Emissive.a = 0.0;
379     material.Power = 0.0;
380     IDirect3DDevice9_SetMaterial(device, &material);
381     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
382
383     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
384     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
385     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
386     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
387
388     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
389     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
390     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
391     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
392     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
393     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
394     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
395     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
396
397     hr = IDirect3DDevice9_BeginScene(device);
398     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
399     if(SUCCEEDED(hr)) {
400         struct vertex lighting_test[] = {
401             {-1.0,   -1.0,   0.1,    0x8000ff00},
402             { 1.0,   -1.0,   0.1,    0x80000000},
403             {-1.0,    1.0,   0.1,    0x8000ff00},
404             { 1.0,    1.0,   0.1,    0x80000000}
405         };
406         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
407         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
408         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
409         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
410
411         hr = IDirect3DDevice9_EndScene(device);
412         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
413     }
414
415     color = getPixelColor(device, 320, 240);
416     ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
417     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
418
419     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
420     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
421     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
422     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
423     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
424     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
425     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
426     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
427     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
428     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
429     hr = IDirect3DDevice9_SetMaterial(device, &old_material);
430     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
431 }
432
433 static void clear_test(IDirect3DDevice9 *device)
434 {
435     /* Tests the correctness of clearing parameters */
436     HRESULT hr;
437     D3DRECT rect[2];
438     D3DRECT rect_negneg;
439     DWORD color;
440     D3DVIEWPORT9 old_vp, vp;
441     RECT scissor;
442     DWORD oldColorWrite;
443     BOOL invalid_clear_failed = FALSE;
444
445     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
446     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
447
448     /* Positive x, negative y */
449     rect[0].x1 = 0;
450     rect[0].y1 = 480;
451     rect[0].x2 = 320;
452     rect[0].y2 = 240;
453
454     /* Positive x, positive y */
455     rect[1].x1 = 0;
456     rect[1].y1 = 0;
457     rect[1].x2 = 320;
458     rect[1].y2 = 240;
459     /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
460      * returns D3D_OK, but ignores the rectangle silently
461      */
462     hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
463     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
464     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
465
466     /* negative x, negative y */
467     rect_negneg.x1 = 640;
468     rect_negneg.y1 = 240;
469     rect_negneg.x2 = 320;
470     rect_negneg.y2 = 0;
471     hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
472     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
473     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
474
475     color = getPixelColor(device, 160, 360); /* lower left quad */
476     ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
477     color = getPixelColor(device, 160, 120); /* upper left quad */
478     if(invalid_clear_failed) {
479         /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
480         ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
481     } else {
482         /* If the negative rectangle was dropped silently, the correct ones are cleared */
483         ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
484     }
485     color = getPixelColor(device, 480, 360); /* lower right quad  */
486     ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
487     color = getPixelColor(device, 480, 120); /* upper right quad */
488     ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
489
490     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
491
492     /* Test how the viewport affects clears */
493     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
494     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
495     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
496     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
497
498     vp.X = 160;
499     vp.Y = 120;
500     vp.Width = 160;
501     vp.Height = 120;
502     vp.MinZ = 0.0;
503     vp.MaxZ = 1.0;
504     hr = IDirect3DDevice9_SetViewport(device, &vp);
505     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
506     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
507     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
508
509     vp.X = 320;
510     vp.Y = 240;
511     vp.Width = 320;
512     vp.Height = 240;
513     vp.MinZ = 0.0;
514     vp.MaxZ = 1.0;
515     hr = IDirect3DDevice9_SetViewport(device, &vp);
516     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
517     rect[0].x1 = 160;
518     rect[0].y1 = 120;
519     rect[0].x2 = 480;
520     rect[0].y2 = 360;
521     hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
522     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
523
524     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
525     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
526
527     color = getPixelColor(device, 158, 118);
528     ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
529     color = getPixelColor(device, 162, 118);
530     ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
531     color = getPixelColor(device, 158, 122);
532     ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
533     color = getPixelColor(device, 162, 122);
534     ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
535
536     color = getPixelColor(device, 318, 238);
537     ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
538     color = getPixelColor(device, 322, 238);
539     ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
540     color = getPixelColor(device, 318, 242);
541     ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
542     color = getPixelColor(device, 322, 242);
543     ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
544
545     color = getPixelColor(device, 478, 358);
546     ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
547     color = getPixelColor(device, 482, 358);
548     ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
549     color = getPixelColor(device, 478, 362);
550     ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
551     color = getPixelColor(device, 482, 362);
552     ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
553
554     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
555
556     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
557     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
558
559     scissor.left = 160;
560     scissor.right = 480;
561     scissor.top = 120;
562     scissor.bottom = 360;
563     hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
564     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
565     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
566     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
567
568     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
569     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
570     hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
571     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
572
573     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
574     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
575
576     color = getPixelColor(device, 158, 118);
577     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
578     color = getPixelColor(device, 162, 118);
579     ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
580     color = getPixelColor(device, 158, 122);
581     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
582     color = getPixelColor(device, 162, 122);
583     ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
584
585     color = getPixelColor(device, 158, 358);
586     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
587     color = getPixelColor(device, 162, 358);
588     ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
589     color = getPixelColor(device, 158, 358);
590     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
591     color = getPixelColor(device, 162, 362);
592     ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
593
594     color = getPixelColor(device, 478, 118);
595     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
596     color = getPixelColor(device, 478, 122);
597     ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
598     color = getPixelColor(device, 482, 122);
599     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
600     color = getPixelColor(device, 482, 358);
601     ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
602
603     color = getPixelColor(device, 478, 358);
604     ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
605     color = getPixelColor(device, 478, 362);
606     ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
607     color = getPixelColor(device, 482, 358);
608     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
609     color = getPixelColor(device, 482, 362);
610     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
611
612     color = getPixelColor(device, 318, 238);
613     ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
614     color = getPixelColor(device, 318, 242);
615     ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
616     color = getPixelColor(device, 322, 238);
617     ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
618     color = getPixelColor(device, 322, 242);
619     ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
620
621     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
622
623     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
624     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
625     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
626     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
627
628     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
629     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
630
631     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
632     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
633
634     /* Colorwriteenable does not affect the clear */
635     color = getPixelColor(device, 320, 240);
636     ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
637
638     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
639 }
640
641 static void color_fill_test(IDirect3DDevice9 *device)
642 {
643     HRESULT hr;
644     IDirect3DSurface9 *backbuffer = NULL;
645     IDirect3DSurface9 *rt_surface = NULL;
646     IDirect3DSurface9 *offscreen_surface = NULL;
647     DWORD fill_color, color;
648
649     /* Test ColorFill on a the backbuffer (should pass) */
650     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
651     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
652     if(backbuffer)
653     {
654         fill_color = 0x112233;
655         hr = IDirect3DDevice9_ColorFill(device, backbuffer, NULL, fill_color);
656
657         color = getPixelColor(device, 0, 0);
658         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
659
660         IDirect3DSurface9_Release(backbuffer);
661     }
662
663     /* Test ColorFill on a render target surface (should pass) */
664     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt_surface, NULL );
665     ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
666     if(rt_surface)
667     {
668         fill_color = 0x445566;
669         hr = IDirect3DDevice9_ColorFill(device, rt_surface, NULL, fill_color);
670
671         color = getPixelColorFromSurface(rt_surface, 0, 0);
672         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
673
674         IDirect3DSurface9_Release(rt_surface);
675     }
676
677     /* Test ColorFill on a offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
678     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
679             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen_surface, NULL);
680     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
681     if(offscreen_surface)
682     {
683         fill_color = 0x778899;
684         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, fill_color);
685
686         color = getPixelColorFromSurface(offscreen_surface, 0, 0);
687         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
688
689         IDirect3DSurface9_Release(offscreen_surface);
690     }
691
692     /* Try ColorFill on a offscreen surface in sysmem (should fail) */
693     offscreen_surface = NULL;
694     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
695             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &offscreen_surface, NULL);
696     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
697     if(offscreen_surface)
698     {
699         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, 0);
700         ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
701
702         IDirect3DSurface9_Release(offscreen_surface);
703     }
704 }
705
706 typedef struct {
707     float in[4];
708     DWORD out;
709 } test_data_t;
710
711 /*
712  *  c7      mova    ARGB            mov     ARGB
713  * -2.4     -2      0x00ffff00      -3      0x00ff0000
714  * -1.6     -2      0x00ffff00      -2      0x00ffff00
715  * -0.4      0      0x0000ffff      -1      0x0000ff00
716  *  0.4      0      0x0000ffff       0      0x0000ffff
717  *  1.6      2      0x00ff00ff       1      0x000000ff
718  *  2.4      2      0x00ff00ff       2      0x00ff00ff
719  */
720 static void test_mova(IDirect3DDevice9 *device)
721 {
722     static const DWORD mova_test[] = {
723         0xfffe0200,                                                             /* vs_2_0                       */
724         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
725         0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
726         0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
727         0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
728         0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
729         0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
730         0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
731         0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
732         0x0200002e, 0xb0010000, 0xa0000007,                                     /* mova a0.x, c7.x              */
733         0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000,                         /* mov oD0, c[a0.x + 3]         */
734         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
735         0x0000ffff                                                              /* END                          */
736     };
737     static const DWORD mov_test[] = {
738         0xfffe0101,                                                             /* vs_1_1                       */
739         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
740         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
741         0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
742         0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
743         0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
744         0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
745         0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
746         0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
747         0x00000001, 0xb0010000, 0xa0000007,                                     /* mov a0.x, c7.x               */
748         0x00000001, 0xd00f0000, 0xa0e42003,                                     /* mov oD0, c[a0.x + 3]         */
749         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
750         0x0000ffff                                                              /* END                          */
751     };
752
753     static const test_data_t test_data[2][6] = {
754         {
755             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
756             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
757             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
758             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
759             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
760             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
761         },
762         {
763             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
764             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
765             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
766             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
767             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
768             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
769         }
770     };
771
772     static const float quad[][3] = {
773         {-1.0f, -1.0f, 0.0f},
774         {-1.0f,  1.0f, 0.0f},
775         { 1.0f, -1.0f, 0.0f},
776         { 1.0f,  1.0f, 0.0f},
777     };
778
779     static const D3DVERTEXELEMENT9 decl_elements[] = {
780         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
781         D3DDECL_END()
782     };
783
784     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
785     IDirect3DVertexShader9 *mova_shader = NULL;
786     IDirect3DVertexShader9 *mov_shader = NULL;
787     HRESULT hr;
788     UINT i, j;
789
790     hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
791     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
792     hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
793     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
794     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
795     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
796     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
797     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
798
799     hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
800     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
801     for(j = 0; j < 2; ++j)
802     {
803         for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
804         {
805             DWORD color;
806
807             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
808             ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
809
810             hr = IDirect3DDevice9_BeginScene(device);
811             ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
812
813             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
814             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
815
816             hr = IDirect3DDevice9_EndScene(device);
817             ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
818
819             color = getPixelColor(device, 320, 240);
820             ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
821                test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
822
823             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
824             ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
825
826             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
827             ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
828         }
829         hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
830         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
831     }
832
833     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
834     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
835
836     IDirect3DVertexDeclaration9_Release(vertex_declaration);
837     IDirect3DVertexShader9_Release(mova_shader);
838     IDirect3DVertexShader9_Release(mov_shader);
839 }
840
841 struct sVertex {
842     float x, y, z;
843     DWORD diffuse;
844     DWORD specular;
845 };
846
847 struct sVertexT {
848     float x, y, z, rhw;
849     DWORD diffuse;
850     DWORD specular;
851 };
852
853 static void fog_test(IDirect3DDevice9 *device)
854 {
855     HRESULT hr;
856     D3DCOLOR color;
857     float start = 0.0f, end = 1.0f;
858     D3DCAPS9 caps;
859     int i;
860
861     /* Gets full z based fog with linear fog, no fog with specular color */
862     struct sVertex unstransformed_1[] = {
863         {-1,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
864         {-1,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
865         { 0,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
866         { 0,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
867     };
868     /* Ok, I am too lazy to deal with transform matrices */
869     struct sVertex unstransformed_2[] = {
870         {-1,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
871         {-1,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
872         { 0,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
873         { 0,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
874     };
875     /* Untransformed ones. Give them a different diffuse color to make the test look
876      * nicer. It also makes making sure that they are drawn correctly easier.
877      */
878     struct sVertexT transformed_1[] = {
879         {320,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
880         {640,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
881         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
882         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
883     };
884     struct sVertexT transformed_2[] = {
885         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
886         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
887         {640,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
888         {320,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
889     };
890     struct vertex rev_fog_quads[] = {
891        {-1.0,   -1.0,   0.1,    0x000000ff},
892        {-1.0,    0.0,   0.1,    0x000000ff},
893        { 0.0,    0.0,   0.1,    0x000000ff},
894        { 0.0,   -1.0,   0.1,    0x000000ff},
895
896        { 0.0,   -1.0,   0.9,    0x000000ff},
897        { 0.0,    0.0,   0.9,    0x000000ff},
898        { 1.0,    0.0,   0.9,    0x000000ff},
899        { 1.0,   -1.0,   0.9,    0x000000ff},
900
901        { 0.0,    0.0,   0.4,    0x000000ff},
902        { 0.0,    1.0,   0.4,    0x000000ff},
903        { 1.0,    1.0,   0.4,    0x000000ff},
904        { 1.0,    0.0,   0.4,    0x000000ff},
905
906        {-1.0,    0.0,   0.7,    0x000000ff},
907        {-1.0,    1.0,   0.7,    0x000000ff},
908        { 0.0,    1.0,   0.7,    0x000000ff},
909        { 0.0,    0.0,   0.7,    0x000000ff},
910     };
911     WORD Indices[] = {0, 1, 2, 2, 3, 0};
912
913     memset(&caps, 0, sizeof(caps));
914     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
915     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
916     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
917     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
918
919     /* Setup initial states: No lighting, fog on, fog color */
920     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
921     ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
922     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
923     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
924     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
925     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
926
927     /* First test: Both table fog and vertex fog off */
928     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
929     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
930     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
931     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
932
933     /* Start = 0, end = 1. Should be default, but set them */
934     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
935     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
936     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
937     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
938
939     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
940     {
941         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
942         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
943         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
944         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
945                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
946                                                      sizeof(unstransformed_1[0]));
947         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
948
949         /* That makes it use the Z value */
950         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
951         ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
952         /* Untransformed, vertex fog != none (or table fog != none):
953          * Use the Z value as input into the equation
954          */
955         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
956                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
957                                                      sizeof(unstransformed_1[0]));
958         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
959
960         /* transformed verts */
961         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
962         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
963         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
964         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
965                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
966                                                      sizeof(transformed_1[0]));
967         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
968
969         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
970         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
971         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
972          * equation
973          */
974         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
975                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
976                                                      sizeof(transformed_2[0]));
977         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
978
979         hr = IDirect3DDevice9_EndScene(device);
980         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
981     }
982     else
983     {
984         ok(FALSE, "BeginScene failed\n");
985     }
986
987     color = getPixelColor(device, 160, 360);
988     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
989     color = getPixelColor(device, 160, 120);
990     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
991     color = getPixelColor(device, 480, 120);
992     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
993     if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
994     {
995         color = getPixelColor(device, 480, 360);
996         ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
997     }
998     else
999     {
1000         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1001          * The settings above result in no fogging with vertex fog
1002          */
1003         color = getPixelColor(device, 480, 120);
1004         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1005         trace("Info: Table fog not supported by this device\n");
1006     }
1007     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1008
1009     /* Now test the special case fogstart == fogend */
1010     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1011     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1012
1013     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1014     {
1015         start = 512;
1016         end = 512;
1017         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1018         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1019         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1020         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1021
1022         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1023         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1024         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1025         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1026         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1027         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1028
1029         /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
1030          * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
1031          * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
1032          * The third transformed quad remains unfogged because the fogcoords are read from the specular
1033          * color and has fixed fogstart and fogend.
1034          */
1035         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1036                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
1037                 sizeof(unstransformed_1[0]));
1038         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1039         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1040                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
1041                 sizeof(unstransformed_1[0]));
1042         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1043
1044         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1045         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1046         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1047         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1048                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1049                 sizeof(transformed_1[0]));
1050         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1051
1052         hr = IDirect3DDevice9_EndScene(device);
1053         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1054     }
1055     else
1056     {
1057         ok(FALSE, "BeginScene failed\n");
1058     }
1059     color = getPixelColor(device, 160, 360);
1060     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1061     color = getPixelColor(device, 160, 120);
1062     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1063     color = getPixelColor(device, 480, 120);
1064     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1065     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1066
1067     /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1068      * but without shaders it seems to work everywhere
1069      */
1070     end = 0.2;
1071     start = 0.8;
1072     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1073     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1074     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1075     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1076     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1077     ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1078
1079     /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1080      * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1081      * so skip this for now
1082      */
1083     for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1084         const char *mode = (i ? "table" : "vertex");
1085         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1086         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1087         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1088         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1089         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1090         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1091         hr = IDirect3DDevice9_BeginScene(device);
1092         ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1093         if(SUCCEEDED(hr)) {
1094             WORD Indices2[] = { 0,  1,  2,  2,  3, 0,
1095                                 4,  5,  6,  6,  7, 4,
1096                                 8,  9, 10, 10, 11, 8,
1097                             12, 13, 14, 14, 15, 12};
1098
1099             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1100                     16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1101                     sizeof(rev_fog_quads[0]));
1102             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1103
1104             hr = IDirect3DDevice9_EndScene(device);
1105             ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1106         }
1107         color = getPixelColor(device, 160, 360);
1108         ok(color_match(color, 0x0000ff00, 1),
1109                 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1110
1111         color = getPixelColor(device, 160, 120);
1112         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1113                 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1114
1115         color = getPixelColor(device, 480, 120);
1116         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1117                 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1118
1119         color = getPixelColor(device, 480, 360);
1120         ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1121
1122         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1123
1124         if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1125             skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1126             break;
1127         }
1128     }
1129     /* Turn off the fog master switch to avoid confusing other tests */
1130     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1131     ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1132     start = 0.0;
1133     end = 1.0;
1134     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1135     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1136     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1137     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1138     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1139     ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1140     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1141     ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1142 }
1143
1144 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1145  * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1146  * regardless of the actual addressing mode set. The way this test works is
1147  * that we sample in one of the corners of the cubemap with filtering enabled,
1148  * and check the interpolated color. There are essentially two reasonable
1149  * things an implementation can do: Either pick one of the faces and
1150  * interpolate the edge texel with itself (i.e., clamp within the face), or
1151  * interpolate between the edge texels of the three involved faces. It should
1152  * never involve the border color or the other side (texcoord wrapping) of a
1153  * face in the interpolation. */
1154 static void test_cube_wrap(IDirect3DDevice9 *device)
1155 {
1156     static const float quad[][6] = {
1157         {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1158         {-1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1159         { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1160         { 1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1161     };
1162
1163     static const D3DVERTEXELEMENT9 decl_elements[] = {
1164         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1165         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1166         D3DDECL_END()
1167     };
1168
1169     static const struct {
1170         D3DTEXTUREADDRESS mode;
1171         const char *name;
1172     } address_modes[] = {
1173         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1174         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1175         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1176         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1177         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1178     };
1179
1180     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1181     IDirect3DCubeTexture9 *texture = NULL;
1182     IDirect3DSurface9 *surface = NULL;
1183     IDirect3DSurface9 *face_surface;
1184     D3DLOCKED_RECT locked_rect;
1185     HRESULT hr;
1186     UINT x;
1187     INT y, face;
1188
1189     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1190     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1191     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1192     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1193
1194     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1195             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1196     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1197
1198     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1199             D3DPOOL_DEFAULT, &texture, NULL);
1200     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1201
1202     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1203     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1204
1205     for (y = 0; y < 128; ++y)
1206     {
1207         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1208         for (x = 0; x < 64; ++x)
1209         {
1210             *ptr++ = 0xff0000ff;
1211         }
1212         for (x = 64; x < 128; ++x)
1213         {
1214             *ptr++ = 0xffff0000;
1215         }
1216     }
1217
1218     hr = IDirect3DSurface9_UnlockRect(surface);
1219     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1220
1221     hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
1222     ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1223
1224     hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1225     ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1226
1227     IDirect3DSurface9_Release(face_surface);
1228
1229     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1230     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1231
1232     for (y = 0; y < 128; ++y)
1233     {
1234         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1235         for (x = 0; x < 64; ++x)
1236         {
1237             *ptr++ = 0xffff0000;
1238         }
1239         for (x = 64; x < 128; ++x)
1240         {
1241             *ptr++ = 0xff0000ff;
1242         }
1243     }
1244
1245     hr = IDirect3DSurface9_UnlockRect(surface);
1246     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1247
1248     /* Create cube faces */
1249     for (face = 1; face < 6; ++face)
1250     {
1251         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1252         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1253
1254         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1255         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1256
1257         IDirect3DSurface9_Release(face_surface);
1258     }
1259
1260     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1261     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1262
1263     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1264     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1265     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1266     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1267     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1268     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1269
1270     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1271     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1272
1273     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1274     {
1275         DWORD color;
1276
1277         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1278         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1279         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1280         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1281
1282         hr = IDirect3DDevice9_BeginScene(device);
1283         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1284
1285         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1286         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1287
1288         hr = IDirect3DDevice9_EndScene(device);
1289         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1290
1291         color = getPixelColor(device, 320, 240);
1292         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1293                 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
1294                 color, address_modes[x].name);
1295
1296         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1297         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1298
1299         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1300         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1301     }
1302
1303     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1304     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1305
1306     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1307     IDirect3DCubeTexture9_Release(texture);
1308     IDirect3DSurface9_Release(surface);
1309 }
1310
1311 static void offscreen_test(IDirect3DDevice9 *device)
1312 {
1313     HRESULT hr;
1314     IDirect3DTexture9 *offscreenTexture = NULL;
1315     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1316     DWORD color;
1317
1318     static const float quad[][5] = {
1319         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1320         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1321         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1322         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1323     };
1324
1325     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1326     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1327
1328     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1329     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1330     if(!offscreenTexture) {
1331         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1332         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1333         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1334         if(!offscreenTexture) {
1335             skip("Cannot create an offscreen render target\n");
1336             goto out;
1337         }
1338     }
1339
1340     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1341     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1342     if(!backbuffer) {
1343         goto out;
1344     }
1345
1346     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1347     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1348     if(!offscreen) {
1349         goto out;
1350     }
1351
1352     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1353     ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1354
1355     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1356     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1357     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1358     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1359     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1360     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1361     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1362     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1363     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1364     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1365
1366     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1367         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1368         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1369         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1370         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1371
1372         /* Draw without textures - Should result in a white quad */
1373         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1374         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1375
1376         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1377         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1378         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1379         ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1380
1381         /* This time with the texture */
1382         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1383         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1384
1385         IDirect3DDevice9_EndScene(device);
1386     }
1387
1388     /* Center quad - should be white */
1389     color = getPixelColor(device, 320, 240);
1390     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1391     /* Some quad in the cleared part of the texture */
1392     color = getPixelColor(device, 170, 240);
1393     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1394     /* Part of the originally cleared back buffer */
1395     color = getPixelColor(device, 10, 10);
1396     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1397     if(0) {
1398         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1399          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1400          * the offscreen rendering mode this test would succeed or fail
1401          */
1402         color = getPixelColor(device, 10, 470);
1403         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1404     }
1405
1406     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1407
1408 out:
1409     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1410     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1411
1412     /* restore things */
1413     if(backbuffer) {
1414         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1415         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1416         IDirect3DSurface9_Release(backbuffer);
1417     }
1418     if(offscreenTexture) {
1419         IDirect3DTexture9_Release(offscreenTexture);
1420     }
1421     if(offscreen) {
1422         IDirect3DSurface9_Release(offscreen);
1423     }
1424 }
1425
1426 /* This test tests fog in combination with shaders.
1427  * What's tested: linear fog (vertex and table) with pixel shader
1428  *                linear table fog with non foggy vertex shader
1429  *                vertex fog with foggy vertex shader, non-linear
1430  *                fog with shader, non-linear fog with foggy shader,
1431  *                linear table fog with foggy shader
1432  */
1433 static void fog_with_shader_test(IDirect3DDevice9 *device)
1434 {
1435     HRESULT hr;
1436     DWORD color;
1437     union {
1438         float f;
1439         DWORD i;
1440     } start, end;
1441     unsigned int i, j;
1442
1443     /* basic vertex shader without fog computation ("non foggy") */
1444     static const DWORD vertex_shader_code1[] = {
1445         0xfffe0101,                                                             /* vs_1_1                       */
1446         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1447         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1448         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1449         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1450         0x0000ffff
1451     };
1452     /* basic vertex shader with reversed fog computation ("foggy") */
1453     static const DWORD vertex_shader_code2[] = {
1454         0xfffe0101,                                                             /* vs_1_1                        */
1455         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1456         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1457         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1458         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1459         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1460         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1461         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1462         0x0000ffff
1463     };
1464     /* basic pixel shader */
1465     static const DWORD pixel_shader_code[] = {
1466         0xffff0101,                                                             /* ps_1_1     */
1467         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, vo */
1468         0x0000ffff
1469     };
1470
1471     static struct vertex quad[] = {
1472         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1473         {-1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1474         { 1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1475         { 1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1476     };
1477
1478     static const D3DVERTEXELEMENT9 decl_elements[] = {
1479         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1480         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1481         D3DDECL_END()
1482     };
1483
1484     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1485     IDirect3DVertexShader9      *vertex_shader[3]   = {NULL, NULL, NULL};
1486     IDirect3DPixelShader9       *pixel_shader[2]    = {NULL, NULL};
1487
1488     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1489     static const struct test_data_t {
1490         int vshader;
1491         int pshader;
1492         D3DFOGMODE vfog;
1493         D3DFOGMODE tfog;
1494         unsigned int color[11];
1495     } test_data[] = {
1496         /* only pixel shader: */
1497         {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1498         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1499         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1500         {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1501         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1502         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1503         {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1504         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1505         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1506         {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1507         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1508         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1509         {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1510         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1511         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1512
1513         /* vertex shader */
1514         {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1515         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1516          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1517         {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1518         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1519         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1520         {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1521         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1522         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1523
1524         {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1525         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1526         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1527         {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1528         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1529         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1530
1531         /* vertex shader and pixel shader */
1532         /* The next 4 tests would read the fog coord output, but it isn't available.
1533          * The result is a fully fogged quad, no matter what the Z coord is. This is on
1534          * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1535          * These tests should be disabled if some other hardware behaves differently
1536          */
1537         {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1538         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1539         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1540         {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1541         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1542         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1543         {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1544         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1545         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1546         {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1547         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1548         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1549
1550         /* These use the Z coordinate with linear table fog */
1551         {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1552         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1553         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1554         {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1555         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1556         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1557         {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1558         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1559         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1560         {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1561         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1562         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1563
1564         /* Non-linear table fog without fog coord */
1565         {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1566         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1567         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1568         {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1569         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1570         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1571
1572 #if 0  /* FIXME: these fail on GeForce 8500 */
1573         /* foggy vertex shader */
1574         {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1575         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1576          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1577         {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1578         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1579          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1580         {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1581         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1582          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1583         {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1584         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1585          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1586 #endif
1587
1588         /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1589          * all using the fixed fog-coord linear fog
1590          */
1591         {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1592         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1593          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1594         {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1595         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1596          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1597         {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1598         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1599          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1600         {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1601         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1602          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1603
1604         /* These use table fog. Here the shader-provided fog coordinate is
1605          * ignored and the z coordinate used instead
1606          */
1607         {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1608         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1609         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1610         {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1611         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1612         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1613         {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1614         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1615         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1616     };
1617
1618     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1619     start.f=0.1f;
1620     end.f=0.9f;
1621
1622     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1623     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1624     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1625     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1626     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1627     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1628     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1629     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1630
1631     /* Setup initial states: No lighting, fog on, fog color */
1632     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1633     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1634     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1635     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1636     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1637     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1638     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1639     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1640
1641     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1642     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1643     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1644     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1645
1646     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1647     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1648     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1649     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1650     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1651
1652     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1653     {
1654         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1655         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1656         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1657         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1658         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1659         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1660         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1661         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1662
1663         for(j=0; j < 11; j++)
1664         {
1665             /* Don't use the whole zrange to prevent rounding errors */
1666             quad[0].z = 0.001f + (float)j / 10.02f;
1667             quad[1].z = 0.001f + (float)j / 10.02f;
1668             quad[2].z = 0.001f + (float)j / 10.02f;
1669             quad[3].z = 0.001f + (float)j / 10.02f;
1670
1671             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1672             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1673
1674             hr = IDirect3DDevice9_BeginScene(device);
1675             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1676
1677             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1678             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1679
1680             hr = IDirect3DDevice9_EndScene(device);
1681             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1682
1683             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1684             color = getPixelColor(device, 128, 240);
1685             ok(color_match(color, test_data[i].color[j], 13),
1686                 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1687                 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1688
1689             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1690         }
1691     }
1692
1693     /* reset states */
1694     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1695     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1696     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1697     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1698     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1699     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1700     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1701     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1702
1703     IDirect3DVertexShader9_Release(vertex_shader[1]);
1704     IDirect3DVertexShader9_Release(vertex_shader[2]);
1705     IDirect3DPixelShader9_Release(pixel_shader[1]);
1706     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1707 }
1708
1709 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1710     unsigned int i, x, y;
1711     HRESULT hr;
1712     IDirect3DTexture9 *texture[2] = {NULL, NULL};
1713     D3DLOCKED_RECT locked_rect;
1714
1715     /* Generate the textures */
1716     for(i=0; i<2; i++)
1717     {
1718         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1719                                             D3DPOOL_MANAGED, &texture[i], NULL);
1720         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1721
1722         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1723         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1724         for (y = 0; y < 128; ++y)
1725         {
1726             if(i)
1727             { /* Set up black texture with 2x2 texel white spot in the middle */
1728                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1729                 for (x = 0; x < 128; ++x)
1730                 {
1731                     if(y>62 && y<66 && x>62 && x<66)
1732                         *ptr++ = 0xffffffff;
1733                     else
1734                         *ptr++ = 0xff000000;
1735                 }
1736             }
1737             else
1738             { /* Set up a displacement map which points away from the center parallel to the closest axis.
1739                * (if multiplied with bumpenvmat)
1740               */
1741                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1742                 for (x = 0; x < 128; ++x)
1743                 {
1744                     if(abs(x-64)>abs(y-64))
1745                     {
1746                         if(x < 64)
1747                             *ptr++ = 0xc000;
1748                         else
1749                             *ptr++ = 0x4000;
1750                     }
1751                     else
1752                     {
1753                         if(y < 64)
1754                             *ptr++ = 0x0040;
1755                         else
1756                             *ptr++ = 0x00c0;
1757                     }
1758                 }
1759             }
1760         }
1761         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1762         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1763
1764         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1765         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1766
1767         /* Disable texture filtering */
1768         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1769         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1770         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1771         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1772
1773         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1774         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1775         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1776         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1777     }
1778 }
1779
1780 /* test the behavior of the texbem instruction
1781  * with normal 2D and projective 2D textures
1782  */
1783 static void texbem_test(IDirect3DDevice9 *device)
1784 {
1785     HRESULT hr;
1786     DWORD color;
1787     int i;
1788
1789     static const DWORD pixel_shader_code[] = {
1790         0xffff0101,                         /* ps_1_1*/
1791         0x00000042, 0xb00f0000,             /* tex t0*/
1792         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1793         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1794         0x0000ffff
1795     };
1796     static const DWORD double_texbem_code[] =  {
1797         0xffff0103,                                         /* ps_1_3           */
1798         0x00000042, 0xb00f0000,                             /* tex t0           */
1799         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
1800         0x00000042, 0xb00f0002,                             /* tex t2           */
1801         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
1802         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
1803         0x0000ffff                                          /* end              */
1804     };
1805
1806
1807     static const float quad[][7] = {
1808         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1809         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1810         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1811         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1812     };
1813     static const float quad_proj[][9] = {
1814         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
1815         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
1816         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
1817         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1818     };
1819
1820     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1821         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1822         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1823         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1824         D3DDECL_END()
1825     },{
1826         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1827         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1828         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1829         D3DDECL_END()
1830     } };
1831
1832     /* use asymmetric matrix to test loading */
1833     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1834
1835     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1836     IDirect3DPixelShader9       *pixel_shader       = NULL;
1837     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
1838     D3DLOCKED_RECT locked_rect;
1839
1840     generate_bumpmap_textures(device);
1841
1842     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1843     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1844     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1845     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1846     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1847
1848     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1849     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1850
1851     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1852     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1853
1854     for(i=0; i<2; i++)
1855     {
1856         if(i)
1857         {
1858             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1859             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1860         }
1861
1862         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1863         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1864         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1865         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1866
1867         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1868         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1869         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1870         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1871
1872         hr = IDirect3DDevice9_BeginScene(device);
1873         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1874
1875         if(!i)
1876             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1877         else
1878             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1879         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1880
1881         hr = IDirect3DDevice9_EndScene(device);
1882         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1883
1884         color = getPixelColor(device, 320-32, 240);
1885         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1886         color = getPixelColor(device, 320+32, 240);
1887         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1888         color = getPixelColor(device, 320, 240-32);
1889         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1890         color = getPixelColor(device, 320, 240+32);
1891         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1892
1893         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1894         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1895
1896         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1897         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1898         IDirect3DPixelShader9_Release(pixel_shader);
1899
1900         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1901         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1902         IDirect3DVertexDeclaration9_Release(vertex_declaration);
1903     }
1904
1905     /* clean up */
1906     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1907     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1908
1909     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1910     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1911
1912     for(i=0; i<2; i++)
1913     {
1914         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1915         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1916         IDirect3DTexture9_Release(texture); /* For the GetTexture */
1917         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1918         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1919         IDirect3DTexture9_Release(texture);
1920     }
1921
1922     /* Test double texbem */
1923     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1924     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1925     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1926     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1927     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1928     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1929     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1930     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1931
1932     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1933     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1934     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1935     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1936
1937     hr = IDirect3DTexture9_UnlockRect(texture, 0);
1938     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1939
1940     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1941     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1942     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1943     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1944     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1945     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1946
1947     {
1948         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1949 #define tex  0x00ff0000
1950 #define tex1 0x0000ff00
1951 #define origin 0x000000ff
1952         static const DWORD pixel_data[] = {
1953             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1954             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1955             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1956             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1957             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
1958             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1959             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1960             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1961         };
1962 #undef tex1
1963 #undef tex2
1964 #undef origin
1965
1966         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1967         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1968         for(i = 0; i < 8; i++) {
1969             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1970         }
1971         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1972         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1973     }
1974
1975     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1976     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1977     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1978     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1979     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1980     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1981     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1982     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1983     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1984     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1985     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1986     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1987
1988     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
1989     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
1990     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1991     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1992     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1993     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1994     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1995     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1996     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1997     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1998
1999     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
2000     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
2001     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2002     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2003     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2004     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2005     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2006     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2007     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2008     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2009
2010     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2011     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2012     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2013     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2014     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2015     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2016     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2017     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2018     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2019     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2020     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2021     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2022     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2023     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2024     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2025     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2026
2027     hr = IDirect3DDevice9_BeginScene(device);
2028     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2029     if(SUCCEEDED(hr)) {
2030         static const float double_quad[] = {
2031             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2032              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2033             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2034              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2035         };
2036
2037         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
2038         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2039         hr = IDirect3DDevice9_EndScene(device);
2040         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2041     }
2042     color = getPixelColor(device, 320, 240);
2043     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2044
2045     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2046     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2047     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
2048     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2049     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
2050     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2051     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
2052     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2053     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2054     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2055
2056     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2057     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2058
2059     IDirect3DPixelShader9_Release(pixel_shader);
2060     IDirect3DTexture9_Release(texture);
2061     IDirect3DTexture9_Release(texture1);
2062     IDirect3DTexture9_Release(texture2);
2063 }
2064
2065 static void z_range_test(IDirect3DDevice9 *device)
2066 {
2067     const struct vertex quad[] =
2068     {
2069         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
2070         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
2071         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
2072         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
2073     };
2074     const struct vertex quad2[] =
2075     {
2076         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
2077         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
2078         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
2079         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
2080     };
2081
2082     const struct tvertex quad3[] =
2083     {
2084         {    0,   240,   1.1f,  1.0,                    0xffffff00},
2085         {    0,   480,   1.1f,  1.0,                    0xffffff00},
2086         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
2087         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
2088     };
2089     const struct tvertex quad4[] =
2090     {
2091         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
2092         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
2093         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
2094         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
2095     };
2096     HRESULT hr;
2097     DWORD color;
2098     IDirect3DVertexShader9 *shader;
2099     IDirect3DVertexDeclaration9 *decl;
2100     D3DCAPS9 caps;
2101     const DWORD shader_code[] = {
2102         0xfffe0101,                                     /* vs_1_1           */
2103         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
2104         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
2105         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
2106         0x0000ffff                                      /* end              */
2107     };
2108     static const D3DVERTEXELEMENT9 decl_elements[] = {
2109         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2110         D3DDECL_END()
2111     };
2112     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2113      * then call Present. Then clear the color buffer to make sure it has some defined content
2114      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2115      * by the depth value.
2116      */
2117     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2118     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2119     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2120     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2121     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2122     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2123
2124     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2125     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2126     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2127     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2128     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2129     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2130     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2131     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2132     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2133     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2134
2135     hr = IDirect3DDevice9_BeginScene(device);
2136     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2137     if(hr == D3D_OK)
2138     {
2139         /* Test the untransformed vertex path */
2140         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2141         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2142         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2143         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2144         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2145         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2146
2147         /* Test the transformed vertex path */
2148         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2149         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2150
2151         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2152         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2153         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2154         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2155         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2156         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2157
2158         hr = IDirect3DDevice9_EndScene(device);
2159         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2160     }
2161
2162     /* Do not test the exact corner pixels, but go pretty close to them */
2163
2164     /* Clipped because z > 1.0 */
2165     color = getPixelColor(device, 28, 238);
2166     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2167     color = getPixelColor(device, 28, 241);
2168     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2169
2170     /* Not clipped, > z buffer clear value(0.75) */
2171     color = getPixelColor(device, 31, 238);
2172     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2173     color = getPixelColor(device, 31, 241);
2174     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2175     color = getPixelColor(device, 100, 238);
2176     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2177     color = getPixelColor(device, 100, 241);
2178     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2179
2180     /* Not clipped, < z buffer clear value */
2181     color = getPixelColor(device, 104, 238);
2182     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2183     color = getPixelColor(device, 104, 241);
2184     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2185     color = getPixelColor(device, 318, 238);
2186     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2187     color = getPixelColor(device, 318, 241);
2188     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2189
2190     /* Clipped because z < 0.0 */
2191     color = getPixelColor(device, 321, 238);
2192     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2193     color = getPixelColor(device, 321, 241);
2194     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2195
2196     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2197     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2198
2199     /* Test the shader path */
2200     IDirect3DDevice9_GetDeviceCaps(device, &caps);
2201     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2202         skip("Vertex shaders not supported\n");
2203         goto out;
2204     }
2205     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2206     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2207     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2208     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2209
2210     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2211
2212     IDirect3DDevice9_SetVertexDeclaration(device, decl);
2213     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2214     IDirect3DDevice9_SetVertexShader(device, shader);
2215     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2216
2217     hr = IDirect3DDevice9_BeginScene(device);
2218     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2219     if(hr == D3D_OK)
2220     {
2221         float colorf[] = {1.0, 0.0, 0.0, 1.0};
2222         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2223         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2224         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2225         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2226         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2227         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2228         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2229         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2230         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2231
2232         hr = IDirect3DDevice9_EndScene(device);
2233         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2234     }
2235
2236     IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2237     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2238     IDirect3DDevice9_SetVertexShader(device, NULL);
2239     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2240
2241     IDirect3DVertexDeclaration9_Release(decl);
2242     IDirect3DVertexShader9_Release(shader);
2243
2244     /* Z < 1.0 */
2245     color = getPixelColor(device, 28, 238);
2246     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2247
2248     /* 1.0 < z < 0.75 */
2249     color = getPixelColor(device, 31, 238);
2250     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2251     color = getPixelColor(device, 100, 238);
2252     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2253
2254     /* 0.75 < z < 0.0 */
2255     color = getPixelColor(device, 104, 238);
2256     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2257     color = getPixelColor(device, 318, 238);
2258     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2259
2260     /* 0.0 < z */
2261     color = getPixelColor(device, 321, 238);
2262     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2263
2264     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2265     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2266
2267     out:
2268     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2269     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2270     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2271     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2272     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2273     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2274 }
2275
2276 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2277 {
2278     D3DSURFACE_DESC desc;
2279     D3DLOCKED_RECT l;
2280     HRESULT hr;
2281     unsigned int x, y;
2282     DWORD *mem;
2283
2284     memset(&desc, 0, sizeof(desc));
2285     memset(&l, 0, sizeof(l));
2286     hr = IDirect3DSurface9_GetDesc(surface, &desc);
2287     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2288     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2289     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2290     if(FAILED(hr)) return;
2291
2292     for(y = 0; y < desc.Height; y++)
2293     {
2294         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2295         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2296         {
2297             mem[x] = color;
2298         }
2299     }
2300     hr = IDirect3DSurface9_UnlockRect(surface);
2301     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2302 }
2303
2304 /* This tests a variety of possible StretchRect() situations */
2305 static void stretchrect_test(IDirect3DDevice9 *device)
2306 {
2307     HRESULT hr;
2308     IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL, *tex_rt_dest640_480 = NULL;
2309     IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL, *surf_tex_rt_dest640_480 = NULL;
2310     IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2311     IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2312     IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2313     IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2314     IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2315     IDirect3DSurface9 *orig_rt = NULL;
2316     IDirect3DSurface9 *backbuffer = NULL;
2317     DWORD color;
2318
2319     RECT src_rect64 = {0, 0, 64, 64};
2320     RECT src_rect64_flipy = {0, 64, 64, 0};
2321     RECT dst_rect64 = {0, 0, 64, 64};
2322     RECT dst_rect64_flipy = {0, 64, 64, 0};
2323
2324     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2325     ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2326     if(!orig_rt) {
2327         goto out;
2328     }
2329
2330     /* Create our temporary surfaces in system memory */
2331     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2332     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2333     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2334     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2335
2336     /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2337     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2338     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2339     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2340     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2341     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2342     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2343
2344     /* Create render target surfaces */
2345     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2346     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2347     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2348     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2349     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2350     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2351     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2352     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2353
2354     /* Create render target textures */
2355     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2356     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2357     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2358     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2359     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2360     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2361     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
2362     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2363     if (tex_rt32) {
2364         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2365         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2366     }
2367     if (tex_rt64) {
2368         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2369         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2370     }
2371     if (tex_rt_dest64) {
2372         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2373         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2374     }
2375     if (tex_rt_dest64) {
2376         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
2377         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2378     }
2379
2380     /* Create regular textures in D3DPOOL_DEFAULT */
2381     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2382     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2383     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2384     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2385     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2386     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2387     if (tex32) {
2388         hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2389         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2390     }
2391     if (tex64) {
2392         hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2393         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2394     }
2395     if (tex_dest64) {
2396         hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2397         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2398     }
2399
2400     /*********************************************************************
2401      * Tests for when the source parameter is an offscreen plain surface *
2402      *********************************************************************/
2403
2404     /* Fill the offscreen 64x64 surface with green */
2405     if (surf_offscreen64)
2406         fill_surface(surf_offscreen64, 0xff00ff00);
2407
2408     /* offscreenplain ==> offscreenplain, same size */
2409     if(surf_offscreen64 && surf_offscreen_dest64) {
2410         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2411         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2412
2413         if (hr == D3D_OK) {
2414             color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2415             ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2416         }
2417
2418         /* Blit without scaling */
2419         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64, 0);
2420         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2421
2422         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2423         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_offscreen_dest64, &dst_rect64, 0);
2424         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2425
2426         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2427         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64_flipy, 0);
2428         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2429     }
2430
2431     /* offscreenplain ==> rendertarget texture, same size */
2432     if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2433         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2434         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2435
2436         /* We can't lock rendertarget textures, so copy to our temp surface first */
2437         if (hr == D3D_OK) {
2438             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2439             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2440         }
2441
2442         if (hr == D3D_OK) {
2443             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2444             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2445         }
2446
2447         /* Blit without scaling */
2448         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2449         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2450
2451         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2452         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2453         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2454
2455         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2456         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2457         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2458     }
2459
2460     /* offscreenplain ==> rendertarget surface, same size */
2461     if(surf_offscreen64 && surf_rt_dest64) {
2462         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2463         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2464
2465         if (hr == D3D_OK) {
2466             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2467             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2468         }
2469
2470         /* Blit without scaling */
2471         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2472         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2473
2474         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2475         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2476         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2477
2478         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2479         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2480         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2481     }
2482
2483     /* offscreenplain ==> texture, same size (should fail) */
2484     if(surf_offscreen64 && surf_tex_dest64) {
2485         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2486         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2487     }
2488
2489     /* Fill the smaller offscreen surface with red */
2490     fill_surface(surf_offscreen32, 0xffff0000);
2491
2492     /* offscreenplain ==> offscreenplain, scaling (should fail) */
2493     if(surf_offscreen32 && surf_offscreen64) {
2494         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2495         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2496     }
2497
2498     /* offscreenplain ==> rendertarget texture, scaling */
2499     if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2500         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2501         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2502
2503         /* We can't lock rendertarget textures, so copy to our temp surface first */
2504         if (hr == D3D_OK) {
2505             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2506             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2507         }
2508
2509         if (hr == D3D_OK) {
2510             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2511             ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2512         }
2513     }
2514
2515     /* offscreenplain ==> rendertarget surface, scaling */
2516     if(surf_offscreen32 && surf_rt_dest64) {
2517         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2518         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2519
2520         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2521         ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2522     }
2523
2524     /* offscreenplain ==> texture, scaling (should fail) */
2525     if(surf_offscreen32 && surf_tex_dest64) {
2526         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2527         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2528     }
2529
2530     /************************************************************
2531      * Tests for when the source parameter is a regular texture *
2532      ************************************************************/
2533
2534     /* Fill the surface of the regular texture with blue */
2535     if (surf_tex64 && surf_temp64) {
2536         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2537         fill_surface(surf_temp64, 0xff0000ff);
2538         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2539         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2540     }
2541
2542     /* texture ==> offscreenplain, same size */
2543     if(surf_tex64 && surf_offscreen64) {
2544         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2545         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2546     }
2547
2548     /* texture ==> rendertarget texture, same size */
2549     if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2550         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2551         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2552
2553         /* We can't lock rendertarget textures, so copy to our temp surface first */
2554         if (hr == D3D_OK) {
2555             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2556             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2557         }
2558
2559         if (hr == D3D_OK) {
2560             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2561             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2562         }
2563
2564         /* Blit without scaling */
2565         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2566         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2567
2568         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2569         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2570         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2571
2572         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2573         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2574         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2575     }
2576
2577     /* texture ==> rendertarget surface, same size */
2578     if(surf_tex64 && surf_rt_dest64) {
2579         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2580         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2581
2582         if (hr == D3D_OK) {
2583             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2584             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2585         }
2586
2587         /* Blit without scaling */
2588         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2589         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2590
2591         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2592         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2593         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2594
2595         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2596         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2597         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2598     }
2599
2600     /* texture ==> texture, same size (should fail) */
2601     if(surf_tex64 && surf_tex_dest64) {
2602         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2603         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2604     }
2605
2606     /* Fill the surface of the smaller regular texture with red */
2607     if (surf_tex32 && surf_temp32) {
2608         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2609         fill_surface(surf_temp32, 0xffff0000);
2610         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2611         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2612     }
2613
2614     /* texture ==> offscreenplain, scaling (should fail) */
2615     if(surf_tex32 && surf_offscreen64) {
2616         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2617         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2618     }
2619
2620     /* texture ==> rendertarget texture, scaling */
2621     if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2622         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2623         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2624
2625         /* We can't lock rendertarget textures, so copy to our temp surface first */
2626         if (hr == D3D_OK) {
2627             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2628             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2629         }
2630
2631         if (hr == D3D_OK) {
2632             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2633             ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2634         }
2635     }
2636
2637     /* texture ==> rendertarget surface, scaling */
2638     if(surf_tex32 && surf_rt_dest64) {
2639         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2640         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2641
2642         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2643         ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2644     }
2645
2646     /* texture ==> texture, scaling (should fail) */
2647     if(surf_tex32 && surf_tex_dest64) {
2648         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2649         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2650     }
2651
2652     /*****************************************************************
2653      * Tests for when the source parameter is a rendertarget texture *
2654      *****************************************************************/
2655
2656     /* Fill the surface of the rendertarget texture with white */
2657     if (surf_tex_rt64 && surf_temp64) {
2658         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2659         fill_surface(surf_temp64, 0xffffffff);
2660         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2661         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2662     }
2663
2664     /* rendertarget texture ==> offscreenplain, same size */
2665     if(surf_tex_rt64 && surf_offscreen64) {
2666         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2667         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2668     }
2669
2670     /* rendertarget texture ==> rendertarget texture, same size */
2671     if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2672         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2673         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2674
2675         /* We can't lock rendertarget textures, so copy to our temp surface first */
2676         if (hr == D3D_OK) {
2677             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2678             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2679         }
2680
2681         if (hr == D3D_OK) {
2682             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2683             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2684         }
2685
2686         /* Blit without scaling */
2687         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2688         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2689
2690         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2691         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2692         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2693
2694         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2695         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2696         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2697     }
2698
2699     /* rendertarget texture ==> rendertarget surface, same size */
2700     if(surf_tex_rt64 && surf_rt_dest64) {
2701         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2702         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2703
2704         if (hr == D3D_OK) {
2705             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2706             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2707         }
2708
2709         /* Blit without scaling */
2710         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2711         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2712
2713         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2714         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2715         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2716
2717         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2718         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2719         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2720     }
2721
2722     /* rendertarget texture ==> texture, same size (should fail) */
2723     if(surf_tex_rt64 && surf_tex_dest64) {
2724         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2725         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2726     }
2727
2728     /* Fill the surface of the smaller rendertarget texture with red */
2729     if (surf_tex_rt32 && surf_temp32) {
2730         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2731         fill_surface(surf_temp32, 0xffff0000);
2732         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2733         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2734     }
2735
2736     /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2737     if(surf_tex_rt32 && surf_offscreen64) {
2738         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2739         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2740     }
2741
2742     /* rendertarget texture ==> rendertarget texture, scaling */
2743     if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2744         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2745         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2746
2747         /* We can't lock rendertarget textures, so copy to our temp surface first */
2748         if (hr == D3D_OK) {
2749             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2750             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2751         }
2752
2753         if (hr == D3D_OK) {
2754             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2755             ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2756         }
2757     }
2758
2759     /* rendertarget texture ==> rendertarget surface, scaling */
2760     if(surf_tex_rt32 && surf_rt_dest64) {
2761         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2762         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2763
2764         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2765         ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2766     }
2767
2768     /* rendertarget texture ==> texture, scaling (should fail) */
2769     if(surf_tex_rt32 && surf_tex_dest64) {
2770         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2771         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2772     }
2773
2774     /*****************************************************************
2775      * Tests for when the source parameter is a rendertarget surface *
2776      *****************************************************************/
2777
2778     /* Fill the surface of the rendertarget surface with black */
2779     if (surf_rt64)
2780         fill_surface(surf_rt64, 0xff000000);
2781
2782     /* rendertarget texture ==> offscreenplain, same size */
2783     if(surf_rt64 && surf_offscreen64) {
2784         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2785         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2786     }
2787
2788     /* rendertarget surface ==> rendertarget texture, same size */
2789     if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2790         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2791         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2792
2793         /* We can't lock rendertarget textures, so copy to our temp surface first */
2794         if (hr == D3D_OK) {
2795             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2796             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2797         }
2798
2799         if (hr == D3D_OK) {
2800             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2801             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2802         }
2803
2804         /* Blit without scaling */
2805         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2806         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2807
2808         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2809         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2810         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2811
2812         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2813         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2814         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2815     }
2816
2817     /* rendertarget surface ==> rendertarget surface, same size */
2818     if(surf_rt64 && surf_rt_dest64) {
2819         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2820         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2821
2822         if (hr == D3D_OK) {
2823             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2824             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2825         }
2826
2827         /* Blit without scaling */
2828         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2829         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2830
2831         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2832         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64_flipy, 0);
2833         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2834
2835         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2836         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2837         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2838     }
2839
2840     /* rendertarget surface ==> texture, same size (should fail) */
2841     if(surf_rt64 && surf_tex_dest64) {
2842         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2843         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2844     }
2845
2846     /* Fill the surface of the smaller rendertarget texture with red */
2847     if (surf_rt32)
2848         fill_surface(surf_rt32, 0xffff0000);
2849
2850     /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2851     if(surf_rt32 && surf_offscreen64) {
2852         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2853         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2854     }
2855
2856     /* rendertarget surface ==> rendertarget texture, scaling */
2857     if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2858         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2859         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2860
2861         /* We can't lock rendertarget textures, so copy to our temp surface first */
2862         if (hr == D3D_OK) {
2863             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2864             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2865         }
2866
2867         if (hr == D3D_OK) {
2868             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2869             ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2870         }
2871     }
2872
2873     /* rendertarget surface ==> rendertarget surface, scaling */
2874     if(surf_rt32 && surf_rt_dest64) {
2875         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2876         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2877
2878         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2879         ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2880     }
2881
2882     /* rendertarget surface ==> texture, scaling (should fail) */
2883     if(surf_rt32 && surf_tex_dest64) {
2884         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2885         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2886     }
2887
2888     /* backbuffer ==> surface tests (no scaling) */
2889     if(backbuffer && surf_tex_rt_dest640_480)
2890     {
2891         RECT src_rect = {0, 0, 640, 480};
2892         RECT src_rect_flipy = {0, 480, 640, 0};
2893         RECT dst_rect = {0, 0, 640, 480};
2894         RECT dst_rect_flipy = {0, 480, 640, 0};
2895
2896         /* Blit with NULL rectangles */
2897         hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, 0);
2898         ok( hr == D3D_OK, "StretchRect backbuffer ==> texture same size failed:\n");
2899
2900         /* Blit without scaling */
2901         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect, 0);
2902         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2903
2904         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2905         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy, surf_tex_rt_dest640_480, &dst_rect, 0);
2906         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2907
2908         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2909         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect_flipy, 0);
2910         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2911     }
2912
2913     /* TODO: Test format conversions */
2914
2915
2916 out:
2917     /* Clean up */
2918     if (backbuffer)
2919         IDirect3DSurface9_Release(backbuffer);
2920     if (surf_rt32)
2921         IDirect3DSurface9_Release(surf_rt32);
2922     if (surf_rt64)
2923         IDirect3DSurface9_Release(surf_rt64);
2924     if (surf_rt_dest64)
2925         IDirect3DSurface9_Release(surf_rt_dest64);
2926     if (surf_temp32)
2927         IDirect3DSurface9_Release(surf_temp32);
2928     if (surf_temp64)
2929         IDirect3DSurface9_Release(surf_temp64);
2930     if (surf_offscreen32)
2931         IDirect3DSurface9_Release(surf_offscreen32);
2932     if (surf_offscreen64)
2933         IDirect3DSurface9_Release(surf_offscreen64);
2934     if (surf_offscreen_dest64)
2935         IDirect3DSurface9_Release(surf_offscreen_dest64);
2936
2937     if (tex_rt32) {
2938         if (surf_tex_rt32)
2939             IDirect3DSurface9_Release(surf_tex_rt32);
2940         IDirect3DTexture9_Release(tex_rt32);
2941     }
2942     if (tex_rt64) {
2943         if (surf_tex_rt64)
2944             IDirect3DSurface9_Release(surf_tex_rt64);
2945         IDirect3DTexture9_Release(tex_rt64);
2946     }
2947     if (tex_rt_dest64) {
2948         if (surf_tex_rt_dest64)
2949             IDirect3DSurface9_Release(surf_tex_rt_dest64);
2950         IDirect3DTexture9_Release(tex_rt_dest64);
2951     }
2952     if (tex_rt_dest640_480) {
2953         if (surf_tex_rt_dest640_480)
2954             IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
2955         IDirect3DTexture9_Release(tex_rt_dest640_480);
2956     }
2957     if (tex32) {
2958         if (surf_tex32)
2959             IDirect3DSurface9_Release(surf_tex32);
2960         IDirect3DTexture9_Release(tex32);
2961     }
2962     if (tex64) {
2963         if (surf_tex64)
2964             IDirect3DSurface9_Release(surf_tex64);
2965         IDirect3DTexture9_Release(tex64);
2966     }
2967     if (tex_dest64) {
2968         if (surf_tex_dest64)
2969             IDirect3DSurface9_Release(surf_tex_dest64);
2970         IDirect3DTexture9_Release(tex_dest64);
2971     }
2972
2973     if (orig_rt) {
2974         hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2975         ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
2976         IDirect3DSurface9_Release(orig_rt);
2977     }
2978 }
2979
2980 static void maxmip_test(IDirect3DDevice9 *device)
2981 {
2982     IDirect3DTexture9 *texture = NULL;
2983     IDirect3DSurface9 *surface = NULL;
2984     HRESULT hr;
2985     DWORD color;
2986     const float quads[] = {
2987         -1.0,   -1.0,   0.0,    0.0,    0.0,
2988         -1.0,    0.0,   0.0,    0.0,    1.0,
2989          0.0,   -1.0,   0.0,    1.0,    0.0,
2990          0.0,    0.0,   0.0,    1.0,    1.0,
2991
2992          0.0,   -1.0,   0.0,    0.0,    0.0,
2993          0.0,    0.0,   0.0,    0.0,    1.0,
2994          1.0,   -1.0,   0.0,    1.0,    0.0,
2995          1.0,    0.0,   0.0,    1.0,    1.0,
2996
2997          0.0,    0.0,   0.0,    0.0,    0.0,
2998          0.0,    1.0,   0.0,    0.0,    1.0,
2999          1.0,    0.0,   0.0,    1.0,    0.0,
3000          1.0,    1.0,   0.0,    1.0,    1.0,
3001
3002         -1.0,    0.0,   0.0,    0.0,    0.0,
3003         -1.0,    1.0,   0.0,    0.0,    1.0,
3004          0.0,    0.0,   0.0,    1.0,    0.0,
3005          0.0,    1.0,   0.0,    1.0,    1.0,
3006     };
3007
3008     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3009     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3010
3011     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
3012                                         &texture, NULL);
3013     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3014     if(!texture)
3015     {
3016         skip("Failed to create test texture\n");
3017         return;
3018     }
3019
3020     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3021     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3022     fill_surface(surface, 0xffff0000);
3023     IDirect3DSurface9_Release(surface);
3024     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
3025     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3026     fill_surface(surface, 0xff00ff00);
3027     IDirect3DSurface9_Release(surface);
3028     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3029     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3030     fill_surface(surface, 0xff0000ff);
3031     IDirect3DSurface9_Release(surface);
3032
3033     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3034     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3035     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3036     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3037
3038     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3039     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3040
3041     hr = IDirect3DDevice9_BeginScene(device);
3042     if(SUCCEEDED(hr))
3043     {
3044         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3045         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3046         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
3047         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3048
3049         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3050         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3051         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
3052         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3053
3054         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3055         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3056         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
3057         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3058
3059         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3060         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3061         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
3062         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3063         hr = IDirect3DDevice9_EndScene(device);
3064         ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
3065     }
3066
3067     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
3068     color = getPixelColor(device, 160, 360);
3069     ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
3070     color = getPixelColor(device, 160, 120);
3071     ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
3072     color = getPixelColor(device, 480, 120);
3073     ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
3074     color = getPixelColor(device, 480, 360);
3075     ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
3076     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3077     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3078
3079     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3080     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3081
3082     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3083     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3084
3085     hr = IDirect3DDevice9_BeginScene(device);
3086     if(SUCCEEDED(hr))
3087     {
3088         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3089         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3090         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
3091         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3092
3093         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3094         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3095         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
3096         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3097
3098         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3099         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3100         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
3101         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3102
3103         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3104         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3105         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
3106         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3107         hr = IDirect3DDevice9_EndScene(device);
3108         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
3109     }
3110
3111     /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
3112      * samples from the highest level in the texture(level 2)
3113      */
3114     color = getPixelColor(device, 160, 360);
3115     ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
3116     color = getPixelColor(device, 160, 120);
3117     ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
3118     color = getPixelColor(device, 480, 120);
3119     ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
3120     color = getPixelColor(device, 480, 360);
3121     ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
3122     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3123     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3124
3125     hr = IDirect3DDevice9_BeginScene(device);
3126     if(SUCCEEDED(hr))
3127     {
3128         DWORD ret;
3129
3130         /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
3131         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3132         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3133         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3134         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3135         ret = IDirect3DTexture9_SetLOD(texture, 1);
3136         ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
3137         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
3138         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3139
3140         /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
3141         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3142         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3143         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3144         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3145         ret = IDirect3DTexture9_SetLOD(texture, 2);
3146         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3147         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
3148         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3149
3150         /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
3151         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3152         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3153         ret = IDirect3DTexture9_SetLOD(texture, 1);
3154         ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
3155         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
3156         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3157
3158         /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
3159         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3160         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3161         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3162         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3163         ret = IDirect3DTexture9_SetLOD(texture, 1);
3164         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3165         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
3166         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3167         hr = IDirect3DDevice9_EndScene(device);
3168     }
3169
3170     /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
3171      * samples from the highest level in the texture(level 2)
3172      */
3173     color = getPixelColor(device, 160, 360);
3174     ok(color == 0x0000FF00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x\n", color);
3175     color = getPixelColor(device, 160, 120);
3176     ok(color == 0x0000FF00, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x\n", color);
3177     color = getPixelColor(device, 480, 120);
3178     ok(color == 0x000000FF, "MapMip 2, LOD 1, point mipfilter has color 0x%08x\n", color);
3179     color = getPixelColor(device, 480, 360);
3180     ok(color == 0x000000FF, "MapMip 2, LOD 1, none mipfilter has color 0x%08x\n", color);
3181     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3182     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3183
3184     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3185     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3186     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3187     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3188     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3189     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3190     IDirect3DTexture9_Release(texture);
3191 }
3192
3193 static void release_buffer_test(IDirect3DDevice9 *device)
3194 {
3195     IDirect3DVertexBuffer9 *vb = NULL;
3196     IDirect3DIndexBuffer9 *ib = NULL;
3197     HRESULT hr;
3198     BYTE *data;
3199     LONG ref;
3200
3201     static const struct vertex quad[] = {
3202         {-1.0,      -1.0,       0.1,        0xffff0000},
3203         {-1.0,       1.0,       0.1,        0xffff0000},
3204         { 1.0,       1.0,       0.1,        0xffff0000},
3205
3206         {-1.0,      -1.0,       0.1,        0xff00ff00},
3207         {-1.0,       1.0,       0.1,        0xff00ff00},
3208         { 1.0,       1.0,       0.1,        0xff00ff00}
3209     };
3210     short indices[] = {3, 4, 5};
3211
3212     /* Index and vertex buffers should always be creatable */
3213     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
3214                                               D3DPOOL_MANAGED, &vb, NULL);
3215     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
3216     if(!vb) {
3217         skip("Failed to create a vertex buffer\n");
3218         return;
3219     }
3220     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3221     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
3222     if(!ib) {
3223         skip("Failed to create an index buffer\n");
3224         return;
3225     }
3226
3227     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3228     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3229     memcpy(data, quad, sizeof(quad));
3230     hr = IDirect3DVertexBuffer9_Unlock(vb);
3231     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3232
3233     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3234     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3235     memcpy(data, indices, sizeof(indices));
3236     hr = IDirect3DIndexBuffer9_Unlock(ib);
3237     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3238
3239     hr = IDirect3DDevice9_SetIndices(device, ib);
3240     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3241     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3242     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3243     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3244     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3245
3246     /* Now destroy the bound index buffer and draw again */
3247     ref = IDirect3DIndexBuffer9_Release(ib);
3248     ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3249
3250     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3251     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3252
3253     hr = IDirect3DDevice9_BeginScene(device);
3254     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3255     if(SUCCEEDED(hr))
3256     {
3257         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3258          * making assumptions about the indices or vertices
3259          */
3260         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3261         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3262         hr = IDirect3DDevice9_EndScene(device);
3263         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3264     }
3265
3266     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3267     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3268
3269     hr = IDirect3DDevice9_SetIndices(device, NULL);
3270     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3271     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3272     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3273
3274     /* Index buffer was already destroyed as part of the test */
3275     IDirect3DVertexBuffer9_Release(vb);
3276 }
3277
3278 static void float_texture_test(IDirect3DDevice9 *device)
3279 {
3280     IDirect3D9 *d3d = NULL;
3281     HRESULT hr;
3282     IDirect3DTexture9 *texture = NULL;
3283     D3DLOCKED_RECT lr;
3284     float *data;
3285     DWORD color;
3286     float quad[] = {
3287         -1.0,      -1.0,       0.1,     0.0,    0.0,
3288         -1.0,       1.0,       0.1,     0.0,    1.0,
3289          1.0,      -1.0,       0.1,     1.0,    0.0,
3290          1.0,       1.0,       0.1,     1.0,    1.0,
3291     };
3292
3293     memset(&lr, 0, sizeof(lr));
3294     IDirect3DDevice9_GetDirect3D(device, &d3d);
3295     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3296                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3297         skip("D3DFMT_R32F textures not supported\n");
3298         goto out;
3299     }
3300
3301     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3302                                         D3DPOOL_MANAGED, &texture, NULL);
3303     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3304     if(!texture) {
3305         skip("Failed to create R32F texture\n");
3306         goto out;
3307     }
3308
3309     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3310     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3311     data = lr.pBits;
3312     *data = 0.0;
3313     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3314     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3315
3316     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3317     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3318
3319     hr = IDirect3DDevice9_BeginScene(device);
3320     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3321     if(SUCCEEDED(hr))
3322     {
3323         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3324         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3325
3326         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3327         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3328
3329         hr = IDirect3DDevice9_EndScene(device);
3330         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3331     }
3332     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3333     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3334
3335     color = getPixelColor(device, 240, 320);
3336     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3337
3338     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3339     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3340
3341 out:
3342     if(texture) IDirect3DTexture9_Release(texture);
3343     IDirect3D9_Release(d3d);
3344 }
3345
3346 static void g16r16_texture_test(IDirect3DDevice9 *device)
3347 {
3348     IDirect3D9 *d3d = NULL;
3349     HRESULT hr;
3350     IDirect3DTexture9 *texture = NULL;
3351     D3DLOCKED_RECT lr;
3352     DWORD *data;
3353     DWORD color;
3354     float quad[] = {
3355        -1.0,      -1.0,       0.1,     0.0,    0.0,
3356        -1.0,       1.0,       0.1,     0.0,    1.0,
3357         1.0,      -1.0,       0.1,     1.0,    0.0,
3358         1.0,       1.0,       0.1,     1.0,    1.0,
3359     };
3360
3361     memset(&lr, 0, sizeof(lr));
3362     IDirect3DDevice9_GetDirect3D(device, &d3d);
3363     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3364        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3365            skip("D3DFMT_G16R16 textures not supported\n");
3366            goto out;
3367     }
3368
3369     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3370                                         D3DPOOL_MANAGED, &texture, NULL);
3371     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3372     if(!texture) {
3373         skip("Failed to create D3DFMT_G16R16 texture\n");
3374         goto out;
3375     }
3376
3377     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3378     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3379     data = lr.pBits;
3380     *data = 0x0f00f000;
3381     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3382     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3383
3384     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3385     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3386
3387     hr = IDirect3DDevice9_BeginScene(device);
3388     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3389     if(SUCCEEDED(hr))
3390     {
3391         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3392         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3393
3394         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3395         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3396
3397         hr = IDirect3DDevice9_EndScene(device);
3398         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3399     }
3400     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3401     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3402
3403     color = getPixelColor(device, 240, 320);
3404     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3405        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3406
3407     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3408     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3409
3410 out:
3411     if(texture) IDirect3DTexture9_Release(texture);
3412     IDirect3D9_Release(d3d);
3413 }
3414
3415 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3416 {
3417     HRESULT hr;
3418     IDirect3D9 *d3d;
3419     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3420     D3DCAPS9 caps;
3421     IDirect3DTexture9 *texture = NULL;
3422     IDirect3DVolumeTexture9 *volume = NULL;
3423     unsigned int x, y, z;
3424     D3DLOCKED_RECT lr;
3425     D3DLOCKED_BOX lb;
3426     DWORD color;
3427     UINT w, h;
3428     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3429     float identity[16] = {1.0, 0.0, 0.0, 0.0,
3430                            0.0, 1.0, 0.0, 0.0,
3431                            0.0, 0.0, 1.0, 0.0,
3432                            0.0, 0.0, 0.0, 1.0};
3433     static const D3DVERTEXELEMENT9 decl_elements[] = {
3434         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3435         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3436         D3DDECL_END()
3437     };
3438     static const D3DVERTEXELEMENT9 decl_elements2[] = {
3439         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3440         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3441         D3DDECL_END()
3442     };
3443     static const D3DVERTEXELEMENT9 decl_elements3[] = {
3444         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3445         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3446         D3DDECL_END()
3447     };
3448     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3449                                                  0x00, 0xff, 0x00, 0x00,
3450                                                  0x00, 0x00, 0x00, 0x00,
3451                                                  0x00, 0x00, 0x00, 0x00};
3452
3453     memset(&lr, 0, sizeof(lr));
3454     memset(&lb, 0, sizeof(lb));
3455     IDirect3DDevice9_GetDirect3D(device, &d3d);
3456     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3457                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3458         fmt = D3DFMT_A16B16G16R16;
3459     }
3460     IDirect3D9_Release(d3d);
3461
3462     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3463     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3464     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3465     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3466     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3467     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3468     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3469     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3470     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3471     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3472     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3473     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3474     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3475     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3476     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3477     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3478     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3479     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3480     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3481     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3482     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3483     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3484     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3485     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3486
3487     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3488     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3489     w = min(1024, caps.MaxTextureWidth);
3490     h = min(1024, caps.MaxTextureHeight);
3491     hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3492                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3493     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3494     if(!texture) {
3495         skip("Failed to create the test texture\n");
3496         return;
3497     }
3498
3499     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3500      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3501      * 1.0 in red and green for the x and y coords
3502      */
3503     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3504     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3505     for(y = 0; y < h; y++) {
3506         for(x = 0; x < w; x++) {
3507             double r_f = (double) y / (double) h;
3508             double g_f = (double) x / (double) w;
3509             if(fmt == D3DFMT_A16B16G16R16) {
3510                 unsigned short r, g;
3511                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3512                 r = (unsigned short) (r_f * 65536.0);
3513                 g = (unsigned short) (g_f * 65536.0);
3514                 dst[0] = r;
3515                 dst[1] = g;
3516                 dst[2] = 0;
3517                 dst[3] = 65535;
3518             } else {
3519                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3520                 unsigned char r = (unsigned char) (r_f * 255.0);
3521                 unsigned char g = (unsigned char) (g_f * 255.0);
3522                 dst[0] = 0;
3523                 dst[1] = g;
3524                 dst[2] = r;
3525                 dst[3] = 255;
3526             }
3527         }
3528     }
3529     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3530     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3531     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3532     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3533
3534     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3535     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3536     hr = IDirect3DDevice9_BeginScene(device);
3537     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3538     if(SUCCEEDED(hr))
3539     {
3540         float quad1[] = {
3541             -1.0,      -1.0,       0.1,     1.0,    1.0,
3542             -1.0,       0.0,       0.1,     1.0,    1.0,
3543              0.0,      -1.0,       0.1,     1.0,    1.0,
3544              0.0,       0.0,       0.1,     1.0,    1.0,
3545         };
3546         float quad2[] = {
3547             -1.0,       0.0,       0.1,     1.0,    1.0,
3548             -1.0,       1.0,       0.1,     1.0,    1.0,
3549              0.0,       0.0,       0.1,     1.0,    1.0,
3550              0.0,       1.0,       0.1,     1.0,    1.0,
3551         };
3552         float quad3[] = {
3553              0.0,       0.0,       0.1,     0.5,    0.5,
3554              0.0,       1.0,       0.1,     0.5,    0.5,
3555              1.0,       0.0,       0.1,     0.5,    0.5,
3556              1.0,       1.0,       0.1,     0.5,    0.5,
3557         };
3558         float quad4[] = {
3559              320,       480,       0.1,     1.0,    0.0,    1.0,
3560              320,       240,       0.1,     1.0,    0.0,    1.0,
3561              640,       480,       0.1,     1.0,    0.0,    1.0,
3562              640,       240,       0.1,     1.0,    0.0,    1.0,
3563         };
3564         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3565                           0.0, 0.0, 0.0, 0.0,
3566                           0.0, 0.0, 0.0, 0.0,
3567                           0.0, 0.0, 0.0, 0.0};
3568
3569         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3570         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3571         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3572         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3573         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3574
3575         /* What happens with transforms enabled? */
3576         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3577         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3578         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3579         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3580
3581         /* What happens if 4 coords are used, but only 2 given ?*/
3582         mat[8] = 1.0;
3583         mat[13] = 1.0;
3584         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3585         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3586         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3587         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3588         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3589         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3590
3591         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3592          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3593          * due to the coords in the vertices. (turns out red, indeed)
3594          */
3595         memset(mat, 0, sizeof(mat));
3596         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3597         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3598         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3599         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3600         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3601         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3602         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3603         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3604
3605         hr = IDirect3DDevice9_EndScene(device);
3606         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3607     }
3608     color = getPixelColor(device, 160, 360);
3609     ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3610     color = getPixelColor(device, 160, 120);
3611     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3612     color = getPixelColor(device, 480, 120);
3613     ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
3614     color = getPixelColor(device, 480, 360);
3615     ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
3616     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3617     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3618
3619     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3620     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3621
3622     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3623     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3624     hr = IDirect3DDevice9_BeginScene(device);
3625     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3626     if(SUCCEEDED(hr))
3627     {
3628         float quad1[] = {
3629             -1.0,      -1.0,       0.1,     0.8,    0.2,
3630             -1.0,       0.0,       0.1,     0.8,    0.2,
3631              0.0,      -1.0,       0.1,     0.8,    0.2,
3632              0.0,       0.0,       0.1,     0.8,    0.2,
3633         };
3634         float quad2[] = {
3635             -1.0,       0.0,       0.1,     0.5,    1.0,
3636             -1.0,       1.0,       0.1,     0.5,    1.0,
3637              0.0,       0.0,       0.1,     0.5,    1.0,
3638              0.0,       1.0,       0.1,     0.5,    1.0,
3639         };
3640         float quad3[] = {
3641              0.0,       0.0,       0.1,     0.5,    1.0,
3642              0.0,       1.0,       0.1,     0.5,    1.0,
3643              1.0,       0.0,       0.1,     0.5,    1.0,
3644              1.0,       1.0,       0.1,     0.5,    1.0,
3645         };
3646         float quad4[] = {
3647              0.0,      -1.0,       0.1,     0.8,    0.2,
3648              0.0,       0.0,       0.1,     0.8,    0.2,
3649              1.0,      -1.0,       0.1,     0.8,    0.2,
3650              1.0,       0.0,       0.1,     0.8,    0.2,
3651         };
3652         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3653                           0.0, 0.0, 0.0, 0.0,
3654                           0.0, 1.0, 0.0, 0.0,
3655                           0.0, 0.0, 0.0, 0.0};
3656
3657         /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3658          */
3659         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3660         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3661         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3662         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3663
3664         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3665         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3666
3667         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3668          * it behaves like COUNT2 because normal textures require 2 coords
3669          */
3670         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3671         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3672         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3673         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3674
3675         /* Just to be sure, the same as quad2 above */
3676         memset(mat, 0, sizeof(mat));
3677         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3678         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3679         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3680         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3681         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3682         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3683
3684         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3685          * used? And what happens to the first?
3686          */
3687         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3688         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3689         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3690         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3691
3692         hr = IDirect3DDevice9_EndScene(device);
3693         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3694     }
3695     color = getPixelColor(device, 160, 360);
3696     ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
3697     color = getPixelColor(device, 160, 120);
3698     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3699     color = getPixelColor(device, 480, 120);
3700     ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
3701        "quad 3 has color %08x, expected 0x00ff8000\n", color);
3702     color = getPixelColor(device, 480, 360);
3703     ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
3704        "quad 4 has color %08x, expected 0x0033cc00\n", color);
3705     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3706     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3707
3708     IDirect3DTexture9_Release(texture);
3709
3710     /* Test projected textures, without any fancy matrices */
3711     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3712     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3713     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3714     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3715     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3716     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3717     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3718     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3719
3720     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3721     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3722     for(x = 0; x < 4; x++) {
3723         memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3724     }
3725     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3726     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3727     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3728     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3729
3730     hr = IDirect3DDevice9_BeginScene(device);
3731     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3732     if(SUCCEEDED(hr))
3733     {
3734         const float proj_quads[] = {
3735            -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3736             1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3737            -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3738             1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3739            -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3740             1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3741            -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3742             1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3743         };
3744
3745         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3746         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3747         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3748         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3749
3750         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3751         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3752         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3753         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3754
3755         hr = IDirect3DDevice9_EndScene(device);
3756         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3757     }
3758
3759     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3760     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3761     IDirect3DTexture9_Release(texture);
3762
3763     color = getPixelColor(device, 158, 118);
3764     ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3765     color = getPixelColor(device, 162, 118);
3766     ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3767     color = getPixelColor(device, 158, 122);
3768     ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3769     color = getPixelColor(device, 162, 122);
3770     ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3771
3772     color = getPixelColor(device, 158, 178);
3773     ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3774     color = getPixelColor(device, 162, 178);
3775     ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3776     color = getPixelColor(device, 158, 182);
3777     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3778     color = getPixelColor(device, 162, 182);
3779     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3780
3781     color = getPixelColor(device, 318, 118);
3782     ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3783     color = getPixelColor(device, 322, 118);
3784     ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3785     color = getPixelColor(device, 318, 122);
3786     ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3787     color = getPixelColor(device, 322, 122);
3788     ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3789
3790     color = getPixelColor(device, 318, 178);
3791     ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3792     color = getPixelColor(device, 322, 178);
3793     ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3794     color = getPixelColor(device, 318, 182);
3795     ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3796     color = getPixelColor(device, 322, 182);
3797     ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3798
3799     color = getPixelColor(device, 238, 298);
3800     ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3801     color = getPixelColor(device, 242, 298);
3802     ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3803     color = getPixelColor(device, 238, 302);
3804     ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3805     color = getPixelColor(device, 242, 302);
3806     ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3807
3808     color = getPixelColor(device, 238, 388);
3809     ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3810     color = getPixelColor(device, 242, 388);
3811     ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3812     color = getPixelColor(device, 238, 392);
3813     ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3814     color = getPixelColor(device, 242, 392);
3815     ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3816
3817     color = getPixelColor(device, 478, 298);
3818     ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3819     color = getPixelColor(device, 482, 298);
3820     ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3821     color = getPixelColor(device, 478, 302);
3822     ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3823     color = getPixelColor(device, 482, 302);
3824     ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3825
3826     color = getPixelColor(device, 478, 388);
3827     ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3828     color = getPixelColor(device, 482, 388);
3829     ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3830     color = getPixelColor(device, 478, 392);
3831     ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3832     color = getPixelColor(device, 482, 392);
3833     ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3834
3835     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3836     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3837
3838     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3839     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3840     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3841      * Thus watch out if sampling from texels between 0 and 1.
3842      */
3843     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3844     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3845        "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3846     if(!volume) {
3847         skip("Failed to create a volume texture\n");
3848         goto out;
3849     }
3850
3851     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3852     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3853     for(z = 0; z < 32; z++) {
3854         for(y = 0; y < 32; y++) {
3855             for(x = 0; x < 32; x++) {
3856                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3857                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3858                 float r_f = (float) x / 31.0;
3859                 float g_f = (float) y / 31.0;
3860                 float b_f = (float) z / 31.0;
3861
3862                 if(fmt == D3DFMT_A16B16G16R16) {
3863                     unsigned short *mem_s = mem;
3864                     mem_s[0]  = r_f * 65535.0;
3865                     mem_s[1]  = g_f * 65535.0;
3866                     mem_s[2]  = b_f * 65535.0;
3867                     mem_s[3]  = 65535;
3868                 } else {
3869                     unsigned char *mem_c = mem;
3870                     mem_c[0]  = b_f * 255.0;
3871                     mem_c[1]  = g_f * 255.0;
3872                     mem_c[2]  = r_f * 255.0;
3873                     mem_c[3]  = 255;
3874                 }
3875             }
3876         }
3877     }
3878     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3879     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3880
3881     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3882     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3883
3884     hr = IDirect3DDevice9_BeginScene(device);
3885     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3886     if(SUCCEEDED(hr))
3887     {
3888         float quad1[] = {
3889             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3890             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3891              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3892              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3893         };
3894         float quad2[] = {
3895             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3896             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
3897              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3898              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
3899         };
3900         float quad3[] = {
3901              0.0,       0.0,       0.1,     0.0,    0.0,
3902              0.0,       1.0,       0.1,     0.0,    0.0,
3903              1.0,       0.0,       0.1,     0.0,    0.0,
3904              1.0,       1.0,       0.1,     0.0,    0.0
3905         };
3906         float quad4[] = {
3907              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3908              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3909              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3910              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
3911         };
3912         float mat[16] = {1.0, 0.0, 0.0, 0.0,
3913                          0.0, 0.0, 1.0, 0.0,
3914                          0.0, 1.0, 0.0, 0.0,
3915                          0.0, 0.0, 0.0, 1.0};
3916         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3917         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3918
3919         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3920          * values
3921          */
3922         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3923         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3924         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3925         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3926         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3927         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3928
3929         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3930          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3931          * otherwise the w will be missing(blue).
3932          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3933          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3934          */
3935         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3936         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3937         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3938         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3939
3940         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
3941         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3942         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3943         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3944         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3945         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3946         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3947         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3948         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3949
3950         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3951          * disable. ATI extends it up to the amount of values needed for the volume texture
3952          */
3953         memset(mat, 0, sizeof(mat));
3954         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3955         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3956         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3957         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3958         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3959         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3960         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3961         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3962
3963         hr = IDirect3DDevice9_EndScene(device);
3964         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3965     }
3966
3967     color = getPixelColor(device, 160, 360);
3968     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3969     color = getPixelColor(device, 160, 120);
3970     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3971        "quad 2 has color %08x, expected 0x00ffff00\n", color);
3972     color = getPixelColor(device, 480, 120);
3973     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3974     color = getPixelColor(device, 480, 360);
3975     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3976
3977     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3978     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3979
3980     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3981     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3982     hr = IDirect3DDevice9_BeginScene(device);
3983     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3984     if(SUCCEEDED(hr))
3985     {
3986         float quad1[] = {
3987             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3988             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3989              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3990              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3991         };
3992         float quad2[] = {
3993             -1.0,       0.0,       0.1,
3994             -1.0,       1.0,       0.1,
3995              0.0,       0.0,       0.1,
3996              0.0,       1.0,       0.1,
3997         };
3998         float quad3[] = {
3999              0.0,       0.0,       0.1,     1.0,
4000              0.0,       1.0,       0.1,     1.0,
4001              1.0,       0.0,       0.1,     1.0,
4002              1.0,       1.0,       0.1,     1.0
4003         };
4004         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
4005                            0.0, 0.0, 0.0, 0.0,
4006                            0.0, 0.0, 0.0, 0.0,
4007                            0.0, 1.0, 0.0, 0.0};
4008         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
4009                            1.0, 0.0, 0.0, 0.0,
4010                            0.0, 1.0, 0.0, 0.0,
4011                            0.0, 0.0, 1.0, 0.0};
4012         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4013         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4014
4015         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
4016          */
4017         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4018         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4019         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
4020         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4021         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4022         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4023
4024         /* None passed */
4025         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4026         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4027         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4028         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4029         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4030         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4031
4032         /* 4 used, 1 passed */
4033         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4034         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4035         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
4036         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4037         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4038         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4039
4040         hr = IDirect3DDevice9_EndScene(device);
4041         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4042     }
4043     color = getPixelColor(device, 160, 360);
4044     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4045     color = getPixelColor(device, 160, 120);
4046     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4047     color = getPixelColor(device, 480, 120);
4048     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4049     /* Quad4: unused */
4050
4051     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4052     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4053
4054     IDirect3DVolumeTexture9_Release(volume);
4055
4056     out:
4057     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4058     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4059     IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
4060     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4061     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4062     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4063     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4064     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4065     IDirect3DVertexDeclaration9_Release(decl);
4066     IDirect3DVertexDeclaration9_Release(decl2);
4067     IDirect3DVertexDeclaration9_Release(decl3);
4068 }
4069
4070 static void texdepth_test(IDirect3DDevice9 *device)
4071 {
4072     IDirect3DPixelShader9 *shader;
4073     HRESULT hr;
4074     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
4075     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
4076     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
4077     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
4078     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
4079     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
4080     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
4081     DWORD shader_code[] = {
4082         0xffff0104,                                                                 /* ps_1_4               */
4083         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
4084         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
4085         0x0000fffd,                                                                 /* phase                */
4086         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
4087         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
4088         0x0000ffff                                                                  /* end                  */
4089     };
4090     DWORD color;
4091     float vertex[] = {
4092        -1.0,   -1.0,    0.0,
4093         1.0,   -1.0,    1.0,
4094        -1.0,    1.0,    0.0,
4095         1.0,    1.0,    1.0
4096     };
4097
4098     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4099     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4100
4101     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4102     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4103     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4104     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4105     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4106     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4107     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4108     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4109     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4110     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4111
4112     /* Fill the depth buffer with a gradient */
4113     hr = IDirect3DDevice9_BeginScene(device);
4114     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4115     if(SUCCEEDED(hr))
4116     {
4117         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4118         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4119         hr = IDirect3DDevice9_EndScene(device);
4120         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4121     }
4122
4123     /* Now perform the actual tests. Same geometry, but with the shader */
4124     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4125     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4126     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4127     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4128     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4129     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4130
4131     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4132     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4133     hr = IDirect3DDevice9_BeginScene(device);
4134     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4135     if(SUCCEEDED(hr))
4136     {
4137         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4138         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4139
4140         hr = IDirect3DDevice9_EndScene(device);
4141         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4142     }
4143
4144     color = getPixelColor(device, 158, 240);
4145     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4146     color = getPixelColor(device, 162, 240);
4147     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
4148
4149     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4150     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4151
4152     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4153     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4154
4155     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
4156     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4157     hr = IDirect3DDevice9_BeginScene(device);
4158     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4159     if(SUCCEEDED(hr))
4160     {
4161         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4162         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4163
4164         hr = IDirect3DDevice9_EndScene(device);
4165         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4166     }
4167
4168     color = getPixelColor(device, 318, 240);
4169     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4170     color = getPixelColor(device, 322, 240);
4171     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4172
4173     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4174     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4175
4176     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4177     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4178
4179     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4180     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4181     hr = IDirect3DDevice9_BeginScene(device);
4182     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4183     if(SUCCEEDED(hr))
4184     {
4185         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4186         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4187
4188         hr = IDirect3DDevice9_EndScene(device);
4189         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4190     }
4191
4192     color = getPixelColor(device, 1, 240);
4193     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4194
4195     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4196     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4197
4198     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4199     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4200
4201     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4202     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4203     hr = IDirect3DDevice9_BeginScene(device);
4204     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4205     if(SUCCEEDED(hr))
4206     {
4207         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4208         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4209
4210         hr = IDirect3DDevice9_EndScene(device);
4211         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4212     }
4213     color = getPixelColor(device, 318, 240);
4214     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4215     color = getPixelColor(device, 322, 240);
4216     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
4217
4218     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4219     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4220
4221     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4222     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4223
4224     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
4225     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4226     hr = IDirect3DDevice9_BeginScene(device);
4227     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4228     if(SUCCEEDED(hr))
4229     {
4230         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4231         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4232
4233         hr = IDirect3DDevice9_EndScene(device);
4234         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4235     }
4236
4237     color = getPixelColor(device, 1, 240);
4238     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4239
4240     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4241     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4242
4243     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4244     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4245
4246     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4247     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4248     hr = IDirect3DDevice9_BeginScene(device);
4249     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4250     if(SUCCEEDED(hr))
4251     {
4252         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4253         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4254
4255         hr = IDirect3DDevice9_EndScene(device);
4256         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4257     }
4258
4259     color = getPixelColor(device, 638, 240);
4260     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4261
4262     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4263     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4264
4265     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4266     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4267
4268     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4269     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4270     hr = IDirect3DDevice9_BeginScene(device);
4271     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4272     if(SUCCEEDED(hr))
4273     {
4274         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4275         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4276
4277         hr = IDirect3DDevice9_EndScene(device);
4278         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4279     }
4280
4281     color = getPixelColor(device, 638, 240);
4282     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4283
4284     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4285     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4286
4287     /* Cleanup */
4288     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4289     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4290     IDirect3DPixelShader9_Release(shader);
4291
4292     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4293     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4294     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4295     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4296 }
4297
4298 static void texkill_test(IDirect3DDevice9 *device)
4299 {
4300     IDirect3DPixelShader9 *shader;
4301     HRESULT hr;
4302     DWORD color;
4303
4304     const float vertex[] = {
4305     /*                          bottom  top    right    left */
4306         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
4307          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
4308         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
4309          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
4310     };
4311
4312     DWORD shader_code_11[] = {
4313     0xffff0101,                                                             /* ps_1_1                     */
4314     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4315     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
4316     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
4317     0x0000ffff                                                              /* end                        */
4318     };
4319     DWORD shader_code_20[] = {
4320     0xffff0200,                                                             /* ps_2_0                     */
4321     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
4322     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4323     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
4324     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
4325     0x0000ffff                                                              /* end                        */
4326     };
4327
4328     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4329     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4330     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4331     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4332
4333     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4334     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4335     hr = IDirect3DDevice9_BeginScene(device);
4336     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4337     if(SUCCEEDED(hr))
4338     {
4339         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4340         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4341         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4342         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4343         hr = IDirect3DDevice9_EndScene(device);
4344         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4345     }
4346     color = getPixelColor(device, 63, 46);
4347     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4348     color = getPixelColor(device, 66, 46);
4349     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4350     color = getPixelColor(device, 63, 49);
4351     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4352     color = getPixelColor(device, 66, 49);
4353     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4354
4355     color = getPixelColor(device, 578, 46);
4356     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4357     color = getPixelColor(device, 575, 46);
4358     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4359     color = getPixelColor(device, 578, 49);
4360     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4361     color = getPixelColor(device, 575, 49);
4362     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4363
4364     color = getPixelColor(device, 63, 430);
4365     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4366     color = getPixelColor(device, 63, 433);
4367     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4368     color = getPixelColor(device, 66, 433);
4369     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4370     color = getPixelColor(device, 66, 430);
4371     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4372
4373     color = getPixelColor(device, 578, 430);
4374     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4375     color = getPixelColor(device, 578, 433);
4376     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4377     color = getPixelColor(device, 575, 433);
4378     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4379     color = getPixelColor(device, 575, 430);
4380     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4381
4382     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4383     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4384
4385     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4386     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4387     IDirect3DPixelShader9_Release(shader);
4388
4389     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4390     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4391     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4392     if(FAILED(hr)) {
4393         skip("Failed to create 2.0 test shader, most likely not supported\n");
4394         return;
4395     }
4396
4397     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4398     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4399     hr = IDirect3DDevice9_BeginScene(device);
4400     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4401     if(SUCCEEDED(hr))
4402     {
4403         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4404         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4405         hr = IDirect3DDevice9_EndScene(device);
4406         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4407     }
4408
4409     color = getPixelColor(device, 63, 46);
4410     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4411     color = getPixelColor(device, 66, 46);
4412     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4413     color = getPixelColor(device, 63, 49);
4414     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4415     color = getPixelColor(device, 66, 49);
4416     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4417
4418     color = getPixelColor(device, 578, 46);
4419     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4420     color = getPixelColor(device, 575, 46);
4421     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4422     color = getPixelColor(device, 578, 49);
4423     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4424     color = getPixelColor(device, 575, 49);
4425     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4426
4427     color = getPixelColor(device, 63, 430);
4428     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4429     color = getPixelColor(device, 63, 433);
4430     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4431     color = getPixelColor(device, 66, 433);
4432     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4433     color = getPixelColor(device, 66, 430);
4434     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4435
4436     color = getPixelColor(device, 578, 430);
4437     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4438     color = getPixelColor(device, 578, 433);
4439     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4440     color = getPixelColor(device, 575, 433);
4441     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4442     color = getPixelColor(device, 575, 430);
4443     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4444
4445     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4446     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4447
4448     /* Cleanup */
4449     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4450     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4451     IDirect3DPixelShader9_Release(shader);
4452 }
4453
4454 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4455 {
4456     IDirect3D9 *d3d9;
4457     HRESULT hr;
4458     IDirect3DTexture9 *texture;
4459     IDirect3DPixelShader9 *shader;
4460     IDirect3DPixelShader9 *shader2;
4461     D3DLOCKED_RECT lr;
4462     DWORD color;
4463     DWORD shader_code[] = {
4464         0xffff0101,                             /* ps_1_1       */
4465         0x00000042, 0xb00f0000,                 /* tex t0       */
4466         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
4467         0x0000ffff                              /* end          */
4468     };
4469     DWORD shader_code2[] = {
4470         0xffff0101,                             /* ps_1_1       */
4471         0x00000042, 0xb00f0000,                 /* tex t0       */
4472         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
4473         0x0000ffff                              /* end          */
4474     };
4475
4476     float quad[] = {
4477        -1.0,   -1.0,   0.1,     0.5,    0.5,
4478         1.0,   -1.0,   0.1,     0.5,    0.5,
4479        -1.0,    1.0,   0.1,     0.5,    0.5,
4480         1.0,    1.0,   0.1,     0.5,    0.5,
4481     };
4482
4483     memset(&lr, 0, sizeof(lr));
4484     IDirect3DDevice9_GetDirect3D(device, &d3d9);
4485     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4486                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4487     IDirect3D9_Release(d3d9);
4488     if(FAILED(hr)) {
4489         skip("No D3DFMT_X8L8V8U8 support\n");
4490         return;
4491     };
4492
4493     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4494     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4495
4496     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4497     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4498     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4499     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4500     *((DWORD *) lr.pBits) = 0x11ca3141;
4501     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4502     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4503
4504     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4505     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4506     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4507     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4508
4509     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4510     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4511     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4512     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4513     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4514     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4515
4516     hr = IDirect3DDevice9_BeginScene(device);
4517     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4518     if(SUCCEEDED(hr))
4519     {
4520         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4521         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4522
4523         hr = IDirect3DDevice9_EndScene(device);
4524         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4525     }
4526     color = getPixelColor(device, 578, 430);
4527     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4528        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4529     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4530     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4531
4532     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4533     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4534     hr = IDirect3DDevice9_BeginScene(device);
4535     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4536     if(SUCCEEDED(hr))
4537     {
4538         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4539         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4540
4541         hr = IDirect3DDevice9_EndScene(device);
4542         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4543     }
4544     color = getPixelColor(device, 578, 430);
4545     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4546     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4547     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4548
4549     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4550     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4551     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4552     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4553     IDirect3DPixelShader9_Release(shader);
4554     IDirect3DPixelShader9_Release(shader2);
4555     IDirect3DTexture9_Release(texture);
4556 }
4557
4558 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4559 {
4560     HRESULT hr;
4561     IDirect3D9 *d3d;
4562     IDirect3DTexture9 *texture = NULL;
4563     IDirect3DSurface9 *surface;
4564     DWORD color;
4565     const RECT r1 = {256, 256, 512, 512};
4566     const RECT r2 = {512, 256, 768, 512};
4567     const RECT r3 = {256, 512, 512, 768};
4568     const RECT r4 = {512, 512, 768, 768};
4569     unsigned int x, y;
4570     D3DLOCKED_RECT lr;
4571     memset(&lr, 0, sizeof(lr));
4572
4573     IDirect3DDevice9_GetDirect3D(device, &d3d);
4574     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4575        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4576         skip("No autogenmipmap support\n");
4577         IDirect3D9_Release(d3d);
4578         return;
4579     }
4580     IDirect3D9_Release(d3d);
4581
4582     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4583     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4584
4585     /* Make the mipmap big, so that a smaller mipmap is used
4586      */
4587     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4588                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4589     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4590
4591     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4592     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4593     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4594     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4595     for(y = 0; y < 1024; y++) {
4596         for(x = 0; x < 1024; x++) {
4597             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4598             POINT pt;
4599
4600             pt.x = x;
4601             pt.y = y;
4602             if(PtInRect(&r1, pt)) {
4603                 *dst = 0xffff0000;
4604             } else if(PtInRect(&r2, pt)) {
4605                 *dst = 0xff00ff00;
4606             } else if(PtInRect(&r3, pt)) {
4607                 *dst = 0xff0000ff;
4608             } else if(PtInRect(&r4, pt)) {
4609                 *dst = 0xff000000;
4610             } else {
4611                 *dst = 0xffffffff;
4612             }
4613         }
4614     }
4615     hr = IDirect3DSurface9_UnlockRect(surface);
4616     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4617     IDirect3DSurface9_Release(surface);
4618
4619     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4620     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4621     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4622     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4623
4624     hr = IDirect3DDevice9_BeginScene(device);
4625     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4626     if(SUCCEEDED(hr)) {
4627         const float quad[] =  {
4628            -0.5,   -0.5,    0.1,    0.0,    0.0,
4629            -0.5,    0.5,    0.1,    0.0,    1.0,
4630             0.5,   -0.5,    0.1,    1.0,    0.0,
4631             0.5,    0.5,    0.1,    1.0,    1.0
4632         };
4633
4634         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4635         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4636         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4637         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4638         hr = IDirect3DDevice9_EndScene(device);
4639         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4640     }
4641     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4642     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4643     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4644     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4645     IDirect3DTexture9_Release(texture);
4646
4647     color = getPixelColor(device, 200, 200);
4648     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4649     color = getPixelColor(device, 280, 200);
4650     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4651     color = getPixelColor(device, 360, 200);
4652     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4653     color = getPixelColor(device, 440, 200);
4654     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4655     color = getPixelColor(device, 200, 270);
4656     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4657     color = getPixelColor(device, 280, 270);
4658     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4659     color = getPixelColor(device, 360, 270);
4660     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4661     color = getPixelColor(device, 440, 270);
4662     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4663     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4664     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4665 }
4666
4667 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4668 {
4669     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4670     IDirect3DVertexDeclaration9 *decl;
4671     HRESULT hr;
4672     DWORD color;
4673     DWORD shader_code_11[] =  {
4674         0xfffe0101,                                         /* vs_1_1           */
4675         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4676         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4677         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4678         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4679         0x0000ffff                                          /* end              */
4680     };
4681     DWORD shader_code_11_2[] =  {
4682         0xfffe0101,                                         /* vs_1_1           */
4683         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4684         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4685         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4686         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4687         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4688         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4689         0x0000ffff                                          /* end              */
4690     };
4691     DWORD shader_code_20[] =  {
4692         0xfffe0200,                                         /* vs_2_0           */
4693         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4694         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4695         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4696         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4697         0x0000ffff                                          /* end              */
4698     };
4699     DWORD shader_code_20_2[] =  {
4700         0xfffe0200,                                         /* vs_2_0           */
4701         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4702         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4703         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4704         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4705         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4706         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4707         0x0000ffff                                          /* end              */
4708     };
4709     static const D3DVERTEXELEMENT9 decl_elements[] = {
4710         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4711         D3DDECL_END()
4712     };
4713     float quad1[] = {
4714         -1.0,   -1.0,   0.1,
4715          0.0,   -1.0,   0.1,
4716         -1.0,    0.0,   0.1,
4717          0.0,    0.0,   0.1
4718     };
4719     float quad2[] = {
4720          0.0,   -1.0,   0.1,
4721          1.0,   -1.0,   0.1,
4722          0.0,    0.0,   0.1,
4723          1.0,    0.0,   0.1
4724     };
4725     float quad3[] = {
4726          0.0,    0.0,   0.1,
4727          1.0,    0.0,   0.1,
4728          0.0,    1.0,   0.1,
4729          1.0,    1.0,   0.1
4730     };
4731     float quad4[] = {
4732         -1.0,    0.0,   0.1,
4733          0.0,    0.0,   0.1,
4734         -1.0,    1.0,   0.1,
4735          0.0,    1.0,   0.1
4736     };
4737     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4738     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4739
4740     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4741     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4742
4743     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4744     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4745     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4746     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4747     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4748     if(FAILED(hr)) shader_20 = NULL;
4749     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4750     if(FAILED(hr)) shader_20_2 = NULL;
4751     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4752     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4753
4754     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4755     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4756     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4757     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4758     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4759     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4760
4761     hr = IDirect3DDevice9_BeginScene(device);
4762     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4763     if(SUCCEEDED(hr))
4764     {
4765         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4766         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4767         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4768         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4769
4770         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4771         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4772         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4773         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4774
4775         if(shader_20) {
4776             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4777             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4778             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4779             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4780         }
4781
4782         if(shader_20_2) {
4783             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4784             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4785             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4786             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4787         }
4788
4789         hr = IDirect3DDevice9_EndScene(device);
4790         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4791     }
4792
4793     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4794     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4795     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4796     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4797
4798     color = getPixelColor(device, 160, 360);
4799     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4800        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4801     color = getPixelColor(device, 480, 360);
4802     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4803        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4804     if(shader_20) {
4805         color = getPixelColor(device, 160, 120);
4806         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4807            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4808     }
4809     if(shader_20_2) {
4810         color = getPixelColor(device, 480, 120);
4811         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4812            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4813     }
4814     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4815     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4816
4817     IDirect3DVertexDeclaration9_Release(decl);
4818     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4819     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4820     IDirect3DVertexShader9_Release(shader_11_2);
4821     IDirect3DVertexShader9_Release(shader_11);
4822 }
4823
4824 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4825 {
4826     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4827     HRESULT hr;
4828     DWORD color;
4829     DWORD shader_code_11[] =  {
4830         0xffff0101,                                         /* ps_1_1           */
4831         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4832         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4833         0x0000ffff                                          /* end              */
4834     };
4835     DWORD shader_code_12[] =  {
4836         0xffff0102,                                         /* ps_1_2           */
4837         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4838         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4839         0x0000ffff                                          /* end              */
4840     };
4841     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4842      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4843      * During development of this test, 1.3 shaders were verified too
4844      */
4845     DWORD shader_code_14[] =  {
4846         0xffff0104,                                         /* ps_1_4           */
4847         /* Try to make one constant local. It gets clamped too, although the binary contains
4848          * the bigger numbers
4849          */
4850         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4851         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4852         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4853         0x0000ffff                                          /* end              */
4854     };
4855     DWORD shader_code_20[] =  {
4856         0xffff0200,                                         /* ps_2_0           */
4857         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4858         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4859         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
4860         0x0000ffff                                          /* end              */
4861     };
4862     float quad1[] = {
4863         -1.0,   -1.0,   0.1,
4864          0.0,   -1.0,   0.1,
4865         -1.0,    0.0,   0.1,
4866          0.0,    0.0,   0.1
4867     };
4868     float quad2[] = {
4869          0.0,   -1.0,   0.1,
4870          1.0,   -1.0,   0.1,
4871          0.0,    0.0,   0.1,
4872          1.0,    0.0,   0.1
4873     };
4874     float quad3[] = {
4875          0.0,    0.0,   0.1,
4876          1.0,    0.0,   0.1,
4877          0.0,    1.0,   0.1,
4878          1.0,    1.0,   0.1
4879     };
4880     float quad4[] = {
4881         -1.0,    0.0,   0.1,
4882          0.0,    0.0,   0.1,
4883         -1.0,    1.0,   0.1,
4884          0.0,    1.0,   0.1
4885     };
4886     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4887     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4888
4889     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4890     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4891
4892     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4893     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4894     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4895     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4896     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4897     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4898     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4899     if(FAILED(hr)) shader_20 = NULL;
4900
4901     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4902     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4903     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4904     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4905     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4906     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4907
4908     hr = IDirect3DDevice9_BeginScene(device);
4909     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4910     if(SUCCEEDED(hr))
4911     {
4912         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4913         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4914         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4915         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4916
4917         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4918         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4919         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4920         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4921
4922         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4923         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4924         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4925         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4926
4927         if(shader_20) {
4928             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4929             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4930             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4931             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4932         }
4933
4934         hr = IDirect3DDevice9_EndScene(device);
4935         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4936     }
4937     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4938     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4939
4940     color = getPixelColor(device, 160, 360);
4941     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4942        "quad 1 has color %08x, expected 0x00808000\n", color);
4943     color = getPixelColor(device, 480, 360);
4944     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4945        "quad 2 has color %08x, expected 0x00808000\n", color);
4946     color = getPixelColor(device, 480, 120);
4947     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4948        "quad 3 has color %08x, expected 0x00808000\n", color);
4949     if(shader_20) {
4950         color = getPixelColor(device, 160, 120);
4951         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4952            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4953     }
4954     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4955     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4956
4957     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4958     IDirect3DPixelShader9_Release(shader_14);
4959     IDirect3DPixelShader9_Release(shader_12);
4960     IDirect3DPixelShader9_Release(shader_11);
4961 }
4962
4963 static void dp2add_ps_test(IDirect3DDevice9 *device)
4964 {
4965     IDirect3DPixelShader9 *shader_dp2add = NULL;
4966     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4967     HRESULT hr;
4968     DWORD color;
4969
4970     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
4971      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4972      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
4973      * r0 first.
4974      * The result here for the r,g,b components should be roughly 0.5:
4975      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4976     static const DWORD shader_code_dp2add[] =  {
4977         0xffff0200,                                                             /* ps_2_0                       */
4978         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
4979
4980         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
4981         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
4982
4983         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
4984         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
4985         0x0000ffff                                                              /* end                          */
4986     };
4987
4988     /* Test the _sat modifier, too.  Result here should be:
4989      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4990      *      _SAT: ==> 1.0
4991      *   ADD: (1.0 + -0.5) = 0.5
4992      */
4993     static const DWORD shader_code_dp2add_sat[] =  {
4994         0xffff0200,                                                             /* ps_2_0                           */
4995         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
4996
4997         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
4998         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
4999         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
5000
5001         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
5002         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
5003         0x0000ffff                                                              /* end                              */
5004     };
5005
5006     const float quad[] = {
5007         -1.0,   -1.0,   0.1,
5008          1.0,   -1.0,   0.1,
5009         -1.0,    1.0,   0.1,
5010          1.0,    1.0,   0.1
5011     };
5012
5013
5014     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
5015     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5016
5017     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
5018     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5019
5020     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
5021     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5022
5023     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5024     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5025
5026     if (shader_dp2add) {
5027
5028         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5029         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5030
5031         hr = IDirect3DDevice9_BeginScene(device);
5032         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5033         if(SUCCEEDED(hr))
5034         {
5035             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5036             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5037
5038             hr = IDirect3DDevice9_EndScene(device);
5039             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5040         }
5041
5042         color = getPixelColor(device, 360, 240);
5043         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5044                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5045
5046         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5047         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5048
5049         IDirect3DPixelShader9_Release(shader_dp2add);
5050     } else {
5051         skip("dp2add shader creation failed\n");
5052     }
5053
5054     if (shader_dp2add_sat) {
5055
5056         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5057         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5058
5059         hr = IDirect3DDevice9_BeginScene(device);
5060         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5061         if(SUCCEEDED(hr))
5062         {
5063             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5064             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5065
5066             hr = IDirect3DDevice9_EndScene(device);
5067             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5068         }
5069
5070         color = getPixelColor(device, 360, 240);
5071         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5072                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5073
5074         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5075         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5076
5077         IDirect3DPixelShader9_Release(shader_dp2add_sat);
5078     } else {
5079         skip("dp2add shader creation failed\n");
5080     }
5081
5082     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5083     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5084 }
5085
5086 static void cnd_test(IDirect3DDevice9 *device)
5087 {
5088     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
5089     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
5090     HRESULT hr;
5091     DWORD color;
5092     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
5093      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
5094      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
5095      */
5096     DWORD shader_code_11[] =  {
5097         0xffff0101,                                                                 /* ps_1_1               */
5098         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5099         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5100         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
5101         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5102         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5103         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5104         0x0000ffff                                                                  /* end                  */
5105     };
5106     DWORD shader_code_12[] =  {
5107         0xffff0102,                                                                 /* ps_1_2               */
5108         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5109         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5110         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5111         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5112         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5113         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5114         0x0000ffff                                                                  /* end                  */
5115     };
5116     DWORD shader_code_13[] =  {
5117         0xffff0103,                                                                 /* ps_1_3               */
5118         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5119         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5120         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5121         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
5122         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5123         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5124         0x0000ffff                                                                  /* end                  */
5125     };
5126     DWORD shader_code_14[] =  {
5127         0xffff0104,                                                                 /* ps_1_3               */
5128         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
5129         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
5130         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
5131         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
5132         0x0000ffff                                                                  /* end                  */
5133     };
5134
5135     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
5136      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
5137      * set by the compiler, it was added manually after compilation. It isn't always allowed,
5138      * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
5139      * native CreatePixelShader returns an error.
5140      *
5141      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
5142      * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
5143      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
5144      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
5145      */
5146     DWORD shader_code_11_coissue[] =  {
5147         0xffff0101,                                                             /* ps_1_1                   */
5148         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5149         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5150         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5151         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5152         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5153         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5154         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5155         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5156         /* 0x40000000 = D3DSI_COISSUE */
5157         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5158         0x0000ffff                                                              /* end                      */
5159     };
5160     DWORD shader_code_12_coissue[] =  {
5161         0xffff0102,                                                             /* ps_1_2                   */
5162         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5163         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5164         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5165         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5166         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5167         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5168         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5169         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5170         /* 0x40000000 = D3DSI_COISSUE */
5171         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5172         0x0000ffff                                                              /* end                      */
5173     };
5174     DWORD shader_code_13_coissue[] =  {
5175         0xffff0103,                                                             /* ps_1_3                   */
5176         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5177         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5178         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5179         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5180         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5181         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5182         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5183         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5184         /* 0x40000000 = D3DSI_COISSUE */
5185         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5186         0x0000ffff                                                              /* end                      */
5187     };
5188     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
5189      * compare against 0.5
5190      */
5191     DWORD shader_code_14_coissue[] =  {
5192         0xffff0104,                                                             /* ps_1_4                   */
5193         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
5194         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
5195         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
5196         /* 0x40000000 = D3DSI_COISSUE */
5197         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
5198         0x0000ffff                                                              /* end                      */
5199     };
5200     float quad1[] = {
5201         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5202          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5203         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5204          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
5205     };
5206     float quad2[] = {
5207          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5208          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5209          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5210          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
5211     };
5212     float quad3[] = {
5213          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5214          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5215          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5216          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
5217     };
5218     float quad4[] = {
5219         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5220          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5221         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5222          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
5223     };
5224     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
5225     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
5226     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
5227     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
5228
5229     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5230     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5231
5232     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5233     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5234     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5235     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5236     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
5237     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5238     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5239     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5240     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
5241     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5242     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5243     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5244     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5245     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5246     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5247     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5248
5249     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5250     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5251     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5252     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5253     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5254     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5255
5256     hr = IDirect3DDevice9_BeginScene(device);
5257     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5258     if(SUCCEEDED(hr))
5259     {
5260         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5261         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5262         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5263         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5264
5265         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5266         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5267         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5268         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5269
5270         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5271         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5272         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5273         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5274
5275         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5276         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5277         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5278         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5279
5280         hr = IDirect3DDevice9_EndScene(device);
5281         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5282     }
5283
5284     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5285     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5286
5287     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5288     color = getPixelColor(device, 158, 118);
5289     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5290     color = getPixelColor(device, 162, 118);
5291     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5292     color = getPixelColor(device, 158, 122);
5293     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5294     color = getPixelColor(device, 162, 122);
5295     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5296
5297     /* 1.1 shader. All 3 components get set, based on the .w comparison */
5298     color = getPixelColor(device, 158, 358);
5299     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5300     color = getPixelColor(device, 162, 358);
5301     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5302         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5303     color = getPixelColor(device, 158, 362);
5304     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5305     color = getPixelColor(device, 162, 362);
5306     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5307         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5308
5309     /* 1.2 shader */
5310     color = getPixelColor(device, 478, 358);
5311     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5312     color = getPixelColor(device, 482, 358);
5313     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5314         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5315     color = getPixelColor(device, 478, 362);
5316     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5317     color = getPixelColor(device, 482, 362);
5318     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5319         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5320
5321     /* 1.3 shader */
5322     color = getPixelColor(device, 478, 118);
5323     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5324     color = getPixelColor(device, 482, 118);
5325     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5326         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5327     color = getPixelColor(device, 478, 122);
5328     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5329     color = getPixelColor(device, 482, 122);
5330     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5331         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5332
5333     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5334     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5335
5336     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5337     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5338     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5339     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5340     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5341     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5342
5343     hr = IDirect3DDevice9_BeginScene(device);
5344     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5345     if(SUCCEEDED(hr))
5346     {
5347         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5348         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5349         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5350         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5351
5352         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5353         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5354         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5355         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5356
5357         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5358         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5359         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5360         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5361
5362         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5363         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5364         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5365         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5366
5367         hr = IDirect3DDevice9_EndScene(device);
5368         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5369     }
5370
5371     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5372     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5373
5374     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5375      * that we swapped the values in c1 and c2 to make the other tests return some color
5376      */
5377     color = getPixelColor(device, 158, 118);
5378     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5379     color = getPixelColor(device, 162, 118);
5380     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5381     color = getPixelColor(device, 158, 122);
5382     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5383     color = getPixelColor(device, 162, 122);
5384     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5385
5386     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
5387     color = getPixelColor(device, 158, 358);
5388     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5389         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5390     color = getPixelColor(device, 162, 358);
5391     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5392         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5393     color = getPixelColor(device, 158, 362);
5394     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5395         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5396     color = getPixelColor(device, 162, 362);
5397     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5398         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5399
5400     /* 1.2 shader */
5401     color = getPixelColor(device, 478, 358);
5402     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5403         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5404     color = getPixelColor(device, 482, 358);
5405     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5406         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5407     color = getPixelColor(device, 478, 362);
5408     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5409         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5410     color = getPixelColor(device, 482, 362);
5411     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5412         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5413
5414     /* 1.3 shader */
5415     color = getPixelColor(device, 478, 118);
5416     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5417         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5418     color = getPixelColor(device, 482, 118);
5419     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5420         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5421     color = getPixelColor(device, 478, 122);
5422     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5423         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5424     color = getPixelColor(device, 482, 122);
5425     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5426         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5427
5428     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5429     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5430
5431     IDirect3DPixelShader9_Release(shader_14_coissue);
5432     IDirect3DPixelShader9_Release(shader_13_coissue);
5433     IDirect3DPixelShader9_Release(shader_12_coissue);
5434     IDirect3DPixelShader9_Release(shader_11_coissue);
5435     IDirect3DPixelShader9_Release(shader_14);
5436     IDirect3DPixelShader9_Release(shader_13);
5437     IDirect3DPixelShader9_Release(shader_12);
5438     IDirect3DPixelShader9_Release(shader_11);
5439 }
5440
5441 static void nested_loop_test(IDirect3DDevice9 *device) {
5442     const DWORD shader_code[] = {
5443         0xffff0300,                                                             /* ps_3_0               */
5444         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
5445         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5446         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
5447         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
5448         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5449         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5450         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
5451         0x0000001d,                                                             /* endloop              */
5452         0x0000001d,                                                             /* endloop              */
5453         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
5454         0x0000ffff                                                              /* end                  */
5455     };
5456     IDirect3DPixelShader9 *shader;
5457     HRESULT hr;
5458     DWORD color;
5459     const float quad[] = {
5460         -1.0,   -1.0,   0.1,
5461          1.0,   -1.0,   0.1,
5462         -1.0,    1.0,   0.1,
5463          1.0,    1.0,   0.1
5464     };
5465
5466     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5467     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5468     hr = IDirect3DDevice9_SetPixelShader(device, shader);
5469     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5470     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5471     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5472     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5473     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5474
5475     hr = IDirect3DDevice9_BeginScene(device);
5476     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5477     if(SUCCEEDED(hr))
5478     {
5479         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5480         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5481         hr = IDirect3DDevice9_EndScene(device);
5482         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5483     }
5484
5485     color = getPixelColor(device, 360, 240);
5486     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5487        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5488
5489     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5490     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5491
5492     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5493     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5494     IDirect3DPixelShader9_Release(shader);
5495 }
5496
5497 struct varying_test_struct
5498 {
5499     const DWORD             *shader_code;
5500     IDirect3DPixelShader9   *shader;
5501     DWORD                   color, color_rhw;
5502     const char              *name;
5503     BOOL                    todo, todo_rhw;
5504 };
5505
5506 struct hugeVertex
5507 {
5508     float pos_x,        pos_y,      pos_z,      rhw;
5509     float weight_1,     weight_2,   weight_3,   weight_4;
5510     float index_1,      index_2,    index_3,    index_4;
5511     float normal_1,     normal_2,   normal_3,   normal_4;
5512     float fog_1,        fog_2,      fog_3,      fog_4;
5513     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
5514     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
5515     float binormal_1,   binormal_2, binormal_3, binormal_4;
5516     float depth_1,      depth_2,    depth_3,    depth_4;
5517     DWORD diffuse, specular;
5518 };
5519
5520 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5521     /* dcl_position: fails to compile */
5522     const DWORD blendweight_code[] = {
5523         0xffff0300,                             /* ps_3_0                   */
5524         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
5525         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5526         0x0000ffff                              /* end                      */
5527     };
5528     const DWORD blendindices_code[] = {
5529         0xffff0300,                             /* ps_3_0                   */
5530         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
5531         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5532         0x0000ffff                              /* end                      */
5533     };
5534     const DWORD normal_code[] = {
5535         0xffff0300,                             /* ps_3_0                   */
5536         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
5537         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5538         0x0000ffff                              /* end                      */
5539     };
5540     /* psize: fails? */
5541     const DWORD texcoord0_code[] = {
5542         0xffff0300,                             /* ps_3_0                   */
5543         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
5544         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5545         0x0000ffff                              /* end                      */
5546     };
5547     const DWORD tangent_code[] = {
5548         0xffff0300,                             /* ps_3_0                   */
5549         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
5550         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5551         0x0000ffff                              /* end                      */
5552     };
5553     const DWORD binormal_code[] = {
5554         0xffff0300,                             /* ps_3_0                   */
5555         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
5556         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5557         0x0000ffff                              /* end                      */
5558     };
5559     /* tessfactor: fails */
5560     /* positiont: fails */
5561     const DWORD color_code[] = {
5562         0xffff0300,                             /* ps_3_0                   */
5563         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
5564         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5565         0x0000ffff                              /* end                      */
5566     };
5567     const DWORD fog_code[] = {
5568         0xffff0300,                             /* ps_3_0                   */
5569         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
5570         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5571         0x0000ffff                              /* end                      */
5572     };
5573     const DWORD depth_code[] = {
5574         0xffff0300,                             /* ps_3_0                   */
5575         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
5576         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5577         0x0000ffff                              /* end                      */
5578     };
5579     const DWORD specular_code[] = {
5580         0xffff0300,                             /* ps_3_0                   */
5581         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
5582         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5583         0x0000ffff                              /* end                      */
5584     };
5585     /* sample: fails */
5586
5587     struct varying_test_struct tests[] = {
5588        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
5589        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
5590        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
5591        /* Why does dx not forward the texcoord? */
5592        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
5593        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
5594        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
5595        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
5596        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
5597        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
5598        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
5599     };
5600     /* Declare a monster vertex type :-) */
5601     static const D3DVERTEXELEMENT9 decl_elements[] = {
5602         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5603         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5604         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5605         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5606         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5607         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5608         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5609         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5610         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5611         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5612         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5613         D3DDECL_END()
5614     };
5615     static const D3DVERTEXELEMENT9 decl_elements2[] = {
5616         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
5617         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5618         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5619         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5620         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5621         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5622         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5623         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5624         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5625         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5626         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5627         D3DDECL_END()
5628     };
5629     struct hugeVertex data[4] = {
5630         {
5631             -1.0,   -1.0,   0.1,    1.0,
5632              0.1,    0.1,   0.1,    0.1,
5633              0.2,    0.2,   0.2,    0.2,
5634              0.3,    0.3,   0.3,    0.3,
5635              0.4,    0.4,   0.4,    0.4,
5636              0.50,   0.55,  0.55,   0.55,
5637              0.6,    0.6,   0.6,    0.7,
5638              0.7,    0.7,   0.7,    0.6,
5639              0.8,    0.8,   0.8,    0.8,
5640              0xe6e6e6e6, /* 0.9 * 256 */
5641              0x224488ff  /* Nothing special */
5642         },
5643         {
5644              1.0,   -1.0,   0.1,    1.0,
5645              0.1,    0.1,   0.1,    0.1,
5646              0.2,    0.2,   0.2,    0.2,
5647              0.3,    0.3,   0.3,    0.3,
5648              0.4,    0.4,   0.4,    0.4,
5649              0.50,   0.55,  0.55,   0.55,
5650              0.6,    0.6,   0.6,    0.7,
5651              0.7,    0.7,   0.7,    0.6,
5652              0.8,    0.8,   0.8,    0.8,
5653              0xe6e6e6e6, /* 0.9 * 256 */
5654              0x224488ff /* Nothing special */
5655         },
5656         {
5657             -1.0,    1.0,   0.1,    1.0,
5658              0.1,    0.1,   0.1,    0.1,
5659              0.2,    0.2,   0.2,    0.2,
5660              0.3,    0.3,   0.3,    0.3,
5661              0.4,    0.4,   0.4,    0.4,
5662              0.50,   0.55,  0.55,   0.55,
5663              0.6,    0.6,   0.6,    0.7,
5664              0.7,    0.7,   0.7,    0.6,
5665              0.8,    0.8,   0.8,    0.8,
5666              0xe6e6e6e6, /* 0.9 * 256 */
5667              0x224488ff /* Nothing special */
5668         },
5669         {
5670              1.0,    1.0,   0.1,    1.0,
5671              0.1,    0.1,   0.1,    0.1,
5672              0.2,    0.2,   0.2,    0.2,
5673              0.3,    0.3,   0.3,    0.3,
5674              0.4,    0.4,   0.4,    0.4,
5675              0.50,   0.55,  0.55,   0.55,
5676              0.6,    0.6,   0.6,    0.7,
5677              0.7,    0.7,   0.7,    0.6,
5678              0.8,    0.8,   0.8,    0.8,
5679              0xe6e6e6e6, /* 0.9 * 256 */
5680              0x224488ff /* Nothing special */
5681         },
5682     };
5683     struct hugeVertex data2[4];
5684     IDirect3DVertexDeclaration9 *decl;
5685     IDirect3DVertexDeclaration9 *decl2;
5686     HRESULT hr;
5687     unsigned int i;
5688     DWORD color, r, g, b, r_e, g_e, b_e;
5689     BOOL drawok;
5690
5691     memcpy(data2, data, sizeof(data2));
5692     data2[0].pos_x = 0;     data2[0].pos_y = 0;
5693     data2[1].pos_x = 640;   data2[1].pos_y = 0;
5694     data2[2].pos_x = 0;     data2[2].pos_y = 480;
5695     data2[3].pos_x = 640;   data2[3].pos_y = 480;
5696
5697     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5698     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5699     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5700     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5701     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5702     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5703
5704     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5705     {
5706         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5707         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5708            tests[i].name, hr);
5709     }
5710
5711     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5712     {
5713         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5714         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5715
5716         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5717         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5718
5719         hr = IDirect3DDevice9_BeginScene(device);
5720         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5721         drawok = FALSE;
5722         if(SUCCEEDED(hr))
5723         {
5724             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5725             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5726             drawok = SUCCEEDED(hr);
5727             hr = IDirect3DDevice9_EndScene(device);
5728             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5729         }
5730
5731         /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5732          * the failure and do not check the color if it failed
5733          */
5734         if(!drawok) {
5735             continue;
5736         }
5737
5738         color = getPixelColor(device, 360, 240);
5739         r = color & 0x00ff0000 >> 16;
5740         g = color & 0x0000ff00 >>  8;
5741         b = color & 0x000000ff;
5742         r_e = tests[i].color & 0x00ff0000 >> 16;
5743         g_e = tests[i].color & 0x0000ff00 >>  8;
5744         b_e = tests[i].color & 0x000000ff;
5745
5746         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5747         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5748
5749         if(tests[i].todo) {
5750             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5751                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5752                          tests[i].name, color, tests[i].color);
5753         } else {
5754             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5755                "Test %s returned color 0x%08x, expected 0x%08x\n",
5756                tests[i].name, color, tests[i].color);
5757         }
5758     }
5759
5760     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5761     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5762     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5763     {
5764         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5765         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5766
5767         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5768         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5769
5770         hr = IDirect3DDevice9_BeginScene(device);
5771         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5772         if(SUCCEEDED(hr))
5773         {
5774             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5775             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5776             hr = IDirect3DDevice9_EndScene(device);
5777             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5778         }
5779
5780         color = getPixelColor(device, 360, 240);
5781         r = color & 0x00ff0000 >> 16;
5782         g = color & 0x0000ff00 >>  8;
5783         b = color & 0x000000ff;
5784         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5785         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
5786         b_e = tests[i].color_rhw & 0x000000ff;
5787
5788         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5789         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5790
5791         if(tests[i].todo_rhw) {
5792             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5793              * pipeline
5794              */
5795             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5796                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5797                          tests[i].name, color, tests[i].color_rhw);
5798         } else {
5799             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5800                "Test %s returned color 0x%08x, expected 0x%08x\n",
5801                tests[i].name, color, tests[i].color_rhw);
5802         }
5803     }
5804
5805     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5806     {
5807         IDirect3DPixelShader9_Release(tests[i].shader);
5808     }
5809
5810     IDirect3DVertexDeclaration9_Release(decl2);
5811     IDirect3DVertexDeclaration9_Release(decl);
5812 }
5813
5814 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5815     static const DWORD ps_code[] = {
5816     0xffff0300,                                                             /* ps_3_0                       */
5817     0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0          */
5818     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5819     0x0200001f, 0x8001000a, 0x900f0003,                                     /* dcl_color1 v3                */
5820     0x0200001f, 0x8000000b, 0x900f0004,                                     /* dcl_fog v4                   */
5821     0x0200001f, 0x80030005, 0x900f0005,                                     /* dcl_texcoord3 v5             */
5822     0x0200001f, 0x80000003, 0x900f0006,                                     /* dcl_normal v6                */
5823     0x0200001f, 0x80000006, 0x900f0007,                                     /* dcl_tangent v7               */
5824     0x0200001f, 0x80000001, 0x900f0008,                                     /* dcl_blendweight v8           */
5825     0x0200001f, 0x8000000c, 0x900f0009,                                     /* dcl_depth v9                 */
5826
5827     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5828     0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0                  */
5829     0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800,             /* add r0, r0, v0[aL]           */
5830     0x0000001d,                                                             /* endloop                      */
5831     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5832     0x0000ffff                                                              /* end                          */
5833     };
5834     static const DWORD vs_1_code[] = {
5835     0xfffe0101,                                                             /* vs_1_1                       */
5836     0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5837     0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5838     0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5839     0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5840     0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5841     0x00000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5842     0x00000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5843     0x00000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5844     0x00000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5845     0x00000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5846     0x00000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5847     0x00000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5848     0x00000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5849     0x00000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5850     0x00000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5851     0x00000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5852     0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5853     0x0000ffff
5854     };
5855     DWORD vs_2_code[] = {
5856     0xfffe0200,                                                             /* vs_2_0                       */
5857     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5858     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5859     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5860     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5861     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5862     0x02000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5863     0x02000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5864     0x02000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5865     0x02000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5866     0x02000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5867     0x02000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5868     0x02000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5869     0x02000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5870     0x02000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5871     0x02000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5872     0x02000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5873     0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5874     0x0000ffff                                                              /* end                          */
5875     };
5876     /* TODO: Define normal, tangent, blendweight and depth here */
5877     static const DWORD vs_3_code[] = {
5878     0xfffe0300,                                                             /* vs_3_0                       */
5879     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5880     0x0200001f, 0x8001000a, 0xe00f0009,                                     /* dcl_color1 o9                */
5881     0x0200001f, 0x8000000b, 0xe00f0002,                                     /* dcl_fog o2                   */
5882     0x0200001f, 0x80030005, 0xe00f0005,                                     /* dcl_texcoord3 o5             */
5883     0x0200001f, 0x80000000, 0xe00f000b,                                     /* dcl_position o11             */
5884     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5885     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5886     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5887     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5888     0x02000001, 0xe00f0009, 0xa0e40000,                                     /* mov o9, c0                   */
5889     0x02000001, 0xe00f0002, 0xa0e40001,                                     /* mov o2, c1                   */
5890     0x02000001, 0xe00f0005, 0xa0e40002,                                     /* mov o5, c2                   */
5891     0x02000001, 0xe00f000b, 0x90e40000,                                     /* mov o11, v0                  */
5892     0x0000ffff                                                              /* end                          */
5893     };
5894     float quad1[] =  {
5895         -1.0,   -1.0,   0.1,
5896          0.0,   -1.0,   0.1,
5897         -1.0,    0.0,   0.1,
5898          0.0,    0.0,   0.1
5899     };
5900     float quad2[] =  {
5901          0.0,   -1.0,   0.1,
5902          1.0,   -1.0,   0.1,
5903          0.0,    0.0,   0.1,
5904          1.0,    0.0,   0.1
5905     };
5906     float quad3[] =  {
5907         -1.0,    0.0,   0.1,
5908          0.0,    0.0,   0.1,
5909         -1.0,    1.0,   0.1,
5910          0.0,    1.0,   0.1
5911     };
5912
5913     HRESULT hr;
5914     DWORD color;
5915     IDirect3DPixelShader9 *pixelshader = NULL;
5916     IDirect3DVertexShader9 *vs_1_shader = NULL;
5917     IDirect3DVertexShader9 *vs_2_shader = NULL;
5918     IDirect3DVertexShader9 *vs_3_shader = NULL;
5919
5920     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5921     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5922
5923     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5924     ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %08x\n", hr);
5925     hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5926     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5927     hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5928     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5929     hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5930     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5931     hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5932     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5933     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5934
5935     hr = IDirect3DDevice9_BeginScene(device);
5936     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5937     if(SUCCEEDED(hr))
5938     {
5939         hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5940         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5941         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5942         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5943
5944         hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5945         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5946         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5947         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5948
5949         hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5950         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5951         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5952         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5953
5954         hr = IDirect3DDevice9_EndScene(device);
5955         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5956     }
5957
5958     color = getPixelColor(device, 160, 120);
5959     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x1a, 0x34, 0x67), 1),
5960        "vs_3_0 returned color 0x%08x, expected 0x00193366\n", color);
5961     /* Accept two ways of oFog handling:
5962      *
5963      * oFog is supposed to be a scalar. The pixel shader declares a vec4 oFog input and reads all components.
5964      * The vertex shader writes oFog without a writemask. There are two ways windows drivers deal with this:
5965      *
5966      * 1) Keep oFog a scalar, and assign v4 = {oFog, 0, 0, 0}. oFog = 0x33, so the result color is 004d0067.
5967      *    This happens with software vertex processing and on Intel cards
5968      *
5969      * 2) Make oFog a vec4, and assign v4 = {oFog.x, oFog.y, oFog.z, oFog.w}. This way the result color is
5970      *    0x004d339a. This happens on Nvidia Geforce 6+ cards
5971      */
5972     color = getPixelColor(device, 160, 360);
5973     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5974        color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5975        "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5976     color = getPixelColor(device, 480, 360);
5977     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5978        color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5979        "vs_2_0 returned color 0x%08x, expected 0x004d0067 or 0x004d33a0\n", color);
5980
5981     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5982     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5983
5984     /* cleanup */
5985     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5986     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5987     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5988     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5989     if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5990     if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5991     if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5992     if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5993 }
5994
5995 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5996     static const DWORD vs_code[] = {
5997     0xfffe0300,                                                             /* vs_3_0                       */
5998     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5999     0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0              */
6000     0x0200001f, 0x8000000a, 0xe00f0001,                                     /* dcl_color0 o1                */
6001     0x0200001f, 0x80000005, 0xe00f0002,                                     /* dcl_texcoord0 o2             */
6002     0x0200001f, 0x8000000b, 0xe00f0003,                                     /* dcl_fog o3                   */
6003     0x0200001f, 0x80000003, 0xe00f0004,                                     /* dcl_normal o4                */
6004     0x0200001f, 0x8000000c, 0xe00f0005,                                     /* dcl_depth o5                 */
6005     0x0200001f, 0x80000006, 0xe00f0006,                                     /* dcl_tangent o6               */
6006     0x0200001f, 0x80000001, 0xe00f0007,                                     /* dcl_blendweight o7           */
6007     0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0   */
6008     0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0   */
6009     0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0   */
6010     0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0   */
6011
6012     0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                   */
6013     0x02000001, 0xe00f0001, 0xa0e40001,                                     /* mov o1, c1                   */
6014     0x02000001, 0xe00f0002, 0xa0e40002,                                     /* mov o2, c2                   */
6015     0x02000001, 0xe00f0003, 0xa0e40003,                                     /* mov o3, c3                   */
6016     0x02000001, 0xe00f0004, 0xa0e40000,                                     /* mov o4, c0                   */
6017     0x02000001, 0xe00f0005, 0xa0e40000,                                     /* mov o5, c0                   */
6018     0x02000001, 0xe00f0006, 0xa0e40000,                                     /* mov o6, c0                   */
6019     0x02000001, 0xe00f0007, 0xa0e40000,                                     /* mov o7, c0                   */
6020     0x0000ffff                                                              /* end                          */
6021     };
6022     static const DWORD ps_1_code[] = {
6023     0xffff0104,                                                             /* ps_1_4                       */
6024     0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
6025     0x00000040, 0x80070001, 0xb0e40000,                                     /* texcrd r1.xyz, t0            */
6026     0x00000001, 0x80080001, 0xa0ff0000,                                     /* mov r1.a, c0.a               */
6027     0x00000002, 0x800f0000, 0x90e40000, 0x80e40001,                         /* add r0, v0, r1               */
6028     0x0000ffff                                                              /* end                          */
6029     };
6030     static const DWORD ps_2_code[] = {
6031     0xffff0200,                                                             /* ps_2_0                       */
6032     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
6033     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl v0                       */
6034     0x0200001f, 0x80000000, 0x900f0001,                                     /* dcl v1                       */
6035
6036     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
6037     0x03000002, 0x800f0000, 0x80e40000,0xb0e40000,                          /* add r0, r0, t0               */
6038     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
6039     0x0000ffff                                                              /* end                          */
6040     };
6041     static const DWORD ps_3_code[] = {
6042     0xffff0300,                                                             /* ps_3_0                       */
6043     0x0200001f, 0x80000005, 0x900f0000,                                     /* dcl_texcoord0 v0             */
6044     0x0200001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
6045     0x0200001f, 0x8000000b, 0x900f0002,                                     /* dcl_fog v2                   */
6046
6047     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
6048     0x03000002, 0x800f0000, 0x80e40000, 0x90e40001,                         /* add r0, r0, v1               */
6049     0x03000002, 0x800f0000, 0x80e40000, 0x90e40002,                         /* mov r0, r0, v2               */
6050     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
6051     0x0000ffff                                                              /* end                          */
6052     };
6053
6054     float quad1[] =  {
6055         -1.0,   -1.0,   0.1,
6056          0.0,   -1.0,   0.1,
6057         -1.0,    0.0,   0.1,
6058          0.0,    0.0,   0.1
6059     };
6060     float quad2[] =  {
6061          0.0,   -1.0,   0.1,
6062          1.0,   -1.0,   0.1,
6063          0.0,    0.0,   0.1,
6064          1.0,    0.0,   0.1
6065     };
6066     float quad3[] =  {
6067         -1.0,    0.0,   0.1,
6068          0.0,    0.0,   0.1,
6069         -1.0,    1.0,   0.1,
6070          0.0,    1.0,   0.1
6071     };
6072     float quad4[] =  {
6073          0.0,    0.0,   0.1,
6074          1.0,    0.0,   0.1,
6075          0.0,    1.0,   0.1,
6076          1.0,    1.0,   0.1
6077     };
6078
6079     HRESULT hr;
6080     DWORD color;
6081     IDirect3DVertexShader9 *vertexshader = NULL;
6082     IDirect3DPixelShader9 *ps_1_shader = NULL;
6083     IDirect3DPixelShader9 *ps_2_shader = NULL;
6084     IDirect3DPixelShader9 *ps_3_shader = NULL;
6085     IDirect3DTexture9 *texture = NULL;
6086     D3DLOCKED_RECT lr;
6087     unsigned int x, y;
6088
6089     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6090     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6091
6092     hr = IDirect3DDevice9_CreateTexture(device, 512,  512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
6093     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
6094     if(FAILED(hr)) {
6095         skip("D3DFMT_A16B16G16R16 textures not supported\n");
6096         return;
6097     }
6098     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
6099     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
6100     for(y = 0; y < 512; y++) {
6101         for(x = 0; x < 512; x++) {
6102             double r_f = (double) x / (double) 512;
6103             double g_f = (double) y / (double) 512;
6104             unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
6105             unsigned short r = (unsigned short) (r_f * 65535.0);
6106             unsigned short g = (unsigned short) (g_f * 65535.0);
6107             dst[0] = r;
6108             dst[1] = g;
6109             dst[2] = 0;
6110             dst[3] = 65535;
6111         }
6112     }
6113     hr = IDirect3DTexture9_UnlockRect(texture, 0);
6114     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
6115
6116     hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
6117     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6118     hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
6119     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6120     hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
6121     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6122     hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
6123     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6124     hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
6125     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6126     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6127
6128     hr = IDirect3DDevice9_BeginScene(device);
6129     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6130     if(SUCCEEDED(hr))
6131     {
6132         hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
6133         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6134         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6135         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6136
6137         hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
6138         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6139         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
6140         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6141
6142         hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
6143         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6144         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6145         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6146
6147         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6148         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6149         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6150         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
6151         hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
6152         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
6153         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
6154         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
6155         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6156         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
6157         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
6158         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
6159         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6160         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6161
6162         hr = IDirect3DDevice9_EndScene(device);
6163         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6164     }
6165
6166     color = getPixelColor(device, 160, 120);
6167     ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
6168        (color & 0x0000ff00) == 0x0000ff00 &&
6169        (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
6170        "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
6171     color = getPixelColor(device, 160, 360);
6172     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
6173        (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
6174        (color & 0x000000ff) == 0x00000000,
6175        "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
6176     color = getPixelColor(device, 480, 360);
6177     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
6178        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
6179        (color & 0x000000ff) == 0x00000000,
6180        "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
6181     color = getPixelColor(device, 480, 160);
6182     ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
6183        (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
6184        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
6185        (color & 0x000000ff) == 0x00000000),
6186        "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
6187
6188     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6189     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6190
6191     /* cleanup */
6192     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6193     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
6194     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6195     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6196     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6197     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6198     if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
6199     if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
6200     if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
6201     if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
6202     if(texture) IDirect3DTexture9_Release(texture);
6203 }
6204
6205 static void test_compare_instructions(IDirect3DDevice9 *device)
6206 {
6207     DWORD shader_sge_vec_code[] = {
6208         0xfffe0101,                                         /* vs_1_1                   */
6209         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6210         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6211         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6212         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
6213         0x0000ffff                                          /* end                      */
6214     };
6215     DWORD shader_slt_vec_code[] = {
6216         0xfffe0101,                                         /* vs_1_1                   */
6217         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6218         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6219         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6220         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
6221         0x0000ffff                                          /* end                      */
6222     };
6223     DWORD shader_sge_scalar_code[] = {
6224         0xfffe0101,                                         /* vs_1_1                   */
6225         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6226         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6227         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6228         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
6229         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
6230         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
6231         0x0000ffff                                          /* end                      */
6232     };
6233     DWORD shader_slt_scalar_code[] = {
6234         0xfffe0101,                                         /* vs_1_1                   */
6235         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6236         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6237         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6238         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
6239         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
6240         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
6241         0x0000ffff                                          /* end                      */
6242     };
6243     IDirect3DVertexShader9 *shader_sge_vec;
6244     IDirect3DVertexShader9 *shader_slt_vec;
6245     IDirect3DVertexShader9 *shader_sge_scalar;
6246     IDirect3DVertexShader9 *shader_slt_scalar;
6247     HRESULT hr, color;
6248     float quad1[] =  {
6249         -1.0,   -1.0,   0.1,
6250          0.0,   -1.0,   0.1,
6251         -1.0,    0.0,   0.1,
6252          0.0,    0.0,   0.1
6253     };
6254     float quad2[] =  {
6255          0.0,   -1.0,   0.1,
6256          1.0,   -1.0,   0.1,
6257          0.0,    0.0,   0.1,
6258          1.0,    0.0,   0.1
6259     };
6260     float quad3[] =  {
6261         -1.0,    0.0,   0.1,
6262          0.0,    0.0,   0.1,
6263         -1.0,    1.0,   0.1,
6264          0.0,    1.0,   0.1
6265     };
6266     float quad4[] =  {
6267          0.0,    0.0,   0.1,
6268          1.0,    0.0,   0.1,
6269          0.0,    1.0,   0.1,
6270          1.0,    1.0,   0.1
6271     };
6272     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
6273     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
6274
6275     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6276     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6277
6278     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
6279     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6280     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
6281     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6282     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
6283     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6284     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
6285     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6286     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6287     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6288     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
6289     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6290     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6291     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
6292
6293     hr = IDirect3DDevice9_BeginScene(device);
6294     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6295     if(SUCCEEDED(hr))
6296     {
6297         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
6298         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6299         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6300         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6301
6302         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
6303         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6304         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
6305         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6306
6307         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
6308         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6309         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6310         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6311
6312         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6313         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6314
6315         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
6316         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6317         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6318         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6319
6320         hr = IDirect3DDevice9_EndScene(device);
6321         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6322     }
6323
6324     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6325     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6326
6327     color = getPixelColor(device, 160, 360);
6328     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
6329     color = getPixelColor(device, 480, 360);
6330     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
6331     color = getPixelColor(device, 160, 120);
6332     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
6333     color = getPixelColor(device, 480, 160);
6334     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
6335
6336     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6337     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6338
6339     IDirect3DVertexShader9_Release(shader_sge_vec);
6340     IDirect3DVertexShader9_Release(shader_slt_vec);
6341     IDirect3DVertexShader9_Release(shader_sge_scalar);
6342     IDirect3DVertexShader9_Release(shader_slt_scalar);
6343 }
6344
6345 static void test_vshader_input(IDirect3DDevice9 *device)
6346 {
6347     DWORD swapped_shader_code_3[] = {
6348         0xfffe0300,                                         /* vs_3_0               */
6349         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6350         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6351         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6352         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6353         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6354         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6355         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6356         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6357         0x0000ffff                                          /* end                  */
6358     };
6359     DWORD swapped_shader_code_1[] = {
6360         0xfffe0101,                                         /* vs_1_1               */
6361         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6362         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6363         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6364         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6365         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6366         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6367         0x0000ffff                                          /* end                  */
6368     };
6369     DWORD swapped_shader_code_2[] = {
6370         0xfffe0200,                                         /* vs_2_0               */
6371         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6372         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6373         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6374         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6375         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6376         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6377         0x0000ffff                                          /* end                  */
6378     };
6379     DWORD texcoord_color_shader_code_3[] = {
6380         0xfffe0300,                                         /* vs_3_0               */
6381         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6382         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6383         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6384         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6385         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6386         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
6387         0x0000ffff                                          /* end                  */
6388     };
6389     DWORD texcoord_color_shader_code_2[] = {
6390         0xfffe0200,                                         /* vs_2_0               */
6391         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6392         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6393         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6394         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6395         0x0000ffff                                          /* end                  */
6396     };
6397     DWORD texcoord_color_shader_code_1[] = {
6398         0xfffe0101,                                         /* vs_1_1               */
6399         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6400         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6401         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6402         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6403         0x0000ffff                                          /* end                  */
6404     };
6405     DWORD color_color_shader_code_3[] = {
6406         0xfffe0300,                                         /* vs_3_0               */
6407         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6408         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6409         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6410         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6411         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6412         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
6413         0x0000ffff                                          /* end                  */
6414     };
6415     DWORD color_color_shader_code_2[] = {
6416         0xfffe0200,                                         /* vs_2_0               */
6417         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6418         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6419         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6420         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6421         0x0000ffff                                          /* end                  */
6422     };
6423     DWORD color_color_shader_code_1[] = {
6424         0xfffe0101,                                         /* vs_1_1               */
6425         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6426         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6427         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6428         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6429         0x0000ffff                                          /* end                  */
6430     };
6431     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6432     HRESULT hr;
6433     DWORD color;
6434     float quad1[] =  {
6435         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6436          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6437         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6438          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6439     };
6440     float quad2[] =  {
6441          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6442          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6443          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6444          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6445     };
6446     float quad3[] =  {
6447         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
6448          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
6449         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
6450          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6451     };
6452     float quad4[] =  {
6453          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6454          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6455          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6456          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6457     };
6458     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6459         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6460         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6461         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6462         D3DDECL_END()
6463     };
6464     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6465         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6466         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6467         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6468         D3DDECL_END()
6469     };
6470     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6471         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6472         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6473         D3DDECL_END()
6474     };
6475     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6476         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6477         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6478         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
6479         D3DDECL_END()
6480     };
6481     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6482         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6483         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6484         D3DDECL_END()
6485     };
6486     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6487         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6488         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6489         D3DDECL_END()
6490     };
6491     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6492         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6493         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6494         D3DDECL_END()
6495     };
6496     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6497         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6498         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6499         D3DDECL_END()
6500     };
6501     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6502     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6503     unsigned int i;
6504     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6505     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6506
6507     struct vertex quad1_color[] =  {
6508        {-1.0,   -1.0,   0.1,    0x00ff8040},
6509        { 0.0,   -1.0,   0.1,    0x00ff8040},
6510        {-1.0,    0.0,   0.1,    0x00ff8040},
6511        { 0.0,    0.0,   0.1,    0x00ff8040}
6512     };
6513     struct vertex quad2_color[] =  {
6514        { 0.0,   -1.0,   0.1,    0x00ff8040},
6515        { 1.0,   -1.0,   0.1,    0x00ff8040},
6516        { 0.0,    0.0,   0.1,    0x00ff8040},
6517        { 1.0,    0.0,   0.1,    0x00ff8040}
6518     };
6519     struct vertex quad3_color[] =  {
6520        {-1.0,    0.0,   0.1,    0x00ff8040},
6521        { 0.0,    0.0,   0.1,    0x00ff8040},
6522        {-1.0,    1.0,   0.1,    0x00ff8040},
6523        { 0.0,    1.0,   0.1,    0x00ff8040}
6524     };
6525     float quad4_color[] =  {
6526          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6527          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6528          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6529          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6530     };
6531
6532     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6533     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6534     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6535     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6536     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6537     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6538     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6539     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6540
6541     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6542     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6543     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6544     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6545     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6546     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6547     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6548     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6549
6550     for(i = 1; i <= 3; i++) {
6551         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6552         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6553         if(i == 3) {
6554             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6555             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6556         } else if(i == 2){
6557             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6558             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6559         } else if(i == 1) {
6560             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6561             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6562         }
6563
6564         hr = IDirect3DDevice9_BeginScene(device);
6565         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6566         if(SUCCEEDED(hr))
6567         {
6568             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6569             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6570
6571             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6572             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6573             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6574             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6575
6576             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6577             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6578             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6579             if(i == 3 || i == 2) {
6580                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6581             } else if(i == 1) {
6582                 /* Succeeds or fails, depending on SW or HW vertex processing */
6583                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6584             }
6585
6586             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6587             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6588             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6589             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6590
6591             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6592             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6593             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6594             if(i == 3 || i == 2) {
6595                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6596             } else if(i == 1) {
6597                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6598             }
6599
6600             hr = IDirect3DDevice9_EndScene(device);
6601             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6602         }
6603
6604         if(i == 3 || i == 2) {
6605             color = getPixelColor(device, 160, 360);
6606             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6607                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6608
6609             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6610             color = getPixelColor(device, 480, 360);
6611             ok(color == 0x00FFFF00 || color ==0x00FF0000,
6612                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6613             color = getPixelColor(device, 160, 120);
6614             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6615             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6616                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6617
6618             color = getPixelColor(device, 480, 160);
6619             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6620         } else if(i == 1) {
6621             color = getPixelColor(device, 160, 360);
6622             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6623                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6624             color = getPixelColor(device, 480, 360);
6625             /* Accept the clear color as well in this case, since SW VP returns an error */
6626             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6627             color = getPixelColor(device, 160, 120);
6628             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6629                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6630             color = getPixelColor(device, 480, 160);
6631             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6632         }
6633
6634         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6635         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6636
6637         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6638         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6639
6640         /* Now find out if the whole streams are re-read, or just the last active value for the
6641          * vertices is used.
6642          */
6643         hr = IDirect3DDevice9_BeginScene(device);
6644         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6645         if(SUCCEEDED(hr))
6646         {
6647             float quad1_modified[] =  {
6648                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6649                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6650                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6651                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6652             };
6653             float quad2_modified[] =  {
6654                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6655                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6656                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6657                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6658             };
6659
6660             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6661             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6662
6663             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6664             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6665             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6666             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6667
6668             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6669             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6670             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6671             if(i == 3 || i == 2) {
6672                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6673             } else if(i == 1) {
6674                 /* Succeeds or fails, depending on SW or HW vertex processing */
6675                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6676             }
6677
6678             hr = IDirect3DDevice9_EndScene(device);
6679             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6680         }
6681
6682         color = getPixelColor(device, 480, 350);
6683         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6684          * as well.
6685          *
6686          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6687          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6688          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6689          * refrast's result.
6690          *
6691          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6692          */
6693         ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6694            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6695
6696         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6697         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6698
6699         IDirect3DDevice9_SetVertexShader(device, NULL);
6700         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6701
6702         IDirect3DVertexShader9_Release(swapped_shader);
6703     }
6704
6705     for(i = 1; i <= 3; i++) {
6706         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6707         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6708         if(i == 3) {
6709             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6710             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6711             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6712             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6713         } else if(i == 2){
6714             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6715             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6716             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6717             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6718         } else if(i == 1) {
6719             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6720             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6721             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6722             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6723         }
6724
6725         hr = IDirect3DDevice9_BeginScene(device);
6726         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6727         if(SUCCEEDED(hr))
6728         {
6729             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6730             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6731             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6732             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6733             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6734             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6735
6736             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6737             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6738
6739             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6740             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6741             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6742             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6743             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6744             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6745
6746             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6747             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6748             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6749             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6750             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6751             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6752
6753             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6754             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6755             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6756             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6757
6758             hr = IDirect3DDevice9_EndScene(device);
6759             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6760         }
6761         IDirect3DDevice9_SetVertexShader(device, NULL);
6762         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6763
6764         color = getPixelColor(device, 160, 360);
6765         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6766            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6767         color = getPixelColor(device, 480, 360);
6768         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6769            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6770         color = getPixelColor(device, 160, 120);
6771         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6772            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6773         color = getPixelColor(device, 480, 160);
6774         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6775            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6776
6777         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6778         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6779
6780         IDirect3DVertexShader9_Release(texcoord_color_shader);
6781         IDirect3DVertexShader9_Release(color_color_shader);
6782     }
6783
6784     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6785     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6786     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6787     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6788
6789     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6790     IDirect3DVertexDeclaration9_Release(decl_color_color);
6791     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6792     IDirect3DVertexDeclaration9_Release(decl_color_float);
6793 }
6794
6795 static void srgbtexture_test(IDirect3DDevice9 *device)
6796 {
6797     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6798      * texture stage state to render a quad using that texture.  The resulting
6799      * color components should be 0x36 (~ 0.21), per this formula:
6800      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6801      * This is true where srgb_color > 0.04045.
6802      */
6803     IDirect3D9 *d3d = NULL;
6804     HRESULT hr;
6805     LPDIRECT3DTEXTURE9 texture = NULL;
6806     LPDIRECT3DSURFACE9 surface = NULL;
6807     D3DLOCKED_RECT lr;
6808     DWORD color;
6809     float quad[] = {
6810         -1.0,       1.0,       0.0,     0.0,    0.0,
6811          1.0,       1.0,       0.0,     1.0,    0.0,
6812         -1.0,      -1.0,       0.0,     0.0,    1.0,
6813          1.0,      -1.0,       0.0,     1.0,    1.0,
6814     };
6815
6816
6817     memset(&lr, 0, sizeof(lr));
6818     IDirect3DDevice9_GetDirect3D(device, &d3d);
6819     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6820                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6821                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6822         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6823         goto out;
6824     }
6825
6826     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6827                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6828                                         &texture, NULL);
6829     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6830     if(!texture) {
6831         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6832         goto out;
6833     }
6834     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6835     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6836
6837     fill_surface(surface, 0xff7f7f7f);
6838     IDirect3DSurface9_Release(surface);
6839
6840     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6841     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6842     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6843     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6844
6845     hr = IDirect3DDevice9_BeginScene(device);
6846     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6847     if(SUCCEEDED(hr))
6848     {
6849         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6850         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6851
6852         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6853         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6854
6855
6856         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6857         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6858
6859         hr = IDirect3DDevice9_EndScene(device);
6860         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6861     }
6862
6863     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6864     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6865     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6866     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6867
6868     color = getPixelColor(device, 320, 240);
6869     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6870
6871     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6872     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6873
6874 out:
6875     if(texture) IDirect3DTexture9_Release(texture);
6876     IDirect3D9_Release(d3d);
6877 }
6878
6879 static void shademode_test(IDirect3DDevice9 *device)
6880 {
6881     /* Render a quad and try all of the different fixed function shading models. */
6882     HRESULT hr;
6883     DWORD color0, color1;
6884     DWORD color0_gouraud = 0, color1_gouraud = 0;
6885     DWORD shademode = D3DSHADE_FLAT;
6886     DWORD primtype = D3DPT_TRIANGLESTRIP;
6887     LPVOID data = NULL;
6888     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6889     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6890     UINT i, j;
6891     struct vertex quad_strip[] =
6892     {
6893         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6894         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6895         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6896         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6897     };
6898     struct vertex quad_list[] =
6899     {
6900         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6901         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6902         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6903
6904         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6905         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6906         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6907     };
6908
6909     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6910                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6911     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6912     if (FAILED(hr)) goto bail;
6913
6914     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6915                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6916     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6917     if (FAILED(hr)) goto bail;
6918
6919     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6920     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6921
6922     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6923     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6924
6925     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6926     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6927     memcpy(data, quad_strip, sizeof(quad_strip));
6928     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6929     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6930
6931     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6932     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6933     memcpy(data, quad_list, sizeof(quad_list));
6934     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6935     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6936
6937     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
6938      * the color fixups we have to do for FLAT shading will be dependent on that. */
6939     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6940     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6941
6942     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6943     for (j=0; j<2; j++) {
6944
6945         /* Inner loop just changes the D3DRS_SHADEMODE */
6946         for (i=0; i<3; i++) {
6947             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6948             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6949
6950             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6951             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6952
6953             hr = IDirect3DDevice9_BeginScene(device);
6954             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6955             if(SUCCEEDED(hr))
6956             {
6957                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6958                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6959
6960                 hr = IDirect3DDevice9_EndScene(device);
6961                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6962             }
6963
6964             /* Sample two spots from the output */
6965             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6966             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6967             switch(shademode) {
6968                 case D3DSHADE_FLAT:
6969                     /* Should take the color of the first vertex of each triangle */
6970                     if (0)
6971                     {
6972                         /* This test depends on EXT_provoking_vertex being
6973                          * available. This extension is currently (20090810)
6974                          * not common enough to let the test fail if it isn't
6975                          * present. */
6976                         ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
6977                         ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
6978                     }
6979                     shademode = D3DSHADE_GOURAUD;
6980                     break;
6981                 case D3DSHADE_GOURAUD:
6982                     /* Should be an interpolated blend */
6983
6984                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6985                        "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6986                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6987                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6988
6989                     color0_gouraud = color0;
6990                     color1_gouraud = color1;
6991
6992                     shademode = D3DSHADE_PHONG;
6993                     break;
6994                 case D3DSHADE_PHONG:
6995                     /* Should be the same as GOURAUD, since no hardware implements this */
6996                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6997                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6998                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6999                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
7000
7001                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7002                             color0_gouraud, color0);
7003                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7004                             color1_gouraud, color1);
7005                     break;
7006             }
7007         }
7008
7009         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7010         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7011
7012         /* Now, do it all over again with a TRIANGLELIST */
7013         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
7014         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7015         primtype = D3DPT_TRIANGLELIST;
7016         shademode = D3DSHADE_FLAT;
7017     }
7018
7019 bail:
7020     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7021     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7022     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
7023     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7024
7025     if (vb_strip)
7026         IDirect3DVertexBuffer9_Release(vb_strip);
7027     if (vb_list)
7028         IDirect3DVertexBuffer9_Release(vb_list);
7029 }
7030
7031
7032 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
7033 {
7034     /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
7035      * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
7036      * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
7037      * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
7038      * 0.73
7039      *
7040      * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
7041      * so use shaders for this task
7042      */
7043     IDirect3DPixelShader9 *pshader;
7044     IDirect3DVertexShader9 *vshader;
7045     IDirect3D9 *d3d;
7046     DWORD vshader_code[] = {
7047         0xfffe0101,                                                             /* vs_1_1                       */
7048         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
7049         0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0   */
7050         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
7051         0x00000001, 0xc00f0001, 0xa0000000,                                     /* mov oFog, c0.x               */
7052         0x0000ffff                                                              /* end                          */
7053     };
7054     DWORD pshader_code[] = {
7055         0xffff0101,                                                             /* ps_1_1                       */
7056         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
7057         0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
7058         0x0000ffff                                                              /* end                          */
7059     };
7060     const float quad[] = {
7061        -1.0,   -1.0,    0.1,
7062         1.0,   -1.0,    0.1,
7063        -1.0,    1.0,    0.1,
7064         1.0,    1.0,    0.1
7065     };
7066     HRESULT hr;
7067     D3DCOLOR color;
7068
7069     IDirect3DDevice9_GetDirect3D(device, &d3d);
7070     /* Ask for srgb writing on D3DRTYPE_TEXTURE. Some Windows drivers do not report it on surfaces.
7071      * For some not entirely understood reasons D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE
7072      * passes on surfaces, while asking for SRGBWRITE alone fails. Textures advertize srgb writing
7073      * alone as well, so use that since it is not the point of this test to show how CheckDeviceFormat
7074      * works
7075      */
7076     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
7077                                     D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
7078                                     D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK) {
7079         skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
7080         IDirect3D9_Release(d3d);
7081         return;
7082     }
7083     IDirect3D9_Release(d3d);
7084
7085     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
7086     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7087
7088     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
7089     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7090     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
7091     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7092     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
7093     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7094     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
7095     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7096     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
7097     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7098
7099     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
7100     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7101     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
7102     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
7103     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7104     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
7105     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
7106     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
7107     hr = IDirect3DDevice9_SetPixelShader(device, pshader);
7108     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7109
7110     hr = IDirect3DDevice9_BeginScene(device);
7111     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
7112     if(SUCCEEDED(hr)) {
7113         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
7114         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7115
7116         hr = IDirect3DDevice9_EndScene(device);
7117         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
7118     }
7119
7120     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7121     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
7122     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7123     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7124     IDirect3DPixelShader9_Release(pshader);
7125     IDirect3DVertexShader9_Release(vshader);
7126
7127     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
7128     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7129     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
7130     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7131
7132     color = getPixelColor(device, 160, 360);
7133     ok(color_match(color, 0x00808080, 1),
7134             "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
7135     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7136     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7137 }
7138
7139 static void alpha_test(IDirect3DDevice9 *device)
7140 {
7141     HRESULT hr;
7142     IDirect3DTexture9 *offscreenTexture;
7143     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
7144     DWORD color;
7145
7146     struct vertex quad1[] =
7147     {
7148         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
7149         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
7150         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
7151         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
7152     };
7153     struct vertex quad2[] =
7154     {
7155         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
7156         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
7157         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
7158         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
7159     };
7160     static const float composite_quad[][5] = {
7161         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
7162         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
7163         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
7164         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
7165     };
7166
7167     /* Clear the render target with alpha = 0.5 */
7168     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7169     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7170
7171     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
7172     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
7173
7174     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7175     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7176     if(!backbuffer) {
7177         goto out;
7178     }
7179
7180     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
7181     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
7182     if(!offscreen) {
7183         goto out;
7184     }
7185
7186     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7187     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7188
7189     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7190     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7191     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7192     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7193     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
7194     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
7195     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
7196     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
7197     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7198     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7199
7200     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
7201     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7202     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
7203
7204         /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
7205         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7206         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7207         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7208         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7209         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7210         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7211
7212         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7213         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7214         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7215         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7216         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7217         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7218
7219         /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
7220          * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
7221          * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
7222         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
7223         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7224         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7225         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7226
7227         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7228         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7229         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7230         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7231         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7232         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7233
7234         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7235         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7236         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7237         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7238         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7239         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7240
7241         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7242         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7243
7244         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
7245          * Disable alpha blending for the final composition
7246          */
7247         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
7248         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7249         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7250         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7251
7252         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
7253         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7254         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
7255         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7256         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7257         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7258
7259         hr = IDirect3DDevice9_EndScene(device);
7260         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
7261     }
7262
7263     color = getPixelColor(device, 160, 360);
7264     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7265        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
7266
7267     color = getPixelColor(device, 160, 120);
7268     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
7269        "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
7270
7271     color = getPixelColor(device, 480, 360);
7272     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7273        "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
7274
7275     color = getPixelColor(device, 480, 120);
7276     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
7277        "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
7278
7279     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7280
7281     out:
7282     /* restore things */
7283     if(backbuffer) {
7284         IDirect3DSurface9_Release(backbuffer);
7285     }
7286     if(offscreenTexture) {
7287         IDirect3DTexture9_Release(offscreenTexture);
7288     }
7289     if(offscreen) {
7290         IDirect3DSurface9_Release(offscreen);
7291     }
7292 }
7293
7294 struct vertex_shortcolor {
7295     float x, y, z;
7296     unsigned short r, g, b, a;
7297 };
7298 struct vertex_floatcolor {
7299     float x, y, z;
7300     float r, g, b, a;
7301 };
7302
7303 static void fixed_function_decl_test(IDirect3DDevice9 *device)
7304 {
7305     HRESULT hr;
7306     BOOL s_ok, ub_ok, f_ok;
7307     DWORD color, size, i;
7308     void *data;
7309     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
7310         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7311         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7312         D3DDECL_END()
7313     };
7314     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
7315         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7316         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7317         D3DDECL_END()
7318     };
7319     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
7320         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7321         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7322         D3DDECL_END()
7323     };
7324     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
7325         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7326         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7327         D3DDECL_END()
7328     };
7329     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
7330         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7331         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7332         D3DDECL_END()
7333     };
7334     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
7335         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7336         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7337         D3DDECL_END()
7338     };
7339     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
7340         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
7341         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7342         D3DDECL_END()
7343     };
7344     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
7345     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
7346     IDirect3DVertexBuffer9 *vb, *vb2;
7347     struct vertex quad1[] =                             /* D3DCOLOR */
7348     {
7349         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
7350         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7351         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
7352         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7353     };
7354     struct vertex quad2[] =                             /* UBYTE4N */
7355     {
7356         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7357         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
7358         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7359         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
7360     };
7361     struct vertex_shortcolor quad3[] =                  /* short */
7362     {
7363         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7364         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7365         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7366         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7367     };
7368     struct vertex_floatcolor quad4[] =
7369     {
7370         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7371         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7372         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7373         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7374     };
7375     DWORD colors[] = {
7376         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7377         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7378         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7379         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7380         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7381         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7382         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7383         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7384         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7385         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7386         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7387         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7388         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7389         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7390         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7391         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7392     };
7393     float quads[] = {
7394         -1.0,   -1.0,     0.1,
7395         -1.0,    0.0,     0.1,
7396          0.0,   -1.0,     0.1,
7397          0.0,    0.0,     0.1,
7398
7399          0.0,   -1.0,     0.1,
7400          0.0,    0.0,     0.1,
7401          1.0,   -1.0,     0.1,
7402          1.0,    0.0,     0.1,
7403
7404          0.0,    0.0,     0.1,
7405          0.0,    1.0,     0.1,
7406          1.0,    0.0,     0.1,
7407          1.0,    1.0,     0.1,
7408
7409         -1.0,    0.0,     0.1,
7410         -1.0,    1.0,     0.1,
7411          0.0,    0.0,     0.1,
7412          0.0,    1.0,     0.1
7413     };
7414     struct tvertex quad_transformed[] = {
7415        {  90,    110,     0.1,      2.0,        0x00ffff00},
7416        { 570,    110,     0.1,      2.0,        0x00ffff00},
7417        {  90,    300,     0.1,      2.0,        0x00ffff00},
7418        { 570,    300,     0.1,      2.0,        0x00ffff00}
7419     };
7420     D3DCAPS9 caps;
7421
7422     memset(&caps, 0, sizeof(caps));
7423     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7424     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7425
7426     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7427     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7428
7429     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7430     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7431     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7432     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7433     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7434     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7435     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7436         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7437         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7438         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7439         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7440     } else {
7441         trace("D3DDTCAPS_UBYTE4N not supported\n");
7442         dcl_ubyte_2 = NULL;
7443         dcl_ubyte = NULL;
7444     }
7445     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7446     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7447     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7448     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7449
7450     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7451     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7452                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
7453     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7454
7455     hr = IDirect3DDevice9_BeginScene(device);
7456     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7457     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7458     if(SUCCEEDED(hr)) {
7459         if(dcl_color) {
7460             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7461             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7462             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7463             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7464         }
7465
7466         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7467          * accepts them, the nvidia driver accepts them all. All those differences even though we're
7468          * using software vertex processing. Doh!
7469          */
7470         if(dcl_ubyte) {
7471             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7472             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7473             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7474             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7475             ub_ok = SUCCEEDED(hr);
7476         }
7477
7478         if(dcl_short) {
7479             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7480             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7481             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7482             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7483             s_ok = SUCCEEDED(hr);
7484         }
7485
7486         if(dcl_float) {
7487             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7488             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7489             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7490             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7491             f_ok = SUCCEEDED(hr);
7492         }
7493
7494         hr = IDirect3DDevice9_EndScene(device);
7495         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7496     }
7497
7498     if(dcl_short) {
7499         color = getPixelColor(device, 480, 360);
7500         ok(color == 0x000000ff || !s_ok,
7501            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7502     }
7503     if(dcl_ubyte) {
7504         color = getPixelColor(device, 160, 120);
7505         ok(color == 0x0000ffff || !ub_ok,
7506            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7507     }
7508     if(dcl_color) {
7509         color = getPixelColor(device, 160, 360);
7510         ok(color == 0x00ffff00,
7511            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7512     }
7513     if(dcl_float) {
7514         color = getPixelColor(device, 480, 120);
7515         ok(color == 0x00ff0000 || !f_ok,
7516            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7517     }
7518     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7519
7520     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7521      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7522      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7523      * whether the immediate mode code works
7524      */
7525     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7526     hr = IDirect3DDevice9_BeginScene(device);
7527     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7528     if(SUCCEEDED(hr)) {
7529         if(dcl_color) {
7530             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7531             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7532             memcpy(data, quad1, sizeof(quad1));
7533             hr = IDirect3DVertexBuffer9_Unlock(vb);
7534             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7535             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7536             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7537             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7538             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7539             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7540             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7541         }
7542
7543         if(dcl_ubyte) {
7544             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7545             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7546             memcpy(data, quad2, sizeof(quad2));
7547             hr = IDirect3DVertexBuffer9_Unlock(vb);
7548             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7549             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7550             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7551             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7552             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7553             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7554             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7555                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7556             ub_ok = SUCCEEDED(hr);
7557         }
7558
7559         if(dcl_short) {
7560             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7561             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7562             memcpy(data, quad3, sizeof(quad3));
7563             hr = IDirect3DVertexBuffer9_Unlock(vb);
7564             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7565             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7566             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7567             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7568             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7569             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7570             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7571                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7572             s_ok = SUCCEEDED(hr);
7573         }
7574
7575         if(dcl_float) {
7576             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7577             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7578             memcpy(data, quad4, sizeof(quad4));
7579             hr = IDirect3DVertexBuffer9_Unlock(vb);
7580             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7581             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7582             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7583             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7584             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7585             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7586             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7587                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7588             f_ok = SUCCEEDED(hr);
7589         }
7590
7591         hr = IDirect3DDevice9_EndScene(device);
7592         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7593     }
7594
7595     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7596     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7597     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7598     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7599
7600     if(dcl_short) {
7601         color = getPixelColor(device, 480, 360);
7602         ok(color == 0x000000ff || !s_ok,
7603            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7604     }
7605     if(dcl_ubyte) {
7606         color = getPixelColor(device, 160, 120);
7607         ok(color == 0x0000ffff || !ub_ok,
7608            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7609     }
7610     if(dcl_color) {
7611         color = getPixelColor(device, 160, 360);
7612         ok(color == 0x00ffff00,
7613            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7614     }
7615     if(dcl_float) {
7616         color = getPixelColor(device, 480, 120);
7617         ok(color == 0x00ff0000 || !f_ok,
7618            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7619     }
7620     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7621
7622     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7623     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7624
7625     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7626     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7627     memcpy(data, quad_transformed, sizeof(quad_transformed));
7628     hr = IDirect3DVertexBuffer9_Unlock(vb);
7629     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7630
7631     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7632     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7633
7634     hr = IDirect3DDevice9_BeginScene(device);
7635     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7636     if(SUCCEEDED(hr)) {
7637         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7638         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7639         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7640         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7641
7642         hr = IDirect3DDevice9_EndScene(device);
7643         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7644     }
7645
7646     color = getPixelColor(device, 88, 108);
7647     ok(color == 0x000000ff,
7648        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7649     color = getPixelColor(device, 92, 108);
7650     ok(color == 0x000000ff,
7651        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7652     color = getPixelColor(device, 88, 112);
7653     ok(color == 0x000000ff,
7654        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7655     color = getPixelColor(device, 92, 112);
7656     ok(color == 0x00ffff00,
7657        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7658
7659     color = getPixelColor(device, 568, 108);
7660     ok(color == 0x000000ff,
7661        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7662     color = getPixelColor(device, 572, 108);
7663     ok(color == 0x000000ff,
7664        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7665     color = getPixelColor(device, 568, 112);
7666     ok(color == 0x00ffff00,
7667        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7668     color = getPixelColor(device, 572, 112);
7669     ok(color == 0x000000ff,
7670        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7671
7672     color = getPixelColor(device, 88, 298);
7673     ok(color == 0x000000ff,
7674        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7675     color = getPixelColor(device, 92, 298);
7676     ok(color == 0x00ffff00,
7677        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7678     color = getPixelColor(device, 88, 302);
7679     ok(color == 0x000000ff,
7680        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7681     color = getPixelColor(device, 92, 302);
7682     ok(color == 0x000000ff,
7683        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7684
7685     color = getPixelColor(device, 568, 298);
7686     ok(color == 0x00ffff00,
7687        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7688     color = getPixelColor(device, 572, 298);
7689     ok(color == 0x000000ff,
7690        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7691     color = getPixelColor(device, 568, 302);
7692     ok(color == 0x000000ff,
7693        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7694     color = getPixelColor(device, 572, 302);
7695     ok(color == 0x000000ff,
7696        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7697
7698     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7699
7700     /* This test is pointless without those two declarations: */
7701     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7702         skip("color-ubyte switching test declarations aren't supported\n");
7703         goto out;
7704     }
7705
7706     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7707     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7708     memcpy(data, quads, sizeof(quads));
7709     hr = IDirect3DVertexBuffer9_Unlock(vb);
7710     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7711     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7712                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7713     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7714     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7715     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7716     memcpy(data, colors, sizeof(colors));
7717     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7718     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7719
7720     for(i = 0; i < 2; i++) {
7721         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7722         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7723
7724         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7725         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7726         if(i == 0) {
7727             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7728         } else {
7729             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7730         }
7731         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7732
7733         hr = IDirect3DDevice9_BeginScene(device);
7734         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7735         ub_ok = FALSE;
7736         if(SUCCEEDED(hr)) {
7737             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7738             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7739             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7740             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7741                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7742             ub_ok = SUCCEEDED(hr);
7743
7744             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7745             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7746             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7747             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7748
7749             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7750             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7751             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7752             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7753                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7754             ub_ok = (SUCCEEDED(hr) && ub_ok);
7755
7756             hr = IDirect3DDevice9_EndScene(device);
7757             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7758         }
7759
7760         if(i == 0) {
7761             color = getPixelColor(device, 480, 360);
7762             ok(color == 0x00ff0000,
7763                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7764             color = getPixelColor(device, 160, 120);
7765             ok(color == 0x00ffffff,
7766                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7767             color = getPixelColor(device, 160, 360);
7768             ok(color == 0x000000ff || !ub_ok,
7769                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7770             color = getPixelColor(device, 480, 120);
7771             ok(color == 0x000000ff || !ub_ok,
7772                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7773         } else {
7774             color = getPixelColor(device, 480, 360);
7775             ok(color == 0x000000ff,
7776                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7777             color = getPixelColor(device, 160, 120);
7778             ok(color == 0x00ffffff,
7779                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7780             color = getPixelColor(device, 160, 360);
7781             ok(color == 0x00ff0000 || !ub_ok,
7782                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7783             color = getPixelColor(device, 480, 120);
7784             ok(color == 0x00ff0000 || !ub_ok,
7785                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7786         }
7787         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7788     }
7789
7790     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7791     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7792     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7793     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7794     IDirect3DVertexBuffer9_Release(vb2);
7795
7796     out:
7797     IDirect3DVertexBuffer9_Release(vb);
7798     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7799     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7800     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7801     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7802     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7803     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7804     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7805 }
7806
7807 struct vertex_float16color {
7808     float x, y, z;
7809     DWORD c1, c2;
7810 };
7811
7812 static void test_vshader_float16(IDirect3DDevice9 *device)
7813 {
7814     HRESULT hr;
7815     DWORD color;
7816     void *data;
7817     static const D3DVERTEXELEMENT9 decl_elements[] = {
7818         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7819         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7820         D3DDECL_END()
7821     };
7822     IDirect3DVertexDeclaration9 *vdecl = NULL;
7823     IDirect3DVertexBuffer9 *buffer = NULL;
7824     IDirect3DVertexShader9 *shader;
7825     DWORD shader_code[] = {
7826         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7827         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7828         0x90e40001, 0x0000ffff
7829     };
7830     struct vertex_float16color quad[] = {
7831         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7832         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7833         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7834         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7835
7836         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7837         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7838         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7839         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7840
7841         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7842         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7843         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7844         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7845
7846         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7847         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7848         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7849         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7850     };
7851
7852     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7853     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7854
7855     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7856     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7857     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7858     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7859     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7860     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7861
7862     hr = IDirect3DDevice9_BeginScene(device);
7863     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7864     if(SUCCEEDED(hr)) {
7865         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7866         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7867         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7868         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7869         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7870         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7871         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7872         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7873         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7874         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7875
7876         hr = IDirect3DDevice9_EndScene(device);
7877         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7878     }
7879     color = getPixelColor(device, 480, 360);
7880     ok(color == 0x00ff0000,
7881        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7882     color = getPixelColor(device, 160, 120);
7883     ok(color == 0x00000000,
7884        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7885     color = getPixelColor(device, 160, 360);
7886     ok(color == 0x0000ff00,
7887        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7888     color = getPixelColor(device, 480, 120);
7889     ok(color == 0x000000ff,
7890        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7891     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7892
7893     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7894     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7895
7896     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7897                                              D3DPOOL_MANAGED, &buffer, NULL);
7898     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7899     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7900     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7901     memcpy(data, quad, sizeof(quad));
7902     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7903     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7904     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7905     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7906
7907     hr = IDirect3DDevice9_BeginScene(device);
7908     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7909     if(SUCCEEDED(hr)) {
7910             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7911             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7912             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7913             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7914             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7915             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7916             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7917             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7918
7919             hr = IDirect3DDevice9_EndScene(device);
7920             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7921     }
7922
7923     color = getPixelColor(device, 480, 360);
7924     ok(color == 0x00ff0000,
7925        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7926     color = getPixelColor(device, 160, 120);
7927     ok(color == 0x00000000,
7928        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7929     color = getPixelColor(device, 160, 360);
7930     ok(color == 0x0000ff00,
7931        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7932     color = getPixelColor(device, 480, 120);
7933     ok(color == 0x000000ff,
7934        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7935     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7936
7937     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7938     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7939     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7940     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7941     IDirect3DDevice9_SetVertexShader(device, NULL);
7942     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7943
7944     IDirect3DVertexDeclaration9_Release(vdecl);
7945     IDirect3DVertexShader9_Release(shader);
7946     IDirect3DVertexBuffer9_Release(buffer);
7947 }
7948
7949 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7950 {
7951     D3DCAPS9 caps;
7952     IDirect3DTexture9 *texture;
7953     HRESULT hr;
7954     D3DLOCKED_RECT rect;
7955     unsigned int x, y;
7956     DWORD *dst, color;
7957     const float quad[] = {
7958         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
7959          1.0,   -1.0,   0.1,    1.2,   -0.2,
7960         -1.0,    1.0,   0.1,   -0.2,    1.2,
7961          1.0,    1.0,   0.1,    1.2,    1.2
7962     };
7963     memset(&caps, 0, sizeof(caps));
7964
7965     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7966     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7967     if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7968         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7969         ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7970            "Card has conditional NP2 support without power of two restriction set\n");
7971         skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7972         return;
7973     } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7974         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7975         return;
7976     }
7977
7978     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7979     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7980
7981     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7982     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7983
7984     memset(&rect, 0, sizeof(rect));
7985     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7986     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7987     for(y = 0; y < 10; y++) {
7988         for(x = 0; x < 10; x++) {
7989             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7990             if(x == 0 || x == 9 || y == 0 || y == 9) {
7991                 *dst = 0x00ff0000;
7992             } else {
7993                 *dst = 0x000000ff;
7994             }
7995         }
7996     }
7997     hr = IDirect3DTexture9_UnlockRect(texture, 0);
7998     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7999
8000     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8001     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8002     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
8003     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
8004     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
8005     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
8006     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8007     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
8008
8009     hr = IDirect3DDevice9_BeginScene(device);
8010     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8011     if(SUCCEEDED(hr)) {
8012         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8013         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8014
8015         hr = IDirect3DDevice9_EndScene(device);
8016         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8017     }
8018
8019     color = getPixelColor(device,    1,  1);
8020     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
8021     color = getPixelColor(device, 639, 479);
8022     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
8023
8024     color = getPixelColor(device, 135, 101);
8025     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
8026     color = getPixelColor(device, 140, 101);
8027     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
8028     color = getPixelColor(device, 135, 105);
8029     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
8030     color = getPixelColor(device, 140, 105);
8031     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
8032
8033     color = getPixelColor(device, 135, 376);
8034     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
8035     color = getPixelColor(device, 140, 376);
8036     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
8037     color = getPixelColor(device, 135, 379);
8038     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
8039     color = getPixelColor(device, 140, 379);
8040     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
8041
8042     color = getPixelColor(device, 500, 101);
8043     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
8044     color = getPixelColor(device, 504, 101);
8045     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
8046     color = getPixelColor(device, 500, 105);
8047     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
8048     color = getPixelColor(device, 504, 105);
8049     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
8050
8051     color = getPixelColor(device, 500, 376);
8052     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
8053     color = getPixelColor(device, 504, 376);
8054     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
8055     color = getPixelColor(device, 500, 380);
8056     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
8057     color = getPixelColor(device, 504, 380);
8058     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
8059
8060     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8061
8062     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8063     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8064     IDirect3DTexture9_Release(texture);
8065 }
8066
8067 static void vFace_register_test(IDirect3DDevice9 *device)
8068 {
8069     HRESULT hr;
8070     DWORD color;
8071     const DWORD shader_code[] = {
8072         0xffff0300,                                                             /* ps_3_0                     */
8073         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8074         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
8075         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
8076         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
8077         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
8078         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8079         0x0000ffff                                                              /* END                        */
8080     };
8081     IDirect3DPixelShader9 *shader;
8082     IDirect3DTexture9 *texture;
8083     IDirect3DSurface9 *surface, *backbuffer;
8084     const float quad[] = {
8085         -1.0,   -1.0,   0.1,
8086          1.0,   -1.0,   0.1,
8087         -1.0,    0.0,   0.1,
8088
8089          1.0,   -1.0,   0.1,
8090          1.0,    0.0,   0.1,
8091         -1.0,    0.0,   0.1,
8092
8093         -1.0,    0.0,   0.1,
8094         -1.0,    1.0,   0.1,
8095          1.0,    0.0,   0.1,
8096
8097          1.0,    0.0,   0.1,
8098         -1.0,    1.0,   0.1,
8099          1.0,    1.0,   0.1,
8100     };
8101     const float blit[] = {
8102          0.0,   -1.0,   0.1,    0.0,    0.0,
8103          1.0,   -1.0,   0.1,    1.0,    0.0,
8104          0.0,    1.0,   0.1,    0.0,    1.0,
8105          1.0,    1.0,   0.1,    1.0,    1.0,
8106     };
8107
8108     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8109     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8110     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
8111     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8112     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8113     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
8114     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8115     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8116     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8117     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8118     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8119     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8120
8121     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8122     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8123
8124     hr = IDirect3DDevice9_BeginScene(device);
8125     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8126     if(SUCCEEDED(hr)) {
8127         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
8128         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8129         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8130         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8131         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8132         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8133         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8134         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8135         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8136         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8137         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8138
8139         /* Blit the texture onto the back buffer to make it visible */
8140         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8141         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8142         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8143         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8144         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8145         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8146         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8147         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8148         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8149         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8150
8151         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
8152         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8153
8154         hr = IDirect3DDevice9_EndScene(device);
8155         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8156     }
8157
8158     color = getPixelColor(device, 160, 360);
8159     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8160     color = getPixelColor(device, 160, 120);
8161     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8162     color = getPixelColor(device, 480, 360);
8163     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8164     color = getPixelColor(device, 480, 120);
8165     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8166     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8167
8168     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8169     IDirect3DDevice9_SetTexture(device, 0, NULL);
8170     IDirect3DPixelShader9_Release(shader);
8171     IDirect3DSurface9_Release(surface);
8172     IDirect3DSurface9_Release(backbuffer);
8173     IDirect3DTexture9_Release(texture);
8174 }
8175
8176 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
8177 {
8178     HRESULT hr;
8179     DWORD color;
8180     int i;
8181     D3DCAPS9 caps;
8182     BOOL L6V5U5_supported = FALSE;
8183     IDirect3DTexture9 *tex1, *tex2;
8184     D3DLOCKED_RECT locked_rect;
8185
8186     static const float quad[][7] = {
8187         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
8188         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
8189         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
8190         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
8191     };
8192
8193     static const D3DVERTEXELEMENT9 decl_elements[] = {
8194         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8195         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8196         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
8197         D3DDECL_END()
8198     };
8199
8200     /* use asymmetric matrix to test loading */
8201     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
8202     float scale, offset;
8203
8204     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
8205     IDirect3DTexture9           *texture            = NULL;
8206
8207     memset(&caps, 0, sizeof(caps));
8208     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8209     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8210     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
8211         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
8212         return;
8213     } else {
8214         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
8215          * They report that it is not supported, but after that bump mapping works properly. So just test
8216          * if the format is generally supported, and check the BUMPENVMAP flag
8217          */
8218         IDirect3D9 *d3d9;
8219
8220         IDirect3DDevice9_GetDirect3D(device, &d3d9);
8221         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8222                                           D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
8223         L6V5U5_supported = SUCCEEDED(hr);
8224         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8225                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
8226         IDirect3D9_Release(d3d9);
8227         if(FAILED(hr)) {
8228             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
8229             return;
8230         }
8231     }
8232
8233     /* Generate the textures */
8234     generate_bumpmap_textures(device);
8235
8236     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
8237     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8238     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
8239     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8240     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
8241     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8242     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
8243     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8244
8245     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
8246     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8247     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
8248     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8249     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
8250     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8251
8252     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8253     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8254     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8255     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8256     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8257     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8258
8259     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8260     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8261
8262     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8263     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
8264
8265     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
8266     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
8267
8268
8269     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
8270     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
8271     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
8272     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
8273
8274     hr = IDirect3DDevice9_BeginScene(device);
8275     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8276
8277     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8278     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8279
8280     hr = IDirect3DDevice9_EndScene(device);
8281     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8282
8283     /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
8284      * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
8285      * But since testing the color match is not the purpose of the test don't be too picky
8286      */
8287     color = getPixelColor(device, 320-32, 240);
8288     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8289     color = getPixelColor(device, 320+32, 240);
8290     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8291     color = getPixelColor(device, 320, 240-32);
8292     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8293     color = getPixelColor(device, 320, 240+32);
8294     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8295     color = getPixelColor(device, 320, 240);
8296     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8297     color = getPixelColor(device, 320+32, 240+32);
8298     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8299     color = getPixelColor(device, 320-32, 240+32);
8300     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8301     color = getPixelColor(device, 320+32, 240-32);
8302     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8303     color = getPixelColor(device, 320-32, 240-32);
8304     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8305     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8306     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8307
8308     for(i = 0; i < 2; i++) {
8309         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
8310         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
8311         IDirect3DTexture9_Release(texture); /* For the GetTexture */
8312         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
8313         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
8314         IDirect3DTexture9_Release(texture); /* To destroy it */
8315     }
8316
8317     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
8318         skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
8319         goto cleanup;
8320     }
8321     if(L6V5U5_supported == FALSE) {
8322         skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
8323         goto cleanup;
8324     }
8325
8326     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
8327     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8328     /* This test only tests the luminance part. The bumpmapping part was already tested above and
8329      * would only make this test more complicated
8330      */
8331     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
8332     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8333     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8334     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8335
8336     memset(&locked_rect, 0, sizeof(locked_rect));
8337     hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
8338     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8339     *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
8340     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8341     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8342
8343     memset(&locked_rect, 0, sizeof(locked_rect));
8344     hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
8345     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8346     *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
8347     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8348     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8349
8350     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8351     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8352     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8353     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8354
8355     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
8356     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8357     scale = 2.0;
8358     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8359     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8360     offset = 0.1;
8361     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8362     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8363
8364     hr = IDirect3DDevice9_BeginScene(device);
8365     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8366     if(SUCCEEDED(hr)) {
8367         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8368         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8369         hr = IDirect3DDevice9_EndScene(device);
8370         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8371     }
8372
8373     color = getPixelColor(device, 320, 240);
8374     /* red:   1.0  * (0.25 * 2.0 + 0.1) = 1.0  * 0.6 = 0.6  = 0x99
8375      * green: 0.5  * (0.25 * 2.0 + 0.1) = 0.5  * 0.6 = 0.3  = 0x4c
8376      * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
8377      */
8378     ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
8379     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8380     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8381
8382     /* Check a result scale factor > 1.0 */
8383     scale = 10;
8384     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8385     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8386     offset = 10;
8387     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8388     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8389
8390     hr = IDirect3DDevice9_BeginScene(device);
8391     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8392     if(SUCCEEDED(hr)) {
8393         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8394         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8395         hr = IDirect3DDevice9_EndScene(device);
8396         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8397     }
8398     color = getPixelColor(device, 320, 240);
8399     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8400     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8401     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8402
8403     /* Check clamping in the scale factor calculation */
8404     scale = 1000;
8405     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8406     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8407     offset = -1;
8408     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8409     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8410
8411     hr = IDirect3DDevice9_BeginScene(device);
8412     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8413     if(SUCCEEDED(hr)) {
8414         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8415         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8416         hr = IDirect3DDevice9_EndScene(device);
8417         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8418     }
8419     color = getPixelColor(device, 320, 240);
8420     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8421     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8422     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8423
8424     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8425     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8426     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8427     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8428
8429     IDirect3DTexture9_Release(tex1);
8430     IDirect3DTexture9_Release(tex2);
8431
8432 cleanup:
8433     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8434     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8435     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8436     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8437
8438     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8439     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8440     IDirect3DVertexDeclaration9_Release(vertex_declaration);
8441 }
8442
8443 static void stencil_cull_test(IDirect3DDevice9 *device) {
8444     HRESULT hr;
8445     IDirect3DSurface9 *depthstencil = NULL;
8446     D3DSURFACE_DESC desc;
8447     float quad1[] = {
8448         -1.0,   -1.0,   0.1,
8449          0.0,   -1.0,   0.1,
8450         -1.0,    0.0,   0.1,
8451          0.0,    0.0,   0.1,
8452     };
8453     float quad2[] = {
8454          0.0,   -1.0,   0.1,
8455          1.0,   -1.0,   0.1,
8456          0.0,    0.0,   0.1,
8457          1.0,    0.0,   0.1,
8458     };
8459     float quad3[] = {
8460         0.0,    0.0,   0.1,
8461         1.0,    0.0,   0.1,
8462         0.0,    1.0,   0.1,
8463         1.0,    1.0,   0.1,
8464     };
8465     float quad4[] = {
8466         -1.0,    0.0,   0.1,
8467          0.0,    0.0,   0.1,
8468         -1.0,    1.0,   0.1,
8469          0.0,    1.0,   0.1,
8470     };
8471     struct vertex painter[] = {
8472        {-1.0,   -1.0,   0.0,    0x00000000},
8473        { 1.0,   -1.0,   0.0,    0x00000000},
8474        {-1.0,    1.0,   0.0,    0x00000000},
8475        { 1.0,    1.0,   0.0,    0x00000000},
8476     };
8477     WORD indices_cw[]  = {0, 1, 3};
8478     WORD indices_ccw[] = {0, 2, 3};
8479     unsigned int i;
8480     DWORD color;
8481
8482     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8483     if(depthstencil == NULL) {
8484         skip("No depth stencil buffer\n");
8485         return;
8486     }
8487     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8488     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8489     IDirect3DSurface9_Release(depthstencil);
8490     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8491         skip("No 4 or 8 bit stencil surface\n");
8492         return;
8493     }
8494
8495     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8496     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8497     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8498
8499     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8500     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8501     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8502     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8503     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8504     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8505     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8506     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8507
8508     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8509     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8510     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8511     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8512     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8513     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8514
8515     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8516     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8517     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8518     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8519
8520     /* First pass: Fill the stencil buffer with some values... */
8521     hr = IDirect3DDevice9_BeginScene(device);
8522     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8523     if(SUCCEEDED(hr))
8524     {
8525         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8526         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8527         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8528                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8529         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8530         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8531                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8532         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8533
8534         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8535         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8536         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8537         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8538         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8539                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8540         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8541         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8542                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8543         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8544
8545         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8546         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8547         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8548                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8549         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8550         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8551                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8552         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8553
8554         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8555         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8556         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8557                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8558         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8559         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8560                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8561         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8562
8563         hr = IDirect3DDevice9_EndScene(device);
8564         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8565     }
8566
8567     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8568     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8569     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8570     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8571     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8572     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8573     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8574     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8575     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8576     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8577     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8578     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8579     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8580
8581     /* 2nd pass: Make the stencil values visible */
8582     hr = IDirect3DDevice9_BeginScene(device);
8583     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8584     if(SUCCEEDED(hr))
8585     {
8586         IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8587         for(i = 0; i < 16; i++) {
8588             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8589             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8590
8591             painter[0].diffuse = (i * 16); /* Creates shades of blue */
8592             painter[1].diffuse = (i * 16);
8593             painter[2].diffuse = (i * 16);
8594             painter[3].diffuse = (i * 16);
8595             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8596             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8597         }
8598         hr = IDirect3DDevice9_EndScene(device);
8599         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8600     }
8601
8602     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8603     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8604
8605     color = getPixelColor(device, 160, 420);
8606     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8607     color = getPixelColor(device, 160, 300);
8608     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8609
8610     color = getPixelColor(device, 480, 420);
8611     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8612     color = getPixelColor(device, 480, 300);
8613     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8614
8615     color = getPixelColor(device, 160, 180);
8616     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8617     color = getPixelColor(device, 160, 60);
8618     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8619
8620     color = getPixelColor(device, 480, 180);
8621     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8622     color = getPixelColor(device, 480, 60);
8623     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8624
8625     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8626     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8627 }
8628
8629 static void vpos_register_test(IDirect3DDevice9 *device)
8630 {
8631     HRESULT hr;
8632     DWORD color;
8633     const DWORD shader_code[] = {
8634     0xffff0300,                                                             /* ps_3_0                     */
8635     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8636     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8637     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8638     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8639     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8640     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8641     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8642     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8643     0x0000ffff                                                              /* end                        */
8644     };
8645     const DWORD shader_frac_code[] = {
8646     0xffff0300,                                                             /* ps_3_0                     */
8647     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8648     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8649     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8650     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8651     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8652     0x0000ffff                                                              /* end                        */
8653     };
8654     IDirect3DPixelShader9 *shader, *shader_frac;
8655     IDirect3DSurface9 *surface = NULL, *backbuffer;
8656     const float quad[] = {
8657         -1.0,   -1.0,   0.1,    0.0,    0.0,
8658          1.0,   -1.0,   0.1,    1.0,    0.0,
8659         -1.0,    1.0,   0.1,    0.0,    1.0,
8660          1.0,    1.0,   0.1,    1.0,    1.0,
8661     };
8662     D3DLOCKED_RECT lr;
8663     float constant[4] = {1.0, 0.0, 320, 240};
8664     DWORD *pos;
8665
8666     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8667     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8668     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8669     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8670     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8671     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8672     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8673     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8674     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8675     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8676     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8677     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8678
8679     hr = IDirect3DDevice9_BeginScene(device);
8680     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8681     if(SUCCEEDED(hr)) {
8682         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8683         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8684         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8685         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8686         hr = IDirect3DDevice9_EndScene(device);
8687         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8688     }
8689
8690     /* This has to be pixel exact */
8691     color = getPixelColor(device, 319, 239);
8692     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8693     color = getPixelColor(device, 320, 239);
8694     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8695     color = getPixelColor(device, 319, 240);
8696     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8697     color = getPixelColor(device, 320, 240);
8698     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8699     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8700
8701     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8702                                              &surface, NULL);
8703     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8704     hr = IDirect3DDevice9_BeginScene(device);
8705     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8706     if(SUCCEEDED(hr)) {
8707         constant[2] = 16; constant[3] = 16;
8708         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8709         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8710         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8711         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8712         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8713         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8714         hr = IDirect3DDevice9_EndScene(device);
8715         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8716     }
8717     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8718     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8719
8720     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8721     color = *pos & 0x00ffffff;
8722     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8723     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8724     color = *pos & 0x00ffffff;
8725     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8726     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8727     color = *pos & 0x00ffffff;
8728     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8729     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8730     color = *pos & 0x00ffffff;
8731     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8732
8733     hr = IDirect3DSurface9_UnlockRect(surface);
8734     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8735
8736     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8737      * have full control over the multisampling setting inside this test
8738      */
8739     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8740     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8741     hr = IDirect3DDevice9_BeginScene(device);
8742     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8743     if(SUCCEEDED(hr)) {
8744         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8745         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8746         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8747         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8748         hr = IDirect3DDevice9_EndScene(device);
8749         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8750     }
8751     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8752     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8753
8754     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8755     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8756
8757     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8758     color = *pos & 0x00ffffff;
8759     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8760
8761     hr = IDirect3DSurface9_UnlockRect(surface);
8762     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8763
8764     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8765     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8766     IDirect3DPixelShader9_Release(shader);
8767     IDirect3DPixelShader9_Release(shader_frac);
8768     if(surface) IDirect3DSurface9_Release(surface);
8769     IDirect3DSurface9_Release(backbuffer);
8770 }
8771
8772 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
8773 {
8774     D3DCOLOR color;
8775
8776     color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
8777     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8778     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8779     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8780     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8781
8782     ++r;
8783     color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
8784     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8785     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8786     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8787     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8788
8789     return TRUE;
8790 }
8791
8792 static void pointsize_test(IDirect3DDevice9 *device)
8793 {
8794     HRESULT hr;
8795     D3DCAPS9 caps;
8796     D3DMATRIX matrix;
8797     D3DMATRIX identity;
8798     float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8799     DWORD color;
8800     IDirect3DSurface9 *rt, *backbuffer;
8801     IDirect3DTexture9 *tex1, *tex2;
8802     RECT rect = {0, 0, 128, 128};
8803     D3DLOCKED_RECT lr;
8804     const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8805                                 0x00000000, 0x00000000};
8806     const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8807                                 0x00000000, 0x0000ff00};
8808
8809     const float vertices[] = {
8810         64,     64,     0.1,
8811         128,    64,     0.1,
8812         192,    64,     0.1,
8813         256,    64,     0.1,
8814         320,    64,     0.1,
8815         384,    64,     0.1,
8816         448,    64,     0.1,
8817         512,    64,     0.1,
8818     };
8819
8820     /* 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 */
8821     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;
8822     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;
8823     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;
8824     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;
8825
8826     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;
8827     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;
8828     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;
8829     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;
8830
8831     memset(&caps, 0, sizeof(caps));
8832     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8833     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8834     if(caps.MaxPointSize < 32.0) {
8835         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8836         return;
8837     }
8838
8839     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8840     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8841     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8842     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8843     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8844     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8845     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8846     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8847
8848     hr = IDirect3DDevice9_BeginScene(device);
8849     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8850     if (SUCCEEDED(hr))
8851     {
8852         ptsize = 15.0;
8853         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8854         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8855         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8856         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8857
8858         ptsize = 31.0;
8859         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8860         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8861         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8862         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8863
8864         ptsize = 30.75;
8865         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8866         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8867         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8868         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8869
8870         if (caps.MaxPointSize >= 63.0)
8871         {
8872             ptsize = 63.0;
8873             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8874             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8875             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8876             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8877
8878             ptsize = 62.75;
8879             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8880             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8881             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8882             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8883         }
8884
8885         ptsize = 1.0;
8886         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8887         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8888         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8889         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8890
8891         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8892         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8893         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8894         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8895
8896         /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8897         ptsize = 15.0;
8898         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8899         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8900         ptsize = 1.0;
8901         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8902         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8903         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8904         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8905
8906         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8907         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8908
8909         /* pointsize < pointsize_min < pointsize_max?
8910          * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
8911         ptsize = 1.0;
8912         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8913         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8914         ptsize = 15.0;
8915         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8916         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8917         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8918         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8919
8920         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8921         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8922
8923         hr = IDirect3DDevice9_EndScene(device);
8924         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8925     }
8926
8927     ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
8928     ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
8929     ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
8930
8931     if (caps.MaxPointSize >= 63.0)
8932     {
8933         ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
8934         ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
8935     }
8936
8937     ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
8938     /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
8939     ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
8940     /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
8941     ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
8942
8943     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8944
8945     /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8946      * generates texture coordinates for the point(result: Yes, it does)
8947      *
8948      * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8949      * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8950      * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8951      */
8952     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8953     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8954
8955     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8956     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8957     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8958     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8959     memset(&lr, 0, sizeof(lr));
8960     hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8961     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8962     memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8963     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8964     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8965     memset(&lr, 0, sizeof(lr));
8966     hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8967     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8968     memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8969     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8970     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8971     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8972     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8973     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8974     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8975     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8976     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8977     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8978     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8979     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8980     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8981     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8982     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8983     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8984     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8985
8986     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8987     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8988     ptsize = 32.0;
8989     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8990     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8991
8992     hr = IDirect3DDevice9_BeginScene(device);
8993     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8994     if(SUCCEEDED(hr))
8995     {
8996         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8997         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8998         hr = IDirect3DDevice9_EndScene(device);
8999         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9000     }
9001
9002     color = getPixelColor(device, 64-4, 64-4);
9003     ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
9004     color = getPixelColor(device, 64-4, 64+4);
9005     ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
9006     color = getPixelColor(device, 64+4, 64+4);
9007     ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
9008     color = getPixelColor(device, 64+4, 64-4);
9009     ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
9010     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9011
9012     U(matrix).m[0][0] =  1.0f / 64.0f;
9013     U(matrix).m[1][1] = -1.0f / 64.0f;
9014     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
9015     ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
9016
9017     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
9018     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
9019
9020     hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
9021             D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
9022     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
9023
9024     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
9025     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
9026     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 0.0f, 0);
9027     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
9028
9029     hr = IDirect3DDevice9_BeginScene(device);
9030     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
9031     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9032     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
9033     hr = IDirect3DDevice9_EndScene(device);
9034     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
9035
9036     hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
9037     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
9038     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9039     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
9040     IDirect3DSurface9_Release(backbuffer);
9041     IDirect3DSurface9_Release(rt);
9042
9043     color = getPixelColor(device, 64-4, 64-4);
9044     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
9045             "Expected color 0x00ff0000, got 0x%08x.\n", color);
9046     color = getPixelColor(device, 64+4, 64-4);
9047     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
9048             "Expected color 0x0000ff00, got 0x%08x.\n", color);
9049     color = getPixelColor(device, 64-4, 64+4);
9050     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
9051             "Expected color 0x00000000, got 0x%08x.\n", color);
9052     color = getPixelColor(device, 64+4, 64+4);
9053     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
9054             "Expected color 0x0000ff00, got 0x%08x.\n", color);
9055
9056     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9057     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
9058
9059     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9060     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9061     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9062     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9063     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9064     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9065     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
9066     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9067     IDirect3DTexture9_Release(tex1);
9068     IDirect3DTexture9_Release(tex2);
9069
9070     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
9071     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9072     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
9073     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9074     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
9075     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
9076 }
9077
9078 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
9079 {
9080     HRESULT hr;
9081     IDirect3DPixelShader9 *ps;
9082     IDirect3DTexture9 *tex1, *tex2;
9083     IDirect3DSurface9 *surf1, *surf2, *backbuf;
9084     D3DCAPS9 caps;
9085     DWORD color;
9086     DWORD shader_code[] = {
9087     0xffff0300,                                                             /* ps_3_0             */
9088     0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
9089     0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
9090     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0        */
9091     0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1        */
9092     0x0000ffff                                                              /* END                */
9093     };
9094     float quad[] = {
9095        -1.0,   -1.0,    0.1,
9096         1.0,   -1.0,    0.1,
9097        -1.0,    1.0,    0.1,
9098         1.0,    1.0,    0.1,
9099     };
9100     float texquad[] = {
9101        -1.0,   -1.0,    0.1,    0.0,    0.0,
9102         0.0,   -1.0,    0.1,    1.0,    0.0,
9103        -1.0,    1.0,    0.1,    0.0,    1.0,
9104         0.0,    1.0,    0.1,    1.0,    1.0,
9105
9106         0.0,   -1.0,    0.1,    0.0,    0.0,
9107         1.0,   -1.0,    0.1,    1.0,    0.0,
9108         0.0,    1.0,    0.1,    0.0,    1.0,
9109         1.0,    1.0,    0.1,    1.0,    1.0,
9110     };
9111
9112     memset(&caps, 0, sizeof(caps));
9113     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9114     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
9115     if(caps.NumSimultaneousRTs < 2) {
9116         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
9117         return;
9118     }
9119
9120     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
9121     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9122
9123     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
9124     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9125     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
9126     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9127     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
9128     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
9129
9130     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
9131     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
9132     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
9133     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9134     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
9135     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9136
9137     hr = IDirect3DDevice9_SetPixelShader(device, ps);
9138     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
9139     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
9140     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9141     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
9142     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9143     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9144     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9145
9146     hr = IDirect3DDevice9_BeginScene(device);
9147     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
9148     if(SUCCEEDED(hr)) {
9149         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
9150         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9151
9152         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9153         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
9154         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
9155         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9156         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
9157         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9158         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9159         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9160
9161         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9162         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9163         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
9164         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9165
9166         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
9167         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9168         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
9169         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9170
9171         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9172         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9173
9174         hr = IDirect3DDevice9_EndScene(device);
9175         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9176     }
9177
9178     color = getPixelColor(device, 160, 240);
9179     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
9180     color = getPixelColor(device, 480, 240);
9181     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
9182     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9183
9184     IDirect3DPixelShader9_Release(ps);
9185     IDirect3DTexture9_Release(tex1);
9186     IDirect3DTexture9_Release(tex2);
9187     IDirect3DSurface9_Release(surf1);
9188     IDirect3DSurface9_Release(surf2);
9189     IDirect3DSurface9_Release(backbuf);
9190 }
9191
9192 struct formats {
9193     const char *fmtName;
9194     D3DFORMAT textureFormat;
9195     DWORD resultColorBlending;
9196     DWORD resultColorNoBlending;
9197 };
9198
9199 const struct formats test_formats[] = {
9200   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
9201   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
9202   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
9203   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
9204   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
9205   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
9206   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
9207   { NULL, 0 }
9208 };
9209
9210 static void pixelshader_blending_test(IDirect3DDevice9 *device)
9211 {
9212     HRESULT hr;
9213     IDirect3DTexture9 *offscreenTexture = NULL;
9214     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
9215     IDirect3D9 *d3d = NULL;
9216     DWORD color;
9217     DWORD r0, g0, b0, r1, g1, b1;
9218     int fmt_index;
9219
9220     static const float quad[][5] = {
9221         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
9222         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
9223         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
9224         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
9225     };
9226
9227     /* Quad with R=0x10, G=0x20 */
9228     static const struct vertex quad1[] = {
9229         {-1.0f, -1.0f, 0.1f, 0x80102000},
9230         {-1.0f,  1.0f, 0.1f, 0x80102000},
9231         { 1.0f, -1.0f, 0.1f, 0x80102000},
9232         { 1.0f,  1.0f, 0.1f, 0x80102000},
9233     };
9234
9235     /* Quad with R=0x20, G=0x10 */
9236     static const struct vertex quad2[] = {
9237         {-1.0f, -1.0f, 0.1f, 0x80201000},
9238         {-1.0f,  1.0f, 0.1f, 0x80201000},
9239         { 1.0f, -1.0f, 0.1f, 0x80201000},
9240         { 1.0f,  1.0f, 0.1f, 0x80201000},
9241     };
9242
9243     IDirect3DDevice9_GetDirect3D(device, &d3d);
9244
9245     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9246     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
9247     if(!backbuffer) {
9248         goto out;
9249     }
9250
9251     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
9252     {
9253         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
9254         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
9255            skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
9256            continue;
9257         }
9258
9259         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9260         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9261
9262         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
9263         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
9264         if(!offscreenTexture) {
9265             continue;
9266         }
9267
9268         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
9269         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
9270         if(!offscreen) {
9271             continue;
9272         }
9273
9274         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9275         ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9276
9277         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9278         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9279         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9280         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9281         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
9282         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
9283         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
9284         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
9285         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9286         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9287
9288         /* Below we will draw two quads with different colors and try to blend them together.
9289          * The result color is compared with the expected outcome.
9290          */
9291         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
9292             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
9293             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9294             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
9295             ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9296
9297             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9298             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9299
9300             /* Draw a quad using color 0x0010200 */
9301             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
9302             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9303             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
9304             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9305             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9306             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9307
9308             /* Draw a quad using color 0x0020100 */
9309             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9310             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9311             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
9312             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9313             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9314             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9315
9316             /* We don't want to blend the result on the backbuffer */
9317             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9318             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9319
9320             /* Prepare rendering the 'blended' texture quad to the backbuffer */
9321             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9322             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9323             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
9324             ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
9325
9326             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9327             ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9328
9329             /* This time with the texture */
9330             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9331             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
9332
9333             IDirect3DDevice9_EndScene(device);
9334         }
9335
9336         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
9337             /* Compare the color of the center quad with our expectation */
9338             color = getPixelColor(device, 320, 240);
9339             r0 = (color & 0x00ff0000) >> 16;
9340             g0 = (color & 0x0000ff00) >>  8;
9341             b0 = (color & 0x000000ff) >>  0;
9342
9343             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
9344             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
9345             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
9346
9347             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9348                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9349                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9350                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9351         } else {
9352             /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9353              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9354              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9355             color = getPixelColor(device, 320, 240);
9356             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);
9357         }
9358         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9359
9360         IDirect3DDevice9_SetTexture(device, 0, NULL);
9361         if(offscreenTexture) {
9362             IDirect3DTexture9_Release(offscreenTexture);
9363         }
9364         if(offscreen) {
9365             IDirect3DSurface9_Release(offscreen);
9366         }
9367     }
9368
9369 out:
9370     /* restore things */
9371     if(backbuffer) {
9372         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9373         IDirect3DSurface9_Release(backbuffer);
9374     }
9375 }
9376
9377 static void tssargtemp_test(IDirect3DDevice9 *device)
9378 {
9379     HRESULT hr;
9380     DWORD color;
9381     static const struct vertex quad[] = {
9382         {-1.0,     -1.0,    0.1,    0x00ff0000},
9383         { 1.0,     -1.0,    0.1,    0x00ff0000},
9384         {-1.0,      1.0,    0.1,    0x00ff0000},
9385         { 1.0,      1.0,    0.1,    0x00ff0000}
9386     };
9387     D3DCAPS9 caps;
9388
9389     memset(&caps, 0, sizeof(caps));
9390     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9391     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9392     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9393         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9394         return;
9395     }
9396
9397     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9398     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9399
9400     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9401     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9402     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9403     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9404
9405     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9406     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9407     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9408     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9409     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9410     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9411
9412     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9413     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9414     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9415     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9416     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9417     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9418
9419     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9420     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9421
9422     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9423     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9424     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9425     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9426
9427     hr = IDirect3DDevice9_BeginScene(device);
9428     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9429     if(SUCCEEDED(hr)) {
9430         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9431         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9432         hr = IDirect3DDevice9_EndScene(device);
9433         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9434     }
9435     color = getPixelColor(device, 320, 240);
9436     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9437     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9438
9439     /* Set stage 1 back to default */
9440     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9441     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9442     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9443     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9444     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9445     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9446     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9447     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9448     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9449     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9450 }
9451
9452 struct testdata
9453 {
9454     DWORD idxVertex; /* number of instances in the first stream */
9455     DWORD idxColor; /* number of instances in the second stream */
9456     DWORD idxInstance; /* should be 1 ?? */
9457     DWORD color1; /* color 1 instance */
9458     DWORD color2; /* color 2 instance */
9459     DWORD color3; /* color 3 instance */
9460     DWORD color4; /* color 4 instance */
9461     WORD strVertex; /* specify which stream to use 0-2*/
9462     WORD strColor;
9463     WORD strInstance;
9464 };
9465
9466 static const struct testdata testcases[]=
9467 {
9468     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
9469     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
9470     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
9471     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
9472     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  4 */
9473     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
9474     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
9475     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
9476     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  8 */
9477     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  9 */
9478     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
9479     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
9480     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
9481     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
9482     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
9483 /*
9484     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
9485     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9486 */
9487 };
9488
9489 /* Drawing Indexed Geometry with instances*/
9490 static void stream_test(IDirect3DDevice9 *device)
9491 {
9492     IDirect3DVertexBuffer9 *vb = NULL;
9493     IDirect3DVertexBuffer9 *vb2 = NULL;
9494     IDirect3DVertexBuffer9 *vb3 = NULL;
9495     IDirect3DIndexBuffer9 *ib = NULL;
9496     IDirect3DVertexDeclaration9 *pDecl = NULL;
9497     IDirect3DVertexShader9 *shader = NULL;
9498     HRESULT hr;
9499     BYTE *data;
9500     DWORD color;
9501     DWORD ind;
9502     unsigned i;
9503
9504     const DWORD shader_code[] =
9505     {
9506         0xfffe0101,                                     /* vs_1_1 */
9507         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
9508         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
9509         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
9510         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
9511         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9512         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
9513         0x0000ffff
9514     };
9515
9516     const float quad[][3] =
9517     {
9518         {-0.5f, -0.5f,  1.1f}, /*0 */
9519         {-0.5f,  0.5f,  1.1f}, /*1 */
9520         { 0.5f, -0.5f,  1.1f}, /*2 */
9521         { 0.5f,  0.5f,  1.1f}, /*3 */
9522     };
9523
9524     const float vertcolor[][4] =
9525     {
9526         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9527         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9528         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9529         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9530     };
9531
9532     /* 4 position for 4 instances */
9533     const float instancepos[][3] =
9534     {
9535         {-0.6f,-0.6f, 0.0f},
9536         { 0.6f,-0.6f, 0.0f},
9537         { 0.6f, 0.6f, 0.0f},
9538         {-0.6f, 0.6f, 0.0f},
9539     };
9540
9541     short indices[] = {0, 1, 2, 1, 2, 3};
9542
9543     D3DVERTEXELEMENT9 decl[] =
9544     {
9545         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9546         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9547         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9548         D3DDECL_END()
9549     };
9550
9551     /* set the default value because it isn't done in wine? */
9552     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9553     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9554
9555     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9556     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9557     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9558
9559     /* check wrong cases */
9560     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9561     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9562     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9563     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9564     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9565     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9566     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9567     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9568     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9569     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9570     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9571     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9572     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9573     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9574     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9575     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9576     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9577     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9578     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9579     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9580
9581     /* set the default value back */
9582     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9583     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9584
9585     /* create all VertexBuffers*/
9586     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9587     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9588     if(!vb) {
9589         skip("Failed to create a vertex buffer\n");
9590         return;
9591     }
9592     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9593     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9594     if(!vb2) {
9595         skip("Failed to create a vertex buffer\n");
9596         goto out;
9597     }
9598     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9599     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9600     if(!vb3) {
9601         skip("Failed to create a vertex buffer\n");
9602         goto out;
9603     }
9604
9605     /* create IndexBuffer*/
9606     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9607     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9608     if(!ib) {
9609         skip("Failed to create a index buffer\n");
9610         goto out;
9611     }
9612
9613     /* copy all Buffers (Vertex + Index)*/
9614     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9615     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9616     memcpy(data, quad, sizeof(quad));
9617     hr = IDirect3DVertexBuffer9_Unlock(vb);
9618     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9619     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9620     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9621     memcpy(data, vertcolor, sizeof(vertcolor));
9622     hr = IDirect3DVertexBuffer9_Unlock(vb2);
9623     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9624     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9625     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9626     memcpy(data, instancepos, sizeof(instancepos));
9627     hr = IDirect3DVertexBuffer9_Unlock(vb3);
9628     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9629     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9630     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9631     memcpy(data, indices, sizeof(indices));
9632     hr = IDirect3DIndexBuffer9_Unlock(ib);
9633     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9634
9635     /* create VertexShader */
9636     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9637     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9638     if(!shader) {
9639         skip("Failed to create a vetex shader\n");
9640         goto out;
9641     }
9642
9643     hr = IDirect3DDevice9_SetVertexShader(device, shader);
9644     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9645
9646     hr = IDirect3DDevice9_SetIndices(device, ib);
9647     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9648
9649     /* run all tests */
9650     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9651     {
9652         struct testdata act = testcases[i];
9653         decl[0].Stream = act.strVertex;
9654         decl[1].Stream = act.strColor;
9655         decl[2].Stream = act.strInstance;
9656         /* create VertexDeclarations */
9657         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9658         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9659
9660         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9661         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9662
9663         hr = IDirect3DDevice9_BeginScene(device);
9664         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9665         if(SUCCEEDED(hr))
9666         {
9667             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9668             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9669
9670             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9671             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9672             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9673             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9674
9675             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9676             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9677             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9678             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9679
9680             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9681             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9682             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9683             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9684
9685             /* don't know if this is right (1*3 and 4*1)*/
9686             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
9687             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9688             hr = IDirect3DDevice9_EndScene(device);
9689             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9690
9691             /* set all StreamSource && StreamSourceFreq back to default */
9692             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9693             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9694             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9695             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9696             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9697             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9698             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9699             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9700             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9701             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9702             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9703             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9704         }
9705
9706         hr = IDirect3DVertexDeclaration9_Release(pDecl);
9707         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9708
9709         color = getPixelColor(device, 160, 360);
9710         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9711         color = getPixelColor(device, 480, 360);
9712         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9713         color = getPixelColor(device, 480, 120);
9714         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9715         color = getPixelColor(device, 160, 120);
9716         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9717
9718         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9719         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9720     }
9721
9722     hr = IDirect3DDevice9_SetIndices(device, NULL);
9723     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9724
9725 out:
9726     if(vb) IDirect3DVertexBuffer9_Release(vb);
9727     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9728     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9729     if(ib)IDirect3DIndexBuffer9_Release(ib);
9730     if(shader)IDirect3DVertexShader9_Release(shader);
9731 }
9732
9733 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9734     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9735     IDirect3DTexture9 *dsttex = NULL;
9736     HRESULT hr;
9737     DWORD color;
9738     D3DRECT r1 = {0,  0,  50,  50 };
9739     D3DRECT r2 = {50, 0,  100, 50 };
9740     D3DRECT r3 = {50, 50, 100, 100};
9741     D3DRECT r4 = {0,  50,  50, 100};
9742     const float quad[] = {
9743         -1.0,   -1.0,   0.1,    0.0,    0.0,
9744          1.0,   -1.0,   0.1,    1.0,    0.0,
9745         -1.0,    1.0,   0.1,    0.0,    1.0,
9746          1.0,    1.0,   0.1,    1.0,    1.0,
9747     };
9748
9749     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9750     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9751
9752     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9753     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9754     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9755     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9756
9757     if(!src || !dsttex) {
9758         skip("One or more test resources could not be created\n");
9759         goto cleanup;
9760     }
9761
9762     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9763     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9764
9765     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9766     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9767
9768     /* Clear the StretchRect destination for debugging */
9769     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9770     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9771     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9772     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9773
9774     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9775     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9776
9777     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9778     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9779     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9780     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9781     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9782     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9783     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9784     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9785
9786     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9787      * the target -> texture GL blit path
9788      */
9789     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9790     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9791     IDirect3DSurface9_Release(dst);
9792
9793     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9794     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9795
9796     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9797     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9798     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9799     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9800     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9801     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9802     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9803     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9804
9805     hr = IDirect3DDevice9_BeginScene(device);
9806     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9807     if(SUCCEEDED(hr)) {
9808         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9809         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9810         hr = IDirect3DDevice9_EndScene(device);
9811         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9812     }
9813
9814     color = getPixelColor(device, 160, 360);
9815     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9816     color = getPixelColor(device, 480, 360);
9817     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9818     color = getPixelColor(device, 480, 120);
9819     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9820     color = getPixelColor(device, 160, 120);
9821     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9822     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9823     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9824
9825     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9826     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9827     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9828     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9829
9830 cleanup:
9831     if(src) IDirect3DSurface9_Release(src);
9832     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9833     if(dsttex) IDirect3DTexture9_Release(dsttex);
9834 }
9835
9836 static void texop_test(IDirect3DDevice9 *device)
9837 {
9838     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9839     IDirect3DTexture9 *texture = NULL;
9840     D3DLOCKED_RECT locked_rect;
9841     D3DCOLOR color;
9842     D3DCAPS9 caps;
9843     HRESULT hr;
9844     unsigned i;
9845
9846     static const struct {
9847         float x, y, z;
9848         float s, t;
9849         D3DCOLOR diffuse;
9850     } quad[] = {
9851         {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9852         {-1.0f,  1.0f, 0.1f, -1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9853         { 1.0f, -1.0f, 0.1f,  1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9854         { 1.0f,  1.0f, 0.1f,  1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9855     };
9856
9857     static const D3DVERTEXELEMENT9 decl_elements[] = {
9858         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9859         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9860         {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9861         D3DDECL_END()
9862     };
9863
9864     static const struct {
9865         D3DTEXTUREOP op;
9866         const char *name;
9867         DWORD caps_flag;
9868         D3DCOLOR result;
9869     } test_data[] = {
9870         {D3DTOP_SELECTARG1,                "SELECTARG1",                D3DTEXOPCAPS_SELECTARG1,                D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9871         {D3DTOP_SELECTARG2,                "SELECTARG2",                D3DTEXOPCAPS_SELECTARG2,                D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9872         {D3DTOP_MODULATE,                  "MODULATE",                  D3DTEXOPCAPS_MODULATE,                  D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9873         {D3DTOP_MODULATE2X,                "MODULATE2X",                D3DTEXOPCAPS_MODULATE2X,                D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9874         {D3DTOP_MODULATE4X,                "MODULATE4X",                D3DTEXOPCAPS_MODULATE4X,                D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9875         {D3DTOP_ADD,                       "ADD",                       D3DTEXOPCAPS_ADD,                       D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9876         {D3DTOP_ADDSIGNED,                 "ADDSIGNED",                 D3DTEXOPCAPS_ADDSIGNED,                 D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9877         {D3DTOP_ADDSIGNED2X,               "ADDSIGNED2X",               D3DTEXOPCAPS_ADDSIGNED2X,               D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9878         {D3DTOP_SUBTRACT,                  "SUBTRACT",                  D3DTEXOPCAPS_SUBTRACT,                  D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9879         {D3DTOP_ADDSMOOTH,                 "ADDSMOOTH",                 D3DTEXOPCAPS_ADDSMOOTH,                 D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9880         {D3DTOP_BLENDDIFFUSEALPHA,         "BLENDDIFFUSEALPHA",         D3DTEXOPCAPS_BLENDDIFFUSEALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9881         {D3DTOP_BLENDTEXTUREALPHA,         "BLENDTEXTUREALPHA",         D3DTEXOPCAPS_BLENDTEXTUREALPHA,         D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9882         {D3DTOP_BLENDFACTORALPHA,          "BLENDFACTORALPHA",          D3DTEXOPCAPS_BLENDFACTORALPHA,          D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9883         {D3DTOP_BLENDTEXTUREALPHAPM,       "BLENDTEXTUREALPHAPM",       D3DTEXOPCAPS_BLENDTEXTUREALPHAPM,       D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9884         {D3DTOP_BLENDCURRENTALPHA,         "BLENDCURRENTALPHA",         D3DTEXOPCAPS_BLENDCURRENTALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9885         {D3DTOP_MODULATEALPHA_ADDCOLOR,    "MODULATEALPHA_ADDCOLOR",    D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR,    D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9886         {D3DTOP_MODULATECOLOR_ADDALPHA,    "MODULATECOLOR_ADDALPHA",    D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA,    D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9887         {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9888         {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9889         /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9890         {D3DTOP_DOTPRODUCT3,               "DOTPRODUCT3",               D3DTEXOPCAPS_DOTPRODUCT3,               D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9891         {D3DTOP_MULTIPLYADD,               "MULTIPLYADD",               D3DTEXOPCAPS_MULTIPLYADD,               D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9892         {D3DTOP_LERP,                      "LERP",                      D3DTEXOPCAPS_LERP,                      D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9893     };
9894
9895     memset(&caps, 0, sizeof(caps));
9896     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9897     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9898
9899     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9900     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9901     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9902     ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9903
9904     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9905     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9906     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9907     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9908     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9909     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9910     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9911     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9912     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9913
9914     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9915     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9916     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9917     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9918     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9919     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9920
9921     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9922     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9923
9924     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9925     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9926     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9927     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9928     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9929     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9930
9931     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9932     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9933
9934     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9935     {
9936         if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9937         {
9938             skip("tex operation %s not supported\n", test_data[i].name);
9939             continue;
9940         }
9941
9942         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9943         ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9944
9945         hr = IDirect3DDevice9_BeginScene(device);
9946         ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9947
9948         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9949         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9950
9951         hr = IDirect3DDevice9_EndScene(device);
9952         ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9953
9954         color = getPixelColor(device, 320, 240);
9955         ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9956                 test_data[i].name, color, test_data[i].result);
9957
9958         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9959         ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9960     }
9961
9962     if (texture) IDirect3DTexture9_Release(texture);
9963     if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9964 }
9965
9966 static void yuv_color_test(IDirect3DDevice9 *device) {
9967     HRESULT hr;
9968     IDirect3DSurface9 *surface = NULL, *target = NULL;
9969     unsigned int fmt, i;
9970     D3DFORMAT format;
9971     const char *fmt_string;
9972     D3DLOCKED_RECT lr;
9973     IDirect3D9 *d3d;
9974     HRESULT color;
9975     DWORD ref_color_left, ref_color_right;
9976
9977     struct {
9978         DWORD in;           /* The input color */
9979         DWORD uyvy_left;    /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9980         DWORD uyvy_right;   /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9981         DWORD yuy2_left;    /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9982         DWORD yuy2_right;   /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9983     } test_data[] = {
9984     /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9985      * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9986      * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9987      * that
9988      */
9989       { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9990       { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9991       { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9992       { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9993       { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9994       { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9995       { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9996       { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9997       { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9998       { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9999       { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
10000       { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
10001       { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
10002       { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
10003
10004       { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
10005       { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
10006       { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
10007       { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
10008     };
10009
10010     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
10011     ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
10012     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
10013     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
10014
10015     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
10016     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
10017
10018     for(fmt = 0; fmt < 2; fmt++) {
10019         if(fmt == 0) {
10020             format = D3DFMT_UYVY;
10021             fmt_string = "D3DFMT_UYVY";
10022         } else {
10023             format = D3DFMT_YUY2;
10024             fmt_string = "D3DFMT_YUY2";
10025         }
10026
10027         /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
10028                        * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
10029                        */
10030         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
10031                                         D3DRTYPE_SURFACE, format) != D3D_OK) {
10032             skip("%s is not supported\n", fmt_string);
10033             continue;
10034         }
10035
10036         /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
10037         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
10038         ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
10039
10040         for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
10041             if(fmt == 0) {
10042                 ref_color_left = test_data[i].uyvy_left;
10043                 ref_color_right = test_data[i].uyvy_right;
10044             } else {
10045                 ref_color_left = test_data[i].yuy2_left;
10046                 ref_color_right = test_data[i].yuy2_right;
10047             }
10048
10049             memset(&lr, 0, sizeof(lr));
10050             hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
10051             ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
10052             *((DWORD *) lr.pBits) = test_data[i].in;
10053             hr = IDirect3DSurface9_UnlockRect(surface);
10054             ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
10055
10056             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10057             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10058             hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
10059             ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
10060
10061             /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
10062              * prevent running into precision problems, read a far left and far right pixel. In the future we may
10063              * want to add tests for the filtered pixels as well.
10064              *
10065              * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
10066              * differently, so we need a max diff of 16
10067              */
10068             color = getPixelColor(device, 40, 240);
10069             ok(color_match(color, ref_color_left, 18),
10070                "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
10071                test_data[i].in, color, ref_color_left, fmt_string);
10072             color = getPixelColor(device, 600, 240);
10073             ok(color_match(color, ref_color_right, 18),
10074                "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
10075                test_data[i].in, color, ref_color_right, fmt_string);
10076             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10077             ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10078         }
10079         IDirect3DSurface9_Release(surface);
10080     }
10081     IDirect3DSurface9_Release(target);
10082     IDirect3D9_Release(d3d);
10083 }
10084
10085 static void texop_range_test(IDirect3DDevice9 *device)
10086 {
10087     static const struct {
10088         float x, y, z;
10089         D3DCOLOR diffuse;
10090     } quad[] = {
10091         {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10092         {-1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10093         { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10094         { 1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
10095     };
10096     HRESULT hr;
10097     IDirect3DTexture9 *texture;
10098     D3DLOCKED_RECT locked_rect;
10099     D3DCAPS9 caps;
10100     DWORD color;
10101
10102     /* We need ADD and SUBTRACT operations */
10103     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10104     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10105     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
10106         skip("D3DTOP_ADD is not supported, skipping value range test\n");
10107         return;
10108     }
10109     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
10110         skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
10111         return;
10112     }
10113
10114     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10115     ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
10116     /* Stage 1: result = diffuse(=1.0) + diffuse
10117      * stage 2: result = result - tfactor(= 0.5)
10118      */
10119     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10120     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10121     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10122     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10123     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10124     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10125     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
10126     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10127     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10128     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10129     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10130     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10131     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10132     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10133
10134     hr = IDirect3DDevice9_BeginScene(device);
10135     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10136     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10137     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10138     hr = IDirect3DDevice9_EndScene(device);
10139     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10140
10141     color = getPixelColor(device, 320, 240);
10142     ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
10143        color);
10144     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10145     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10146
10147     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
10148     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
10149     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
10150     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10151     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
10152     hr = IDirect3DTexture9_UnlockRect(texture, 0);
10153     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10154     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10155     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10156
10157     /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
10158      * stage 2: result = result + diffuse(1.0)
10159      */
10160     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10161     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10162     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10163     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10164     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10165     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10166     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10167     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10168     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10169     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10170     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10171     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10172     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
10173     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10174
10175     hr = IDirect3DDevice9_BeginScene(device);
10176     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10177     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10178     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10179     hr = IDirect3DDevice9_EndScene(device);
10180     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10181
10182     color = getPixelColor(device, 320, 240);
10183     ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
10184        color);
10185     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10186     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10187
10188     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10189     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10190     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10191     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10192     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
10193     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10194     IDirect3DTexture9_Release(texture);
10195 }
10196
10197 static void alphareplicate_test(IDirect3DDevice9 *device) {
10198     struct vertex quad[] = {
10199         { -1.0,    -1.0,    0.1,    0x80ff00ff },
10200         {  1.0,    -1.0,    0.1,    0x80ff00ff },
10201         { -1.0,     1.0,    0.1,    0x80ff00ff },
10202         {  1.0,     1.0,    0.1,    0x80ff00ff },
10203     };
10204     HRESULT hr;
10205     DWORD color;
10206
10207     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10208     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10209
10210     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10211     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10212
10213     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10214     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10215     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
10216     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10217
10218     hr = IDirect3DDevice9_BeginScene(device);
10219     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10220     if(SUCCEEDED(hr)) {
10221         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10222         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10223         hr = IDirect3DDevice9_EndScene(device);
10224         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10225     }
10226
10227     color = getPixelColor(device, 320, 240);
10228     ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
10229        color);
10230     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10231     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10232
10233     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10234     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10235
10236 }
10237
10238 static void dp3_alpha_test(IDirect3DDevice9 *device) {
10239     HRESULT hr;
10240     D3DCAPS9 caps;
10241     DWORD color;
10242     struct vertex quad[] = {
10243         { -1.0,    -1.0,    0.1,    0x408080c0 },
10244         {  1.0,    -1.0,    0.1,    0x408080c0 },
10245         { -1.0,     1.0,    0.1,    0x408080c0 },
10246         {  1.0,     1.0,    0.1,    0x408080c0 },
10247     };
10248
10249     memset(&caps, 0, sizeof(caps));
10250     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10251     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10252     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
10253         skip("D3DTOP_DOTPRODUCT3 not supported\n");
10254         return;
10255     }
10256
10257     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10258     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10259
10260     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10261     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10262
10263     /* dp3_x4 r0, diffuse_bias, tfactor_bias
10264      * mov r0.a, diffuse.a
10265      * mov r0, r0.a
10266      *
10267      * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
10268      * 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
10269      * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
10270      */
10271     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
10272     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10273     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10274     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10275     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10276     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10277     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
10278     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10279     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
10280     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10281     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10282     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10283     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
10284     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10285     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10286     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10287     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
10288     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10289
10290     hr = IDirect3DDevice9_BeginScene(device);
10291     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10292     if(SUCCEEDED(hr)) {
10293         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10294         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10295         hr = IDirect3DDevice9_EndScene(device);
10296         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10297     }
10298
10299     color = getPixelColor(device, 320, 240);
10300     ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
10301        color);
10302     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10303     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10304
10305     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10306     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10307     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10308     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10309     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10310     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10311 }
10312
10313 static void zwriteenable_test(IDirect3DDevice9 *device) {
10314     HRESULT hr;
10315     DWORD color;
10316     struct vertex quad1[] = {
10317         { -1.0,  -1.0,  0.1,    0x00ff0000},
10318         { -1.0,   1.0,  0.1,    0x00ff0000},
10319         {  1.0,  -1.0,  0.1,    0x00ff0000},
10320         {  1.0,   1.0,  0.1,    0x00ff0000},
10321     };
10322     struct vertex quad2[] = {
10323         { -1.0,  -1.0,  0.9,    0x0000ff00},
10324         { -1.0,   1.0,  0.9,    0x0000ff00},
10325         {  1.0,  -1.0,  0.9,    0x0000ff00},
10326         {  1.0,   1.0,  0.9,    0x0000ff00},
10327     };
10328
10329     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
10330     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10331
10332     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10333     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10334     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10335     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10336     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10337     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10338     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10339     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10340
10341     hr = IDirect3DDevice9_BeginScene(device);
10342     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10343     if(SUCCEEDED(hr)) {
10344         /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10345          * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10346          * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10347          * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10348          * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10349          * the screen is green, so zenable = D3DZB_FALSE and zwriteenable  = TRUE does NOT write to the z buffer.
10350          */
10351         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10352         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10353         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10354         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10355         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10356         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10357
10358         hr = IDirect3DDevice9_EndScene(device);
10359         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10360     }
10361
10362     color = getPixelColor(device, 320, 240);
10363     ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10364        color);
10365     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10366     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10367
10368     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10369     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10370 }
10371
10372 static void alphatest_test(IDirect3DDevice9 *device) {
10373 #define ALPHATEST_PASSED 0x0000ff00
10374 #define ALPHATEST_FAILED 0x00ff0000
10375     struct {
10376         D3DCMPFUNC  func;
10377         DWORD       color_less;
10378         DWORD       color_equal;
10379         DWORD       color_greater;
10380     } testdata[] = {
10381         {   D3DCMP_NEVER,           ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10382         {   D3DCMP_LESS,            ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10383         {   D3DCMP_EQUAL,           ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10384         {   D3DCMP_LESSEQUAL,       ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10385         {   D3DCMP_GREATER,         ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10386         {   D3DCMP_NOTEQUAL,        ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10387         {   D3DCMP_GREATEREQUAL,    ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10388         {   D3DCMP_ALWAYS,          ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10389     };
10390     unsigned int i, j;
10391     HRESULT hr;
10392     DWORD color;
10393     struct vertex quad[] = {
10394         {   -1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10395         {    1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10396         {   -1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10397         {    1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10398     };
10399     D3DCAPS9 caps;
10400
10401     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10402     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10403     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10404     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10405
10406     for(j = 0; j < 2; j++) {
10407         if(j == 1) {
10408             /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10409              * the alpha test either for performance reasons(floating point RTs) or to work
10410              * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10411              * codepath for ffp and shader in this case, and the test should cover both
10412              */
10413             IDirect3DPixelShader9 *ps;
10414             DWORD shader_code[] = {
10415                 0xffff0101,                                 /* ps_1_1           */
10416                 0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
10417                 0x0000ffff                                  /* end              */
10418             };
10419             memset(&caps, 0, sizeof(caps));
10420             IDirect3DDevice9_GetDeviceCaps(device, &caps);
10421             ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10422             if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10423                 break;
10424             }
10425
10426             hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10427             ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10428             IDirect3DDevice9_SetPixelShader(device, ps);
10429             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10430             IDirect3DPixelShader9_Release(ps);
10431         }
10432
10433         for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10434             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10435             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10436
10437             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10438             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10439             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10440             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10441             hr = IDirect3DDevice9_BeginScene(device);
10442             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10443             if(SUCCEEDED(hr)) {
10444                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10445                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10446                 hr = IDirect3DDevice9_EndScene(device);
10447                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10448             }
10449             color = getPixelColor(device, 320, 240);
10450             ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10451             color, testdata[i].color_less, testdata[i].func);
10452             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10453             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10454
10455             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10456             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10457             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10458             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10459             hr = IDirect3DDevice9_BeginScene(device);
10460             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10461             if(SUCCEEDED(hr)) {
10462                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10463                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10464                 hr = IDirect3DDevice9_EndScene(device);
10465                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10466             }
10467             color = getPixelColor(device, 320, 240);
10468             ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10469             color, testdata[i].color_equal, testdata[i].func);
10470             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10471             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10472
10473             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10474             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10475             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10476             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10477             hr = IDirect3DDevice9_BeginScene(device);
10478             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10479             if(SUCCEEDED(hr)) {
10480                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10481                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10482                 hr = IDirect3DDevice9_EndScene(device);
10483                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10484             }
10485             color = getPixelColor(device, 320, 240);
10486             ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10487             color, testdata[i].color_greater, testdata[i].func);
10488             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10489             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10490         }
10491     }
10492
10493     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10494     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10495     IDirect3DDevice9_SetPixelShader(device, NULL);
10496     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10497 }
10498
10499 static void sincos_test(IDirect3DDevice9 *device) {
10500     const DWORD sin_shader_code[] = {
10501         0xfffe0200,                                                                 /* vs_2_0                       */
10502         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10503         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10504         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10505         0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.y, r1.x, c0, c1    */
10506         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10507         0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002,                             /* mul oPos.y, r0.y, c2.w       */
10508         0x02000001, 0xd00f0000, 0xa0a60002,                                         /* mov oD0, c2.zyzz             */
10509         0x0000ffff                                                                  /* end                          */
10510     };
10511     const DWORD cos_shader_code[] = {
10512         0xfffe0200,                                                                 /* vs_2_0                       */
10513         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10514         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10515         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10516         0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.x, r1.x, c0, c1    */
10517         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10518         0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002,                             /* mul oPos.y, r0.x, c2.w       */
10519         0x02000001, 0xd00f0000, 0xa0a90002,                                         /* mov oD0, c2.yzzz             */
10520         0x0000ffff                                                                  /* end                          */
10521     };
10522     IDirect3DVertexShader9 *sin_shader, *cos_shader;
10523     HRESULT hr;
10524     struct {
10525         float x, y, z;
10526     } data[1280];
10527     unsigned int i;
10528     float sincosc1[4] = {D3DSINCOSCONST1};
10529     float sincosc2[4] = {D3DSINCOSCONST2};
10530
10531     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10532     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10533
10534     hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10535     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10536     hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10537     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10538     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10539     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10540     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10541     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10542     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10543     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10544
10545     /* Generate a point from -1 to 1 every 0.5 pixels */
10546     for(i = 0; i < 1280; i++) {
10547         data[i].x = (-640.0 + i) / 640.0;
10548         data[i].y = 0.0;
10549         data[i].z = 0.1;
10550     }
10551
10552     hr = IDirect3DDevice9_BeginScene(device);
10553     if(SUCCEEDED(hr)) {
10554         hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10555         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10556         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10557         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10558
10559         hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10560         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10561         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10562         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10563
10564         hr = IDirect3DDevice9_EndScene(device);
10565         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10566     }
10567     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10568     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10569     /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10570
10571     IDirect3DDevice9_SetVertexShader(device, NULL);
10572     IDirect3DVertexShader9_Release(sin_shader);
10573     IDirect3DVertexShader9_Release(cos_shader);
10574 }
10575
10576 static void loop_index_test(IDirect3DDevice9 *device) {
10577     const DWORD shader_code[] = {
10578         0xfffe0200,                                                 /* vs_2_0                   */
10579         0x0200001f, 0x80000000, 0x900f0000,                         /* dcl_position v0          */
10580         0x02000001, 0x800f0000, 0xa0e40000,                         /* mov r0, c0               */
10581         0x0200001b, 0xf0e40800, 0xf0e40000,                         /* loop aL, i0              */
10582         0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1]    */
10583         0x0000001d,                                                 /* endloop                  */
10584         0x02000001, 0xc00f0000, 0x90e40000,                         /* mov oPos, v0             */
10585         0x02000001, 0xd00f0000, 0x80e40000,                         /* mov oD0, r0              */
10586         0x0000ffff                                                  /* END                      */
10587     };
10588     IDirect3DVertexShader9 *shader;
10589     HRESULT hr;
10590     DWORD color;
10591     const float quad[] = {
10592         -1.0,   -1.0,   0.1,
10593          1.0,   -1.0,   0.1,
10594         -1.0,    1.0,   0.1,
10595          1.0,    1.0,   0.1
10596     };
10597     const float zero[4] = {0, 0, 0, 0};
10598     const float one[4] = {1, 1, 1, 1};
10599     int i0[4] = {2, 10, -3, 0};
10600     float values[4];
10601
10602     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10603     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10604     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10605     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10606     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10607     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10608     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10609     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10610
10611     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10612     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10613     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10614     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10615     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10616     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10617     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10618     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10619     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10620     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10621     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10622     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10623     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10624     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10625     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10626     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10627     values[0] = 1.0;
10628     values[1] = 1.0;
10629     values[2] = 0.0;
10630     values[3] = 0.0;
10631     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10632     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10633     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10634     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10635     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10636     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10637     values[0] = -1.0;
10638     values[1] = 0.0;
10639     values[2] = 0.0;
10640     values[3] = 0.0;
10641     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10642     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10643     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10644     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10645     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10646     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10647     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10648     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10649     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10650     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10651
10652     hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10653     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10654
10655     hr = IDirect3DDevice9_BeginScene(device);
10656     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10657     if(SUCCEEDED(hr))
10658     {
10659         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10660         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10661         hr = IDirect3DDevice9_EndScene(device);
10662         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10663     }
10664     color = getPixelColor(device, 320, 240);
10665     ok(color_match(color, 0x0000ff00, 1),
10666        "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10667     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10668     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10669
10670     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10671     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10672     IDirect3DVertexShader9_Release(shader);
10673 }
10674
10675 static void sgn_test(IDirect3DDevice9 *device) {
10676     const DWORD shader_code[] = {
10677         0xfffe0200,                                                             /* vs_2_0                       */
10678         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position o0              */
10679         0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10680         0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0   */
10681         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
10682         0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002,             /* sgn r0, c0, r1, r2           */
10683         0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001,                         /* add oD0, r0, c1              */
10684         0x0000ffff                                                              /* end                          */
10685     };
10686     IDirect3DVertexShader9 *shader;
10687     HRESULT hr;
10688     DWORD color;
10689     const float quad[] = {
10690         -1.0,   -1.0,   0.1,
10691          1.0,   -1.0,   0.1,
10692         -1.0,    1.0,   0.1,
10693          1.0,    1.0,   0.1
10694     };
10695
10696     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10697     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10698     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10699     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10700     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10701     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10702     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10703     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10704
10705     hr = IDirect3DDevice9_BeginScene(device);
10706     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10707     if(SUCCEEDED(hr))
10708     {
10709         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10710         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10711         hr = IDirect3DDevice9_EndScene(device);
10712         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10713     }
10714     color = getPixelColor(device, 320, 240);
10715     ok(color_match(color, 0x008000ff, 1),
10716        "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10717     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10718     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10719
10720     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10721     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10722     IDirect3DVertexShader9_Release(shader);
10723 }
10724
10725 static void viewport_test(IDirect3DDevice9 *device) {
10726     HRESULT hr;
10727     DWORD color;
10728     D3DVIEWPORT9 vp, old_vp;
10729     const float quad[] =
10730     {
10731         -0.5,   -0.5,   0.1,
10732          0.5,   -0.5,   0.1,
10733         -0.5,    0.5,   0.1,
10734          0.5,    0.5,   0.1
10735     };
10736
10737     memset(&old_vp, 0, sizeof(old_vp));
10738     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10739     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10740
10741     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10742     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10743
10744     /* Test a viewport with Width and Height bigger than the surface dimensions
10745      *
10746      * TODO: Test Width < surface.width, but X + Width > surface.width
10747      * TODO: Test Width < surface.width, what happens with the height?
10748      */
10749     memset(&vp, 0, sizeof(vp));
10750     vp.X = 0;
10751     vp.Y = 0;
10752     vp.Width = 10000;
10753     vp.Height = 10000;
10754     vp.MinZ = 0.0;
10755     vp.MaxZ = 0.0;
10756     hr = IDirect3DDevice9_SetViewport(device, &vp);
10757     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10758
10759     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10760     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10761     hr = IDirect3DDevice9_BeginScene(device);
10762     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10763     if(SUCCEEDED(hr))
10764     {
10765         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10766         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10767         hr = IDirect3DDevice9_EndScene(device);
10768         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10769     }
10770
10771     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10772     color = getPixelColor(device, 158, 118);
10773     ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10774     color = getPixelColor(device, 162, 118);
10775     ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10776     color = getPixelColor(device, 158, 122);
10777     ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10778     color = getPixelColor(device, 162, 122);
10779     ok(color == 0x00ffffff, "viewport test: (162,122) has color %08x\n", color);
10780
10781     color = getPixelColor(device, 478, 358);
10782     ok(color == 0x00ffffff, "viewport test: (478,358 has color %08x\n", color);
10783     color = getPixelColor(device, 482, 358);
10784     ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10785     color = getPixelColor(device, 478, 362);
10786     ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10787     color = getPixelColor(device, 482, 362);
10788     ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10789
10790     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10791     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10792
10793     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10794     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10795 }
10796
10797 /* This test tests depth clamping / clipping behaviour:
10798  *   - When D3DRS_CLIPPING is disabled depth values are *clamped* to the
10799  *   minimum/maximum z value.
10800  *   - The viewport's MinZ/MaxZ is irrelevant for this.
10801  *   - When D3DRS_CLIPPING is enabled depth values are clipped.
10802  *   - Pretransformed vertices behave the same as regular vertices.
10803  */
10804 static void depth_clamp_test(IDirect3DDevice9 *device)
10805 {
10806     const struct tvertex quad1[] =
10807     {
10808         {    0,    0,  5.0f, 1.0, 0xff002b7f},
10809         {  640,    0,  5.0f, 1.0, 0xff002b7f},
10810         {    0,  480,  5.0f, 1.0, 0xff002b7f},
10811         {  640,  480,  5.0f, 1.0, 0xff002b7f},
10812     };
10813     const struct tvertex quad2[] =
10814     {
10815         {    0,  300, 10.0f, 1.0, 0xfff9e814},
10816         {  640,  300, 10.0f, 1.0, 0xfff9e814},
10817         {    0,  360, 10.0f, 1.0, 0xfff9e814},
10818         {  640,  360, 10.0f, 1.0, 0xfff9e814},
10819     };
10820     const struct vertex quad3[] =
10821     {
10822         {-0.65, 0.55,  5.0f,      0xffffffff},
10823         {-0.35, 0.55,  5.0f,      0xffffffff},
10824         {-0.65, 0.15,  5.0f,      0xffffffff},
10825         {-0.35, 0.15,  5.0f,      0xffffffff},
10826     };
10827     const struct vertex quad4[] =
10828     {
10829         {-0.87, 0.83, 10.0f,      0xffffffff},
10830         {-0.65, 0.83, 10.0f,      0xffffffff},
10831         {-0.87, 0.55, 10.0f,      0xffffffff},
10832         {-0.65, 0.55, 10.0f,      0xffffffff},
10833     };
10834     const struct vertex quad5[] =
10835     {
10836         { -0.5,  0.5, 10.0f,      0xff14f914},
10837         {  0.5,  0.5, 10.0f,      0xff14f914},
10838         { -0.5, -0.5, 10.0f,      0xff14f914},
10839         {  0.5, -0.5, 10.0f,      0xff14f914},
10840     };
10841     const struct tvertex quad6[] =
10842     {
10843         {    0,  120, 10.0f, 1.0, 0xfff91414},
10844         {  640,  120, 10.0f, 1.0, 0xfff91414},
10845         {    0,  180, 10.0f, 1.0, 0xfff91414},
10846         {  640,  180, 10.0f, 1.0, 0xfff91414},
10847     };
10848
10849     D3DVIEWPORT9 vp;
10850     D3DCOLOR color;
10851     HRESULT hr;
10852
10853     vp.X = 0;
10854     vp.Y = 0;
10855     vp.Width = 640;
10856     vp.Height = 480;
10857     vp.MinZ = 0.0;
10858     vp.MaxZ = 7.5;
10859
10860     hr = IDirect3DDevice9_SetViewport(device, &vp);
10861     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10862
10863     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
10864     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10865
10866     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10867     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10868     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10869     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10870     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10871     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10872     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10873     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10874
10875     hr = IDirect3DDevice9_BeginScene(device);
10876     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10877
10878     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10879     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10880
10881     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10882     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10883     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10884     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10885
10886     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10887     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10888
10889     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10890     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10891     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
10892     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10893
10894     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10895     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10896
10897     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
10898     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10899
10900     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10901     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10902
10903     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
10904     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10905
10906     hr = IDirect3DDevice9_EndScene(device);
10907     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10908
10909     color = getPixelColor(device, 75, 75);
10910     ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10911     color = getPixelColor(device, 150, 150);
10912     ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10913     color = getPixelColor(device, 320, 240);
10914     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10915     color = getPixelColor(device, 320, 330);
10916     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10917     color = getPixelColor(device, 320, 330);
10918     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10919
10920     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10921     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10922
10923     vp.MinZ = 0.0;
10924     vp.MaxZ = 1.0;
10925     hr = IDirect3DDevice9_SetViewport(device, &vp);
10926     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10927 }
10928
10929 static void depth_buffer_test(IDirect3DDevice9 *device)
10930 {
10931     static const struct vertex quad1[] =
10932     {
10933         { -1.0,  1.0, 0.33f, 0xff00ff00},
10934         {  1.0,  1.0, 0.33f, 0xff00ff00},
10935         { -1.0, -1.0, 0.33f, 0xff00ff00},
10936         {  1.0, -1.0, 0.33f, 0xff00ff00},
10937     };
10938     static const struct vertex quad2[] =
10939     {
10940         { -1.0,  1.0, 0.50f, 0xffff00ff},
10941         {  1.0,  1.0, 0.50f, 0xffff00ff},
10942         { -1.0, -1.0, 0.50f, 0xffff00ff},
10943         {  1.0, -1.0, 0.50f, 0xffff00ff},
10944     };
10945     static const struct vertex quad3[] =
10946     {
10947         { -1.0,  1.0, 0.66f, 0xffff0000},
10948         {  1.0,  1.0, 0.66f, 0xffff0000},
10949         { -1.0, -1.0, 0.66f, 0xffff0000},
10950         {  1.0, -1.0, 0.66f, 0xffff0000},
10951     };
10952     static const DWORD expected_colors[4][4] =
10953     {
10954         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10955         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10956         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
10957         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
10958     };
10959
10960     IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
10961     unsigned int i, j;
10962     D3DVIEWPORT9 vp;
10963     D3DCOLOR color;
10964     HRESULT hr;
10965
10966     vp.X = 0;
10967     vp.Y = 0;
10968     vp.Width = 640;
10969     vp.Height = 480;
10970     vp.MinZ = 0.0;
10971     vp.MaxZ = 1.0;
10972
10973     hr = IDirect3DDevice9_SetViewport(device, &vp);
10974     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10975
10976     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10977     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10978     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10979     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10980     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10981     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10982     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10983     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10984     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10985     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10986
10987     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
10988     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10989     hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
10990             D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
10991     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10992     hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
10993             D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
10994     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10995     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
10996             D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
10997     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10998
10999     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
11000     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11001     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
11002     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11003
11004     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11005     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11006     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11007     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11008
11009     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11010     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11011     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11012     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11013
11014     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11015     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11016     hr = IDirect3DDevice9_BeginScene(device);
11017     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11018     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11019     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11020     hr = IDirect3DDevice9_EndScene(device);
11021     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11022
11023     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11024     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11025     IDirect3DSurface9_Release(backbuffer);
11026     IDirect3DSurface9_Release(rt3);
11027     IDirect3DSurface9_Release(rt2);
11028     IDirect3DSurface9_Release(rt1);
11029
11030     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11031     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11032
11033     hr = IDirect3DDevice9_BeginScene(device);
11034     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11035     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11036     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11037     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11038     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11039     hr = IDirect3DDevice9_EndScene(device);
11040     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11041
11042     for (i = 0; i < 4; ++i)
11043     {
11044         for (j = 0; j < 4; ++j)
11045         {
11046             unsigned int x = 80 * ((2 * j) + 1);
11047             unsigned int y = 60 * ((2 * i) + 1);
11048             color = getPixelColor(device, x, y);
11049             ok(color_match(color, expected_colors[i][j], 0),
11050                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11051         }
11052     }
11053
11054     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11055     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11056 }
11057
11058 static void shadow_test(IDirect3DDevice9 *device)
11059 {
11060     static const DWORD ps_code[] =
11061     {
11062         0xffff0200,                                                             /* ps_2_0                       */
11063         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
11064         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
11065         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
11066         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
11067         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
11068         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
11069         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
11070         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
11071         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov 0C0, r1                  */
11072         0x0000ffff,                                                             /* end                          */
11073     };
11074     struct
11075     {
11076         D3DFORMAT format;
11077         const char *name;
11078     }
11079     formats[] =
11080     {
11081         {D3DFMT_D16_LOCKABLE,   "D3DFMT_D16_LOCKABLE"},
11082         {D3DFMT_D32,            "D3DFMT_D32"},
11083         {D3DFMT_D15S1,          "D3DFMT_D15S1"},
11084         {D3DFMT_D24S8,          "D3DFMT_D24S8"},
11085         {D3DFMT_D24X8,          "D3DFMT_D24X8"},
11086         {D3DFMT_D24X4S4,        "D3DFMT_D24X4S4"},
11087         {D3DFMT_D16,            "D3DFMT_D16"},
11088         {D3DFMT_D32F_LOCKABLE,  "D3DFMT_D32F_LOCKABLE"},
11089         {D3DFMT_D24FS8,         "D3DFMT_D24FS8"},
11090     };
11091     struct
11092     {
11093         float x, y, z;
11094         float s, t, p, q;
11095     }
11096     quad[] =
11097     {
11098         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
11099         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
11100         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
11101         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
11102     };
11103     struct
11104     {
11105         UINT x, y;
11106         D3DCOLOR color;
11107     }
11108     expected_colors[] =
11109     {
11110         {400,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11111         {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11112         {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11113         {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11114         {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11115         { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11116         { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11117         {240,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11118     };
11119
11120     IDirect3DSurface9 *original_ds, *original_rt, *rt;
11121     IDirect3DPixelShader9 *ps;
11122     IDirect3D9 *d3d9;
11123     D3DCAPS9 caps;
11124     HRESULT hr;
11125     UINT i;
11126
11127     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11128     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11129     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11130     {
11131         skip("No pixel shader 2.0 support, skipping shadow test.\n");
11132         return;
11133     }
11134
11135     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11136     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11137     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11138     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11139     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11140     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11141
11142     hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
11143             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11144     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11145     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11146     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11147
11148     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11149     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11150     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11151     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11152     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11153     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11154     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11155     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11156     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11157     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11158
11159     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11160     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11161     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11162     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11163     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11164     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11165     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11166     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11167     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11168     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11169
11170     for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
11171     {
11172         D3DFORMAT format = formats[i].format;
11173         IDirect3DTexture9 *texture;
11174         IDirect3DSurface9 *ds;
11175         unsigned int j;
11176
11177         hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11178                 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
11179         if (FAILED(hr)) continue;
11180
11181         hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
11182                 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
11183         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11184
11185         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11186         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11187
11188         hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11189         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11190
11191         hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11192         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11193
11194         IDirect3DDevice9_SetPixelShader(device, NULL);
11195         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11196
11197         /* Setup the depth/stencil surface. */
11198         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11199         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11200
11201         hr = IDirect3DDevice9_BeginScene(device);
11202         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11203         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11204         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11205         hr = IDirect3DDevice9_EndScene(device);
11206         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11207
11208         hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11209         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11210         IDirect3DSurface9_Release(ds);
11211
11212         hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11213         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11214
11215         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11216         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11217
11218         hr = IDirect3DDevice9_SetPixelShader(device, ps);
11219         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11220
11221         /* Do the actual shadow mapping. */
11222         hr = IDirect3DDevice9_BeginScene(device);
11223         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11224         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11225         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11226         hr = IDirect3DDevice9_EndScene(device);
11227         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11228
11229         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11230         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11231         IDirect3DTexture9_Release(texture);
11232
11233         for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
11234         {
11235             D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
11236             ok(color_match(color, expected_colors[j].color, 0),
11237                     "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
11238                     expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
11239                     formats[i].name, color);
11240         }
11241
11242         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11243         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11244     }
11245
11246     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11247     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11248     IDirect3DPixelShader9_Release(ps);
11249
11250     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11251     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11252     IDirect3DSurface9_Release(original_ds);
11253
11254     IDirect3DSurface9_Release(original_rt);
11255     IDirect3DSurface9_Release(rt);
11256
11257     IDirect3D9_Release(d3d9);
11258 }
11259
11260 START_TEST(visual)
11261 {
11262     IDirect3DDevice9 *device_ptr;
11263     D3DCAPS9 caps;
11264     HRESULT hr;
11265     DWORD color;
11266
11267     d3d9_handle = LoadLibraryA("d3d9.dll");
11268     if (!d3d9_handle)
11269     {
11270         skip("Could not load d3d9.dll\n");
11271         return;
11272     }
11273
11274     device_ptr = init_d3d9();
11275     if (!device_ptr)
11276     {
11277         skip("Creating the device failed\n");
11278         return;
11279     }
11280
11281     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
11282
11283     /* Check for the reliability of the returned data */
11284     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
11285     if(FAILED(hr))
11286     {
11287         skip("Clear failed, can't assure correctness of the test results, skipping\n");
11288         goto cleanup;
11289     }
11290
11291     color = getPixelColor(device_ptr, 1, 1);
11292     if(color !=0x00ff0000)
11293     {
11294         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
11295         goto cleanup;
11296     }
11297     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
11298
11299     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
11300     if(FAILED(hr))
11301     {
11302         skip("Clear failed, can't assure correctness of the test results, skipping\n");
11303         goto cleanup;
11304     }
11305
11306     color = getPixelColor(device_ptr, 639, 479);
11307     if(color != 0x0000ddee)
11308     {
11309         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
11310         goto cleanup;
11311     }
11312     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
11313
11314     /* Now execute the real tests */
11315     depth_clamp_test(device_ptr);
11316     stretchrect_test(device_ptr);
11317     lighting_test(device_ptr);
11318     clear_test(device_ptr);
11319     color_fill_test(device_ptr);
11320     fog_test(device_ptr);
11321     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
11322     {
11323         test_cube_wrap(device_ptr);
11324     } else {
11325         skip("No cube texture support\n");
11326     }
11327     z_range_test(device_ptr);
11328     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
11329     {
11330         maxmip_test(device_ptr);
11331     }
11332     else
11333     {
11334         skip("No mipmap support\n");
11335     }
11336     offscreen_test(device_ptr);
11337     alpha_test(device_ptr);
11338     shademode_test(device_ptr);
11339     srgbtexture_test(device_ptr);
11340     release_buffer_test(device_ptr);
11341     float_texture_test(device_ptr);
11342     g16r16_texture_test(device_ptr);
11343     pixelshader_blending_test(device_ptr);
11344     texture_transform_flags_test(device_ptr);
11345     autogen_mipmap_test(device_ptr);
11346     fixed_function_decl_test(device_ptr);
11347     conditional_np2_repeat_test(device_ptr);
11348     fixed_function_bumpmap_test(device_ptr);
11349     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
11350         stencil_cull_test(device_ptr);
11351     } else {
11352         skip("No two sided stencil support\n");
11353     }
11354     pointsize_test(device_ptr);
11355     tssargtemp_test(device_ptr);
11356     np2_stretch_rect_test(device_ptr);
11357     yuv_color_test(device_ptr);
11358     zwriteenable_test(device_ptr);
11359     alphatest_test(device_ptr);
11360     viewport_test(device_ptr);
11361
11362     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
11363     {
11364         test_constant_clamp_vs(device_ptr);
11365         test_compare_instructions(device_ptr);
11366     }
11367     else skip("No vs_1_1 support\n");
11368
11369     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
11370     {
11371         test_mova(device_ptr);
11372         loop_index_test(device_ptr);
11373         sincos_test(device_ptr);
11374         sgn_test(device_ptr);
11375         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
11376             test_vshader_input(device_ptr);
11377             test_vshader_float16(device_ptr);
11378             stream_test(device_ptr);
11379         } else {
11380             skip("No vs_3_0 support\n");
11381         }
11382     }
11383     else skip("No vs_2_0 support\n");
11384
11385     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
11386     {
11387         fog_with_shader_test(device_ptr);
11388         fog_srgbwrite_test(device_ptr);
11389     }
11390     else skip("No vs_1_1 and ps_1_1 support\n");
11391
11392     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
11393     {
11394         texbem_test(device_ptr);
11395         texdepth_test(device_ptr);
11396         texkill_test(device_ptr);
11397         x8l8v8u8_test(device_ptr);
11398         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
11399             constant_clamp_ps_test(device_ptr);
11400             cnd_test(device_ptr);
11401             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
11402                 dp2add_ps_test(device_ptr);
11403                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
11404                     nested_loop_test(device_ptr);
11405                     fixed_function_varying_test(device_ptr);
11406                     vFace_register_test(device_ptr);
11407                     vpos_register_test(device_ptr);
11408                     multiple_rendertargets_test(device_ptr);
11409                     if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
11410                         vshader_version_varying_test(device_ptr);
11411                         pshader_version_varying_test(device_ptr);
11412                     } else {
11413                         skip("No vs_3_0 support\n");
11414                     }
11415                 } else {
11416                     skip("No ps_3_0 support\n");
11417                 }
11418             } else {
11419                 skip("No ps_2_0 support\n");
11420             }
11421         }
11422     }
11423     else skip("No ps_1_1 support\n");
11424
11425     texop_test(device_ptr);
11426     texop_range_test(device_ptr);
11427     alphareplicate_test(device_ptr);
11428     dp3_alpha_test(device_ptr);
11429     depth_buffer_test(device_ptr);
11430     shadow_test(device_ptr);
11431
11432 cleanup:
11433     if(device_ptr) {
11434         D3DPRESENT_PARAMETERS present_parameters;
11435         IDirect3DSwapChain9 *swapchain;
11436         ULONG ref;
11437
11438         IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
11439         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
11440         IDirect3DSwapChain9_Release(swapchain);
11441         ref = IDirect3DDevice9_Release(device_ptr);
11442         ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
11443         DestroyWindow(present_parameters.hDeviceWindow);
11444     }
11445 }