d3d9: Add a LIT 0.0^0.0 test.
[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_CreateOffscreenPlainSurface(device, 640, 480,
114             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
115     if (FAILED(hr) || !surf)
116     {
117         trace("Can't create an offscreen plain surface to read the render target data, hr=%08x\n", hr);
118         return 0xdeadbeef;
119     }
120
121     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
122     if(FAILED(hr))
123     {
124         trace("Can't get the render target, hr=%08x\n", hr);
125         ret = 0xdeadbeed;
126         goto out;
127     }
128
129     hr = IDirect3DDevice9_GetRenderTargetData(device, target, surf);
130     if (FAILED(hr))
131     {
132         trace("Can't read the render target data, hr=%08x\n", hr);
133         ret = 0xdeadbeec;
134         goto out;
135     }
136
137     hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
138     if(FAILED(hr))
139     {
140         trace("Can't lock the offscreen surface, hr=%08x\n", hr);
141         ret = 0xdeadbeeb;
142         goto out;
143     }
144
145     /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
146      * really important for these tests
147      */
148     ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
149     hr = IDirect3DSurface9_UnlockRect(surf);
150     if(FAILED(hr))
151     {
152         trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
153     }
154
155 out:
156     if(target) IDirect3DSurface9_Release(target);
157     if(surf) IDirect3DSurface9_Release(surf);
158     return ret;
159 }
160
161 static IDirect3DDevice9 *init_d3d9(void)
162 {
163     IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
164     IDirect3D9 *d3d9_ptr = 0;
165     IDirect3DDevice9 *device_ptr = 0;
166     D3DPRESENT_PARAMETERS present_parameters;
167     HRESULT hr;
168     D3DADAPTER_IDENTIFIER9 identifier;
169
170     d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
171     ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
172     if (!d3d9_create) return NULL;
173
174     d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
175     if (!d3d9_ptr)
176     {
177         skip("could not create D3D9\n");
178         return NULL;
179     }
180
181     ZeroMemory(&present_parameters, sizeof(present_parameters));
182     present_parameters.Windowed = TRUE;
183     present_parameters.hDeviceWindow = create_window();
184     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
185     present_parameters.BackBufferWidth = 640;
186     present_parameters.BackBufferHeight = 480;
187     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
188     present_parameters.EnableAutoDepthStencil = TRUE;
189     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
190
191     memset(&identifier, 0, sizeof(identifier));
192     hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
193     ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
194     trace("Driver string: \"%s\"\n", identifier.Driver);
195     trace("Description string: \"%s\"\n", identifier.Description);
196     ok(identifier.Description[0] != '\0', "Empty driver description\n");
197     trace("Device name string: \"%s\"\n", identifier.DeviceName);
198     ok(identifier.DeviceName[0]  != '\0', "Empty device name\n");
199     trace("Driver version %d.%d.%d.%d\n",
200           HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
201           HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
202
203     hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
204             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
205     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE || hr == D3DERR_INVALIDCALL,
206             "Failed to create a device, hr %#x.\n", hr);
207
208     return device_ptr;
209 }
210
211 struct vertex
212 {
213     float x, y, z;
214     DWORD diffuse;
215 };
216
217 struct tvertex
218 {
219     float x, y, z, rhw;
220     DWORD diffuse;
221 };
222
223 struct nvertex
224 {
225     float x, y, z;
226     float nx, ny, nz;
227     DWORD diffuse;
228 };
229
230 static void lighting_test(IDirect3DDevice9 *device)
231 {
232     HRESULT hr;
233     DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
234     DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
235     DWORD color;
236     D3DMATERIAL9 material, old_material;
237     DWORD cop, carg;
238     DWORD old_colorwrite;
239
240     float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
241                       0.0f, 1.0f, 0.0f, 0.0f,
242                       0.0f, 0.0f, 1.0f, 0.0f,
243                       0.0f, 0.0f, 0.0f, 1.0f };
244
245     struct vertex unlitquad[] =
246     {
247         {-1.0f, -1.0f,   0.1f,                          0xffff0000},
248         {-1.0f,  0.0f,   0.1f,                          0xffff0000},
249         { 0.0f,  0.0f,   0.1f,                          0xffff0000},
250         { 0.0f, -1.0f,   0.1f,                          0xffff0000},
251     };
252     struct vertex litquad[] =
253     {
254         {-1.0f,  0.0f,   0.1f,                          0xff00ff00},
255         {-1.0f,  1.0f,   0.1f,                          0xff00ff00},
256         { 0.0f,  1.0f,   0.1f,                          0xff00ff00},
257         { 0.0f,  0.0f,   0.1f,                          0xff00ff00},
258     };
259     struct nvertex unlitnquad[] =
260     {
261         { 0.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
262         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
263         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
264         { 1.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
265     };
266     struct nvertex litnquad[] =
267     {
268         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
269         { 0.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
270         { 1.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
271         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
272     };
273     WORD Indices[] = {0, 1, 2, 2, 3, 0};
274
275     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
276     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
277
278     /* Setup some states that may cause issues */
279     hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
280     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
281     hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
282     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
283     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
284     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
285     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
286     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
287     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
288     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
289     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
290     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
291     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
292     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
293     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
294     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
295     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
296     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
297     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
298     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
299     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
300     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
301     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &old_colorwrite);
302     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
303     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
304     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
305
306     hr = IDirect3DDevice9_SetFVF(device, 0);
307     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
308
309     hr = IDirect3DDevice9_SetFVF(device, fvf);
310     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
311
312     hr = IDirect3DDevice9_BeginScene(device);
313     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
314     if(hr == D3D_OK)
315     {
316         /* No lights are defined... That means, lit vertices should be entirely black */
317         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
318         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
319         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
320                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
321         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
322
323         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
324         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
325         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
326                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
327         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
328
329         hr = IDirect3DDevice9_SetFVF(device, nfvf);
330         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
331
332         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
333         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
334         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
335                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
336         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
337
338         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
339         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
340         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
341                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
342         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
343
344         IDirect3DDevice9_EndScene(device);
345         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
346     }
347
348     color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
349     ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
350     color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
351     ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
352     color = getPixelColor(device, 480, 360); /* Lower left quad - unlit with normals */
353     ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
354     color = getPixelColor(device, 480, 120); /* Upper left quad - lit with normals */
355     ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
356
357     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
358
359     hr = IDirect3DDevice9_GetMaterial(device, &old_material);
360     ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
361     memset(&material, 0, sizeof(material));
362     material.Diffuse.r = 0.0;
363     material.Diffuse.g = 0.0;
364     material.Diffuse.b = 0.0;
365     material.Diffuse.a = 1.0;
366     material.Ambient.r = 0.0;
367     material.Ambient.g = 0.0;
368     material.Ambient.b = 0.0;
369     material.Ambient.a = 0.0;
370     material.Specular.r = 0.0;
371     material.Specular.g = 0.0;
372     material.Specular.b = 0.0;
373     material.Specular.a = 0.0;
374     material.Emissive.r = 0.0;
375     material.Emissive.g = 0.0;
376     material.Emissive.b = 0.0;
377     material.Emissive.a = 0.0;
378     material.Power = 0.0;
379     IDirect3DDevice9_SetMaterial(device, &material);
380     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
381
382     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
383     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
384     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
385     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
386
387     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
388     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
389     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
390     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
391     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
392     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
393     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
394     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
395
396     hr = IDirect3DDevice9_BeginScene(device);
397     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
398     if(SUCCEEDED(hr)) {
399         struct vertex lighting_test[] = {
400             {-1.0,   -1.0,   0.1,    0x8000ff00},
401             { 1.0,   -1.0,   0.1,    0x80000000},
402             {-1.0,    1.0,   0.1,    0x8000ff00},
403             { 1.0,    1.0,   0.1,    0x80000000}
404         };
405         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
406         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
407         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
408         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
409
410         hr = IDirect3DDevice9_EndScene(device);
411         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
412     }
413
414     color = getPixelColor(device, 320, 240);
415     ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
416     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
417
418     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
419     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
420     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
421     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
422     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
423     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
424     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
425     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
426     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, old_colorwrite);
427     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
428     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
429     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
430     hr = IDirect3DDevice9_SetMaterial(device, &old_material);
431     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
432 }
433
434 static void clear_test(IDirect3DDevice9 *device)
435 {
436     /* Tests the correctness of clearing parameters */
437     HRESULT hr;
438     D3DRECT rect[2];
439     D3DRECT rect_negneg;
440     DWORD color;
441     D3DVIEWPORT9 old_vp, vp;
442     RECT scissor;
443     DWORD oldColorWrite;
444     BOOL invalid_clear_failed = FALSE;
445
446     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
447     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
448
449     /* Positive x, negative y */
450     rect[0].x1 = 0;
451     rect[0].y1 = 480;
452     rect[0].x2 = 320;
453     rect[0].y2 = 240;
454
455     /* Positive x, positive y */
456     rect[1].x1 = 0;
457     rect[1].y1 = 0;
458     rect[1].x2 = 320;
459     rect[1].y2 = 240;
460     /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
461      * returns D3D_OK, but ignores the rectangle silently
462      */
463     hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
464     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
465     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
466
467     /* negative x, negative y */
468     rect_negneg.x1 = 640;
469     rect_negneg.y1 = 240;
470     rect_negneg.x2 = 320;
471     rect_negneg.y2 = 0;
472     hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
473     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
474     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
475
476     color = getPixelColor(device, 160, 360); /* lower left quad */
477     ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
478     color = getPixelColor(device, 160, 120); /* upper left quad */
479     if(invalid_clear_failed) {
480         /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
481         ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
482     } else {
483         /* If the negative rectangle was dropped silently, the correct ones are cleared */
484         ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
485     }
486     color = getPixelColor(device, 480, 360); /* lower right quad  */
487     ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
488     color = getPixelColor(device, 480, 120); /* upper right quad */
489     ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
490
491     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
492
493     /* Hack to work around a nvidia windows driver bug. The clear below is supposed to
494      * clear the red quad in the top left part of the render target. For some reason it
495      * doesn't work if the clear color is 0xffffffff on some versions of the Nvidia Windows
496      * driver(tested on 8.17.12.5896, Win7). A clear with a different color works around
497      * this bug and fixes the clear with the white color. Even 0xfeffffff works, but let's
498      * pick some obvious value
499      */
500     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbabe, 0.0, 0);
501     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
502
503     /* Test how the viewport affects clears */
504     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
505     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
506     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
507     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
508
509     vp.X = 160;
510     vp.Y = 120;
511     vp.Width = 160;
512     vp.Height = 120;
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     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
518     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
519
520     vp.X = 320;
521     vp.Y = 240;
522     vp.Width = 320;
523     vp.Height = 240;
524     vp.MinZ = 0.0;
525     vp.MaxZ = 1.0;
526     hr = IDirect3DDevice9_SetViewport(device, &vp);
527     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
528     rect[0].x1 = 160;
529     rect[0].y1 = 120;
530     rect[0].x2 = 480;
531     rect[0].y2 = 360;
532     hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
533     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
534
535     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
536     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
537
538     color = getPixelColor(device, 158, 118);
539     ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
540     color = getPixelColor(device, 162, 118);
541     ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
542     color = getPixelColor(device, 158, 122);
543     ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
544     color = getPixelColor(device, 162, 122);
545     ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
546
547     color = getPixelColor(device, 318, 238);
548     ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
549     color = getPixelColor(device, 322, 238);
550     ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
551     color = getPixelColor(device, 318, 242);
552     ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
553     color = getPixelColor(device, 322, 242);
554     ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
555
556     color = getPixelColor(device, 478, 358);
557     ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
558     color = getPixelColor(device, 482, 358);
559     ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
560     color = getPixelColor(device, 478, 362);
561     ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
562     color = getPixelColor(device, 482, 362);
563     ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
564
565     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
566
567     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
568     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
569
570     scissor.left = 160;
571     scissor.right = 480;
572     scissor.top = 120;
573     scissor.bottom = 360;
574     hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
575     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
576     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
577     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
578
579     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
580     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
581     hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
582     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
583
584     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
585     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
586
587     color = getPixelColor(device, 158, 118);
588     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
589     color = getPixelColor(device, 162, 118);
590     ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
591     color = getPixelColor(device, 158, 122);
592     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
593     color = getPixelColor(device, 162, 122);
594     ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
595
596     color = getPixelColor(device, 158, 358);
597     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
598     color = getPixelColor(device, 162, 358);
599     ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
600     color = getPixelColor(device, 158, 358);
601     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
602     color = getPixelColor(device, 162, 362);
603     ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
604
605     color = getPixelColor(device, 478, 118);
606     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
607     color = getPixelColor(device, 478, 122);
608     ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
609     color = getPixelColor(device, 482, 122);
610     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
611     color = getPixelColor(device, 482, 358);
612     ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
613
614     color = getPixelColor(device, 478, 358);
615     ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
616     color = getPixelColor(device, 478, 362);
617     ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
618     color = getPixelColor(device, 482, 358);
619     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
620     color = getPixelColor(device, 482, 362);
621     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
622
623     color = getPixelColor(device, 318, 238);
624     ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
625     color = getPixelColor(device, 318, 242);
626     ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
627     color = getPixelColor(device, 322, 238);
628     ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
629     color = getPixelColor(device, 322, 242);
630     ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
631
632     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
633
634     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
635     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
636     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
637     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
638
639     /* Same nvidia windows driver trouble with white clears as earlier in the same test */
640     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbeef, 0.0, 0);
641     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
642
643     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
644     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
645
646     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
647     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
648
649     /* Colorwriteenable does not affect the clear */
650     color = getPixelColor(device, 320, 240);
651     ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
652
653     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
654 }
655
656 static void color_fill_test(IDirect3DDevice9 *device)
657 {
658     HRESULT hr;
659     IDirect3DSurface9 *backbuffer = NULL;
660     IDirect3DSurface9 *rt_surface = NULL;
661     IDirect3DSurface9 *offscreen_surface = NULL;
662     DWORD fill_color, color;
663
664     /* Test ColorFill on a the backbuffer (should pass) */
665     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
666     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
667     if(backbuffer)
668     {
669         fill_color = 0x112233;
670         hr = IDirect3DDevice9_ColorFill(device, backbuffer, NULL, fill_color);
671         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
672
673         color = getPixelColor(device, 0, 0);
674         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
675
676         IDirect3DSurface9_Release(backbuffer);
677     }
678
679     /* Test ColorFill on a render target surface (should pass) */
680     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt_surface, NULL );
681     ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
682     if(rt_surface)
683     {
684         fill_color = 0x445566;
685         hr = IDirect3DDevice9_ColorFill(device, rt_surface, NULL, fill_color);
686         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
687
688         color = getPixelColorFromSurface(rt_surface, 0, 0);
689         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
690
691         IDirect3DSurface9_Release(rt_surface);
692     }
693
694     /* Test ColorFill on a offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
695     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
696             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen_surface, NULL);
697     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
698     if(offscreen_surface)
699     {
700         fill_color = 0x778899;
701         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, fill_color);
702         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
703
704         color = getPixelColorFromSurface(offscreen_surface, 0, 0);
705         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
706
707         IDirect3DSurface9_Release(offscreen_surface);
708     }
709
710     /* Try ColorFill on a offscreen surface in sysmem (should fail) */
711     offscreen_surface = NULL;
712     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
713             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &offscreen_surface, NULL);
714     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
715     if(offscreen_surface)
716     {
717         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, 0);
718         ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
719
720         IDirect3DSurface9_Release(offscreen_surface);
721     }
722 }
723
724 typedef struct {
725     float in[4];
726     DWORD out;
727 } test_data_t;
728
729 /*
730  *  c7      mova    ARGB            mov     ARGB
731  * -2.4     -2      0x00ffff00      -3      0x00ff0000
732  * -1.6     -2      0x00ffff00      -2      0x00ffff00
733  * -0.4      0      0x0000ffff      -1      0x0000ff00
734  *  0.4      0      0x0000ffff       0      0x0000ffff
735  *  1.6      2      0x00ff00ff       1      0x000000ff
736  *  2.4      2      0x00ff00ff       2      0x00ff00ff
737  */
738 static void test_mova(IDirect3DDevice9 *device)
739 {
740     static const DWORD mova_test[] = {
741         0xfffe0200,                                                             /* vs_2_0                       */
742         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
743         0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
744         0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
745         0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
746         0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
747         0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
748         0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
749         0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
750         0x0200002e, 0xb0010000, 0xa0000007,                                     /* mova a0.x, c7.x              */
751         0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000,                         /* mov oD0, c[a0.x + 3]         */
752         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
753         0x0000ffff                                                              /* END                          */
754     };
755     static const DWORD mov_test[] = {
756         0xfffe0101,                                                             /* vs_1_1                       */
757         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
758         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
759         0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
760         0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
761         0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
762         0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
763         0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
764         0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
765         0x00000001, 0xb0010000, 0xa0000007,                                     /* mov a0.x, c7.x               */
766         0x00000001, 0xd00f0000, 0xa0e42003,                                     /* mov oD0, c[a0.x + 3]         */
767         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
768         0x0000ffff                                                              /* END                          */
769     };
770
771     static const test_data_t test_data[2][6] = {
772         {
773             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
774             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
775             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
776             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
777             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
778             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
779         },
780         {
781             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
782             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
783             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
784             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
785             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
786             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
787         }
788     };
789
790     static const float quad[][3] = {
791         {-1.0f, -1.0f, 0.0f},
792         {-1.0f,  1.0f, 0.0f},
793         { 1.0f, -1.0f, 0.0f},
794         { 1.0f,  1.0f, 0.0f},
795     };
796
797     static const D3DVERTEXELEMENT9 decl_elements[] = {
798         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
799         D3DDECL_END()
800     };
801
802     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
803     IDirect3DVertexShader9 *mova_shader = NULL;
804     IDirect3DVertexShader9 *mov_shader = NULL;
805     HRESULT hr;
806     UINT i, j;
807
808     hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
809     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
810     hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
811     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
812     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
813     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
814     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
815     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
816
817     hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
818     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
819     for(j = 0; j < 2; ++j)
820     {
821         for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
822         {
823             DWORD color;
824
825             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
826             ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
827
828             hr = IDirect3DDevice9_BeginScene(device);
829             ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
830
831             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
832             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
833
834             hr = IDirect3DDevice9_EndScene(device);
835             ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
836
837             color = getPixelColor(device, 320, 240);
838             ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
839                test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
840
841             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
842             ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
843
844             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
845             ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
846         }
847         hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
848         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
849     }
850
851     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
852     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
853
854     IDirect3DVertexDeclaration9_Release(vertex_declaration);
855     IDirect3DVertexShader9_Release(mova_shader);
856     IDirect3DVertexShader9_Release(mov_shader);
857 }
858
859 struct sVertex {
860     float x, y, z;
861     DWORD diffuse;
862     DWORD specular;
863 };
864
865 struct sVertexT {
866     float x, y, z, rhw;
867     DWORD diffuse;
868     DWORD specular;
869 };
870
871 static void fog_test(IDirect3DDevice9 *device)
872 {
873     HRESULT hr;
874     D3DCOLOR color;
875     float start = 0.0f, end = 1.0f;
876     D3DCAPS9 caps;
877     int i;
878
879     /* Gets full z based fog with linear fog, no fog with specular color */
880     struct sVertex untransformed_1[] = {
881         {-1,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
882         {-1,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
883         { 0,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
884         { 0,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
885     };
886     /* Ok, I am too lazy to deal with transform matrices */
887     struct sVertex untransformed_2[] = {
888         {-1,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
889         {-1,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
890         { 0,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
891         { 0,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
892     };
893     /* Untransformed ones. Give them a different diffuse color to make the test look
894      * nicer. It also makes making sure that they are drawn correctly easier.
895      */
896     struct sVertexT transformed_1[] = {
897         {320,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
898         {640,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
899         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
900         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
901     };
902     struct sVertexT transformed_2[] = {
903         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
904         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
905         {640,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
906         {320,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
907     };
908     struct vertex rev_fog_quads[] = {
909        {-1.0,   -1.0,   0.1,    0x000000ff},
910        {-1.0,    0.0,   0.1,    0x000000ff},
911        { 0.0,    0.0,   0.1,    0x000000ff},
912        { 0.0,   -1.0,   0.1,    0x000000ff},
913
914        { 0.0,   -1.0,   0.9,    0x000000ff},
915        { 0.0,    0.0,   0.9,    0x000000ff},
916        { 1.0,    0.0,   0.9,    0x000000ff},
917        { 1.0,   -1.0,   0.9,    0x000000ff},
918
919        { 0.0,    0.0,   0.4,    0x000000ff},
920        { 0.0,    1.0,   0.4,    0x000000ff},
921        { 1.0,    1.0,   0.4,    0x000000ff},
922        { 1.0,    0.0,   0.4,    0x000000ff},
923
924        {-1.0,    0.0,   0.7,    0x000000ff},
925        {-1.0,    1.0,   0.7,    0x000000ff},
926        { 0.0,    1.0,   0.7,    0x000000ff},
927        { 0.0,    0.0,   0.7,    0x000000ff},
928     };
929     WORD Indices[] = {0, 1, 2, 2, 3, 0};
930
931     const float ident_mat[16] =
932     {
933         1.0f, 0.0f, 0.0f, 0.0f,
934         0.0f, 1.0f, 0.0f, 0.0f,
935         0.0f, 0.0f, 1.0f, 0.0f,
936         0.0f, 0.0f, 0.0f, 1.0f
937     };
938     const float world_mat1[16] =
939     {
940         1.0f, 0.0f,  0.0f, 0.0f,
941         0.0f, 1.0f,  0.0f, 0.0f,
942         0.0f, 0.0f,  1.0f, 0.0f,
943         0.0f, 0.0f, -0.5f, 1.0f
944     };
945     const float world_mat2[16] =
946     {
947         1.0f, 0.0f, 0.0f, 0.0f,
948         0.0f, 1.0f, 0.0f, 0.0f,
949         0.0f, 0.0f, 1.0f, 0.0f,
950         0.0f, 0.0f, 1.0f, 1.0f
951     };
952     const float proj_mat[16] =
953     {
954         1.0f, 0.0f,  0.0f, 0.0f,
955         0.0f, 1.0f,  0.0f, 0.0f,
956         0.0f, 0.0f,  1.0f, 0.0f,
957         0.0f, 0.0f, -1.0f, 1.0f
958     };
959
960     const struct sVertex far_quad1[] =
961     {
962         {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
963         {-1.0f,  0.0f, 0.5f, 0xffff0000, 0xff000000},
964         { 0.0f,  0.0f, 0.5f, 0xffff0000, 0xff000000},
965         { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
966     };
967     const struct sVertex far_quad2[] =
968     {
969         {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
970         {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
971         { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
972         { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
973     };
974
975     memset(&caps, 0, sizeof(caps));
976     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
977     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
978     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
979     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
980
981     /* Setup initial states: No lighting, fog on, fog color */
982     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
983     ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
984     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
985     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
986     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
987     ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
988
989     /* First test: Both table fog and vertex fog off */
990     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
991     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
992     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
993     ok(hr == D3D_OK, "Turning off vertex fog returned %08x\n", hr);
994
995     /* Start = 0, end = 1. Should be default, but set them */
996     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
997     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
998     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
999     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1000
1001     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1002     {
1003         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1004         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1005         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
1006         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1007                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1,
1008                                                      sizeof(untransformed_1[0]));
1009         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1010
1011         /* That makes it use the Z value */
1012         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1013         ok(hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %#08x\n", hr);
1014         /* Untransformed, vertex fog != none (or table fog != none):
1015          * Use the Z value as input into the equation
1016          */
1017         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1018                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2,
1019                                                      sizeof(untransformed_2[0]));
1020         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1021
1022         /* transformed verts */
1023         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1024         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1025         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1026         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1027                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1028                                                      sizeof(transformed_1[0]));
1029         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1030
1031         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1032         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1033         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
1034          * equation
1035          */
1036         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1037                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
1038                                                      sizeof(transformed_2[0]));
1039         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1040
1041         hr = IDirect3DDevice9_EndScene(device);
1042         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1043     }
1044     else
1045     {
1046         ok(FALSE, "BeginScene failed\n");
1047     }
1048
1049     color = getPixelColor(device, 160, 360);
1050     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1051     color = getPixelColor(device, 160, 120);
1052     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
1053     color = getPixelColor(device, 480, 120);
1054     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1055     if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1056     {
1057         color = getPixelColor(device, 480, 360);
1058         ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
1059     }
1060     else
1061     {
1062         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1063          * The settings above result in no fogging with vertex fog
1064          */
1065         color = getPixelColor(device, 480, 120);
1066         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1067         trace("Info: Table fog not supported by this device\n");
1068     }
1069     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1070
1071     /* Now test the special case fogstart == fogend */
1072     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1073     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1074
1075     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1076     {
1077         start = 512;
1078         end = 512;
1079         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1080         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1081         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1082         ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1083
1084         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1085         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1086         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1087         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %08x\n", hr);
1088         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1089         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1090
1091         /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
1092          * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
1093          * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
1094          * The third transformed quad remains unfogged because the fogcoords are read from the specular
1095          * color and has fixed fogstart and fogend.
1096          */
1097         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1098                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1,
1099                 sizeof(untransformed_1[0]));
1100         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1101         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1102                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2,
1103                 sizeof(untransformed_2[0]));
1104         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1105
1106         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1107         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1108         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1109         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1110                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1111                 sizeof(transformed_1[0]));
1112         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1113
1114         hr = IDirect3DDevice9_EndScene(device);
1115         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1116     }
1117     else
1118     {
1119         ok(FALSE, "BeginScene failed\n");
1120     }
1121     color = getPixelColor(device, 160, 360);
1122     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1123     color = getPixelColor(device, 160, 120);
1124     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1125     color = getPixelColor(device, 480, 120);
1126     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1127     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1128
1129     /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1130      * but without shaders it seems to work everywhere
1131      */
1132     end = 0.2;
1133     start = 0.8;
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_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1139     ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1140
1141     /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1142      * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1143      * so skip this for now
1144      */
1145     for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1146         const char *mode = (i ? "table" : "vertex");
1147         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1148         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1149         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1150         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1151         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1152         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1153         hr = IDirect3DDevice9_BeginScene(device);
1154         ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1155         if(SUCCEEDED(hr)) {
1156             WORD Indices2[] = { 0,  1,  2,  2,  3, 0,
1157                                 4,  5,  6,  6,  7, 4,
1158                                 8,  9, 10, 10, 11, 8,
1159                             12, 13, 14, 14, 15, 12};
1160
1161             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1162                     16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1163                     sizeof(rev_fog_quads[0]));
1164             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1165
1166             hr = IDirect3DDevice9_EndScene(device);
1167             ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1168         }
1169         color = getPixelColor(device, 160, 360);
1170         ok(color_match(color, 0x0000ff00, 1),
1171                 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1172
1173         color = getPixelColor(device, 160, 120);
1174         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1175                 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1176
1177         color = getPixelColor(device, 480, 120);
1178         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1179                 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1180
1181         color = getPixelColor(device, 480, 360);
1182         ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1183
1184         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1185
1186         if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1187             skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1188             break;
1189         }
1190     }
1191
1192     if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1193     {
1194         /* A simple fog + non-identity world matrix test */
1195         hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)world_mat1);
1196         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %#08x\n", hr);
1197
1198         start = 0.0;
1199         end = 1.0;
1200         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
1201         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1202         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
1203         ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1204         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1205         ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
1206         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1207         ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
1208
1209         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1210         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %#08x\n", hr);
1211
1212         if (IDirect3DDevice9_BeginScene(device) == D3D_OK)
1213         {
1214             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1215             ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
1216
1217             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1218                     2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
1219             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1220
1221             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1222                     2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
1223             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1224
1225             hr = IDirect3DDevice9_EndScene(device);
1226             ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
1227         }
1228         else
1229         {
1230             ok(FALSE, "BeginScene failed\n");
1231         }
1232
1233         color = getPixelColor(device, 160, 360);
1234         ok(color_match(color, 0x00ff0000, 4), "Unfogged quad has color %08x\n", color);
1235         color = getPixelColor(device, 160, 120);
1236         ok(color == 0x0000ff00, "Fogged out quad has color %08x\n", color);
1237
1238         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1239
1240         /* Test fog behavior with an orthogonal (but non-identity) projection matrix */
1241         hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)world_mat2);
1242         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1243         hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (const D3DMATRIX *)proj_mat);
1244         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1245
1246         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1247         ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
1248
1249         if (IDirect3DDevice9_BeginScene(device) == D3D_OK)
1250         {
1251             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1252             ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
1253
1254             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1255                     2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1256             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1257
1258             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1259                     2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1260             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1261
1262             hr = IDirect3DDevice9_EndScene(device);
1263             ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
1264         }
1265         else
1266         {
1267             ok(FALSE, "BeginScene failed\n");
1268         }
1269
1270         color = getPixelColor(device, 160, 360);
1271         todo_wine ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
1272         color = getPixelColor(device, 160, 120);
1273         ok(color == 0x0000ff00, "Fogged out quad has color %08x\n", color);
1274
1275         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1276
1277         hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)ident_mat);
1278         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1279         hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (const D3DMATRIX *)ident_mat);
1280         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1281     }
1282     else
1283     {
1284         skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
1285     }
1286
1287     /* Turn off the fog master switch to avoid confusing other tests */
1288     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1289     ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1290     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1291     ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %08x\n", hr);
1292     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1293     ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1294 }
1295
1296 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1297  * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1298  * regardless of the actual addressing mode set. The way this test works is
1299  * that we sample in one of the corners of the cubemap with filtering enabled,
1300  * and check the interpolated color. There are essentially two reasonable
1301  * things an implementation can do: Either pick one of the faces and
1302  * interpolate the edge texel with itself (i.e., clamp within the face), or
1303  * interpolate between the edge texels of the three involved faces. It should
1304  * never involve the border color or the other side (texcoord wrapping) of a
1305  * face in the interpolation. */
1306 static void test_cube_wrap(IDirect3DDevice9 *device)
1307 {
1308     static const float quad[][6] = {
1309         {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1310         {-1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1311         { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1312         { 1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1313     };
1314
1315     static const D3DVERTEXELEMENT9 decl_elements[] = {
1316         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1317         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1318         D3DDECL_END()
1319     };
1320
1321     static const struct {
1322         D3DTEXTUREADDRESS mode;
1323         const char *name;
1324     } address_modes[] = {
1325         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1326         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1327         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1328         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1329         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1330     };
1331
1332     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1333     IDirect3DCubeTexture9 *texture = NULL;
1334     IDirect3DSurface9 *surface = NULL;
1335     IDirect3DSurface9 *face_surface;
1336     D3DLOCKED_RECT locked_rect;
1337     HRESULT hr;
1338     UINT x;
1339     INT y, face;
1340
1341     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1342     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1343     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1344     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1345
1346     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1347             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1348     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1349
1350     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1351             D3DPOOL_DEFAULT, &texture, NULL);
1352     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1353
1354     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1355     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1356
1357     for (y = 0; y < 128; ++y)
1358     {
1359         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1360         for (x = 0; x < 64; ++x)
1361         {
1362             *ptr++ = 0xff0000ff;
1363         }
1364         for (x = 64; x < 128; ++x)
1365         {
1366             *ptr++ = 0xffff0000;
1367         }
1368     }
1369
1370     hr = IDirect3DSurface9_UnlockRect(surface);
1371     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1372
1373     hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
1374     ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1375
1376     hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1377     ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1378
1379     IDirect3DSurface9_Release(face_surface);
1380
1381     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1382     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1383
1384     for (y = 0; y < 128; ++y)
1385     {
1386         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1387         for (x = 0; x < 64; ++x)
1388         {
1389             *ptr++ = 0xffff0000;
1390         }
1391         for (x = 64; x < 128; ++x)
1392         {
1393             *ptr++ = 0xff0000ff;
1394         }
1395     }
1396
1397     hr = IDirect3DSurface9_UnlockRect(surface);
1398     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1399
1400     /* Create cube faces */
1401     for (face = 1; face < 6; ++face)
1402     {
1403         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1404         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1405
1406         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1407         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1408
1409         IDirect3DSurface9_Release(face_surface);
1410     }
1411
1412     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1413     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1414
1415     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1416     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1417     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1418     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1419     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1420     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1421
1422     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1423     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1424
1425     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1426     {
1427         DWORD color;
1428
1429         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1430         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1431         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1432         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1433
1434         hr = IDirect3DDevice9_BeginScene(device);
1435         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1436
1437         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1438         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1439
1440         hr = IDirect3DDevice9_EndScene(device);
1441         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1442
1443         color = getPixelColor(device, 320, 240);
1444         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1445                 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
1446                 color, address_modes[x].name);
1447
1448         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1449         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1450
1451         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1452         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1453     }
1454
1455     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1456     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1457
1458     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1459     IDirect3DCubeTexture9_Release(texture);
1460     IDirect3DSurface9_Release(surface);
1461 }
1462
1463 static void offscreen_test(IDirect3DDevice9 *device)
1464 {
1465     HRESULT hr;
1466     IDirect3DTexture9 *offscreenTexture = NULL;
1467     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1468     DWORD color;
1469
1470     static const float quad[][5] = {
1471         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1472         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1473         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1474         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1475     };
1476
1477     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1478     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1479
1480     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1481     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1482     if(!offscreenTexture) {
1483         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1484         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1485         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1486         if(!offscreenTexture) {
1487             skip("Cannot create an offscreen render target\n");
1488             goto out;
1489         }
1490     }
1491
1492     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1493     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1494     if(!backbuffer) {
1495         goto out;
1496     }
1497
1498     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1499     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1500     if(!offscreen) {
1501         goto out;
1502     }
1503
1504     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1505     ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1506
1507     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1508     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1509     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1510     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1511     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1512     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1513     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1514     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1515     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1516     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1517
1518     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1519         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1520         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1521         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1522         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1523
1524         /* Draw without textures - Should result in a white quad */
1525         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1526         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1527
1528         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1529         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1530         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1531         ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1532
1533         /* This time with the texture */
1534         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1535         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1536
1537         IDirect3DDevice9_EndScene(device);
1538     }
1539
1540     /* Center quad - should be white */
1541     color = getPixelColor(device, 320, 240);
1542     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1543     /* Some quad in the cleared part of the texture */
1544     color = getPixelColor(device, 170, 240);
1545     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1546     /* Part of the originally cleared back buffer */
1547     color = getPixelColor(device, 10, 10);
1548     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1549     if(0) {
1550         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1551          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1552          * the offscreen rendering mode this test would succeed or fail
1553          */
1554         color = getPixelColor(device, 10, 470);
1555         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1556     }
1557
1558     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1559
1560 out:
1561     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1562     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1563
1564     /* restore things */
1565     if(backbuffer) {
1566         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1567         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1568         IDirect3DSurface9_Release(backbuffer);
1569     }
1570     if(offscreenTexture) {
1571         IDirect3DTexture9_Release(offscreenTexture);
1572     }
1573     if(offscreen) {
1574         IDirect3DSurface9_Release(offscreen);
1575     }
1576 }
1577
1578 /* This test tests fog in combination with shaders.
1579  * What's tested: linear fog (vertex and table) with pixel shader
1580  *                linear table fog with non foggy vertex shader
1581  *                vertex fog with foggy vertex shader, non-linear
1582  *                fog with shader, non-linear fog with foggy shader,
1583  *                linear table fog with foggy shader
1584  */
1585 static void fog_with_shader_test(IDirect3DDevice9 *device)
1586 {
1587     HRESULT hr;
1588     DWORD color;
1589     union {
1590         float f;
1591         DWORD i;
1592     } start, end;
1593     unsigned int i, j;
1594
1595     /* basic vertex shader without fog computation ("non foggy") */
1596     static const DWORD vertex_shader_code1[] = {
1597         0xfffe0101,                                                             /* vs_1_1                       */
1598         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1599         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1600         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1601         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1602         0x0000ffff
1603     };
1604     /* basic vertex shader with reversed fog computation ("foggy") */
1605     static const DWORD vertex_shader_code2[] = {
1606         0xfffe0101,                                                             /* vs_1_1                        */
1607         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1608         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1609         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1610         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1611         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1612         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1613         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1614         0x0000ffff
1615     };
1616     /* basic pixel shader */
1617     static const DWORD pixel_shader_code[] = {
1618         0xffff0101,                                                             /* ps_1_1     */
1619         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, vo */
1620         0x0000ffff
1621     };
1622
1623     static struct vertex quad[] = {
1624         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1625         {-1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1626         { 1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1627         { 1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1628     };
1629
1630     static const D3DVERTEXELEMENT9 decl_elements[] = {
1631         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1632         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1633         D3DDECL_END()
1634     };
1635
1636     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1637     IDirect3DVertexShader9      *vertex_shader[3]   = {NULL, NULL, NULL};
1638     IDirect3DPixelShader9       *pixel_shader[2]    = {NULL, NULL};
1639
1640     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1641     static const struct test_data_t {
1642         int vshader;
1643         int pshader;
1644         D3DFOGMODE vfog;
1645         D3DFOGMODE tfog;
1646         unsigned int color[11];
1647     } test_data[] = {
1648         /* only pixel shader: */
1649         {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1650         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1651         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1652         {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1653         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1654         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1655         {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1656         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1657         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1658         {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1659         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1660         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1661         {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1662         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1663         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1664
1665         /* vertex shader */
1666         {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1667         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1668          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1669         {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1670         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1671         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1672         {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1673         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1674         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1675
1676         {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1677         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1678         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1679         {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1680         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1681         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1682
1683         /* vertex shader and pixel shader */
1684         /* The next 4 tests would read the fog coord output, but it isn't available.
1685          * The result is a fully fogged quad, no matter what the Z coord is. This is on
1686          * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1687          * These tests should be disabled if some other hardware behaves differently
1688          */
1689         {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1690         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1691         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1692         {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1693         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1694         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1695         {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1696         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1697         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1698         {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1699         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1700         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1701
1702         /* These use the Z coordinate with linear table fog */
1703         {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1704         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1705         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1706         {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1707         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1708         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1709         {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1710         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1711         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1712         {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1713         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1714         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1715
1716         /* Non-linear table fog without fog coord */
1717         {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1718         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1719         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1720         {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1721         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1722         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1723
1724 #if 0  /* FIXME: these fail on GeForce 8500 */
1725         /* foggy vertex shader */
1726         {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1727         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1728          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1729         {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1730         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1731          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1732         {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1733         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1734          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1735         {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1736         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1737          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1738 #endif
1739
1740         /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1741          * all using the fixed fog-coord linear fog
1742          */
1743         {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1744         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1745          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1746         {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1747         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1748          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1749         {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1750         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1751          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1752         {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1753         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1754          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1755
1756         /* These use table fog. Here the shader-provided fog coordinate is
1757          * ignored and the z coordinate used instead
1758          */
1759         {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1760         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1761         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1762         {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1763         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1764         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1765         {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1766         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1767         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1768     };
1769
1770     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1771     start.f=0.1f;
1772     end.f=0.9f;
1773
1774     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1775     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1776     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1777     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1778     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1779     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1780     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1781     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1782
1783     /* Setup initial states: No lighting, fog on, fog color */
1784     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1785     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1786     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1787     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1788     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1789     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1790     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1791     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1792
1793     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1794     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1795     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1796     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1797
1798     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1799     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1800     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1801     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1802     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1803
1804     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1805     {
1806         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1807         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1808         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1809         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1810         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1811         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1812         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1813         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1814
1815         for(j=0; j < 11; j++)
1816         {
1817             /* Don't use the whole zrange to prevent rounding errors */
1818             quad[0].z = 0.001f + (float)j / 10.02f;
1819             quad[1].z = 0.001f + (float)j / 10.02f;
1820             quad[2].z = 0.001f + (float)j / 10.02f;
1821             quad[3].z = 0.001f + (float)j / 10.02f;
1822
1823             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1824             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1825
1826             hr = IDirect3DDevice9_BeginScene(device);
1827             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1828
1829             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1830             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1831
1832             hr = IDirect3DDevice9_EndScene(device);
1833             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1834
1835             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1836             color = getPixelColor(device, 128, 240);
1837             ok(color_match(color, test_data[i].color[j], 13),
1838                 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1839                 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1840
1841             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1842         }
1843     }
1844
1845     /* reset states */
1846     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1847     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1848     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1849     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1850     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1851     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1852     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1853     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1854
1855     IDirect3DVertexShader9_Release(vertex_shader[1]);
1856     IDirect3DVertexShader9_Release(vertex_shader[2]);
1857     IDirect3DPixelShader9_Release(pixel_shader[1]);
1858     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1859 }
1860
1861 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1862     unsigned int i, x, y;
1863     HRESULT hr;
1864     IDirect3DTexture9 *texture[2] = {NULL, NULL};
1865     D3DLOCKED_RECT locked_rect;
1866
1867     /* Generate the textures */
1868     for(i=0; i<2; i++)
1869     {
1870         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1871                                             D3DPOOL_MANAGED, &texture[i], NULL);
1872         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1873
1874         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1875         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1876         for (y = 0; y < 128; ++y)
1877         {
1878             if(i)
1879             { /* Set up black texture with 2x2 texel white spot in the middle */
1880                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1881                 for (x = 0; x < 128; ++x)
1882                 {
1883                     if(y>62 && y<66 && x>62 && x<66)
1884                         *ptr++ = 0xffffffff;
1885                     else
1886                         *ptr++ = 0xff000000;
1887                 }
1888             }
1889             else
1890             { /* Set up a displacement map which points away from the center parallel to the closest axis.
1891                * (if multiplied with bumpenvmat)
1892               */
1893                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1894                 for (x = 0; x < 128; ++x)
1895                 {
1896                     if(abs(x-64)>abs(y-64))
1897                     {
1898                         if(x < 64)
1899                             *ptr++ = 0xc000;
1900                         else
1901                             *ptr++ = 0x4000;
1902                     }
1903                     else
1904                     {
1905                         if(y < 64)
1906                             *ptr++ = 0x0040;
1907                         else
1908                             *ptr++ = 0x00c0;
1909                     }
1910                 }
1911             }
1912         }
1913         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1914         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1915
1916         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1917         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1918
1919         /* Disable texture filtering */
1920         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1921         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1922         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1923         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1924
1925         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1926         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1927         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1928         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1929     }
1930 }
1931
1932 /* test the behavior of the texbem instruction
1933  * with normal 2D and projective 2D textures
1934  */
1935 static void texbem_test(IDirect3DDevice9 *device)
1936 {
1937     HRESULT hr;
1938     DWORD color;
1939     int i;
1940
1941     static const DWORD pixel_shader_code[] = {
1942         0xffff0101,                         /* ps_1_1*/
1943         0x00000042, 0xb00f0000,             /* tex t0*/
1944         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1945         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1946         0x0000ffff
1947     };
1948     static const DWORD double_texbem_code[] =  {
1949         0xffff0103,                                         /* ps_1_3           */
1950         0x00000042, 0xb00f0000,                             /* tex t0           */
1951         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
1952         0x00000042, 0xb00f0002,                             /* tex t2           */
1953         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
1954         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
1955         0x0000ffff                                          /* end              */
1956     };
1957
1958
1959     static const float quad[][7] = {
1960         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1961         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1962         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1963         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1964     };
1965     static const float quad_proj[][9] = {
1966         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
1967         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
1968         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
1969         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1970     };
1971
1972     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1973         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1974         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1975         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1976         D3DDECL_END()
1977     },{
1978         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1979         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1980         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1981         D3DDECL_END()
1982     } };
1983
1984     /* use asymmetric matrix to test loading */
1985     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1986
1987     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1988     IDirect3DPixelShader9       *pixel_shader       = NULL;
1989     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
1990     D3DLOCKED_RECT locked_rect;
1991
1992     generate_bumpmap_textures(device);
1993
1994     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1995     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1996     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1997     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1998     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1999
2000     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
2001     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2002
2003     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2004     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2005
2006     for(i=0; i<2; i++)
2007     {
2008         if(i)
2009         {
2010             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
2011             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2012         }
2013
2014         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
2015         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
2016         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2017         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
2018
2019         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
2020         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2021         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2022         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2023
2024         hr = IDirect3DDevice9_BeginScene(device);
2025         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2026
2027         if(!i)
2028             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2029         else
2030             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
2031         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2032
2033         hr = IDirect3DDevice9_EndScene(device);
2034         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2035
2036         color = getPixelColor(device, 320-32, 240);
2037         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2038         color = getPixelColor(device, 320+32, 240);
2039         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2040         color = getPixelColor(device, 320, 240-32);
2041         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2042         color = getPixelColor(device, 320, 240+32);
2043         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2044
2045         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2046         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2047
2048         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2049         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2050         IDirect3DPixelShader9_Release(pixel_shader);
2051
2052         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2053         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2054         IDirect3DVertexDeclaration9_Release(vertex_declaration);
2055     }
2056
2057     /* clean up */
2058     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
2059     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
2060
2061     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2062     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2063
2064     for(i=0; i<2; i++)
2065     {
2066         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
2067         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
2068         IDirect3DTexture9_Release(texture); /* For the GetTexture */
2069         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
2070         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2071         IDirect3DTexture9_Release(texture);
2072     }
2073
2074     /* Test double texbem */
2075     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
2076     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2077     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
2078     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2079     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
2080     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2081     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
2082     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2083
2084     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
2085     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2086     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
2087     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
2088
2089     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2090     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2091
2092     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
2093     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2094     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
2095     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
2096     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
2097     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2098
2099     {
2100         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
2101 #define tex  0x00ff0000
2102 #define tex1 0x0000ff00
2103 #define origin 0x000000ff
2104         static const DWORD pixel_data[] = {
2105             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2106             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2107             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2108             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2109             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
2110             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2111             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2112             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2113         };
2114 #undef tex1
2115 #undef tex2
2116 #undef origin
2117
2118         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
2119         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2120         for(i = 0; i < 8; i++) {
2121             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
2122         }
2123         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
2124         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2125     }
2126
2127     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2128     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2129     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
2130     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2131     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
2132     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2133     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
2134     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2135     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2136     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2137     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
2138     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2139
2140     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
2141     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
2142     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2143     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2144     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2145     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2146     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2147     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2148     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2149     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2150
2151     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
2152     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
2153     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2154     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2155     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2156     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2157     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2158     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2159     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2160     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2161
2162     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2163     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2164     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2165     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2166     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2167     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2168     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2169     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2170     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2171     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2172     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2173     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2174     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2175     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2176     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2177     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2178
2179     hr = IDirect3DDevice9_BeginScene(device);
2180     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2181     if(SUCCEEDED(hr)) {
2182         static const float double_quad[] = {
2183             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2184              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2185             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2186              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2187         };
2188
2189         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
2190         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2191         hr = IDirect3DDevice9_EndScene(device);
2192         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2193     }
2194     color = getPixelColor(device, 320, 240);
2195     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2196
2197     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2198     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2199     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
2200     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2201     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
2202     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2203     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
2204     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2205     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2206     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2207
2208     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2209     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2210
2211     IDirect3DPixelShader9_Release(pixel_shader);
2212     IDirect3DTexture9_Release(texture);
2213     IDirect3DTexture9_Release(texture1);
2214     IDirect3DTexture9_Release(texture2);
2215 }
2216
2217 static void z_range_test(IDirect3DDevice9 *device)
2218 {
2219     const struct vertex quad[] =
2220     {
2221         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
2222         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
2223         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
2224         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
2225     };
2226     const struct vertex quad2[] =
2227     {
2228         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
2229         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
2230         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
2231         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
2232     };
2233
2234     const struct tvertex quad3[] =
2235     {
2236         {    0,   240,   1.1f,  1.0,                    0xffffff00},
2237         {    0,   480,   1.1f,  1.0,                    0xffffff00},
2238         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
2239         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
2240     };
2241     const struct tvertex quad4[] =
2242     {
2243         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
2244         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
2245         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
2246         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
2247     };
2248     HRESULT hr;
2249     DWORD color;
2250     IDirect3DVertexShader9 *shader;
2251     IDirect3DVertexDeclaration9 *decl;
2252     D3DCAPS9 caps;
2253     const DWORD shader_code[] = {
2254         0xfffe0101,                                     /* vs_1_1           */
2255         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
2256         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
2257         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
2258         0x0000ffff                                      /* end              */
2259     };
2260     static const D3DVERTEXELEMENT9 decl_elements[] = {
2261         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2262         D3DDECL_END()
2263     };
2264
2265     IDirect3DDevice9_GetDeviceCaps(device, &caps);
2266
2267     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2268      * then call Present. Then clear the color buffer to make sure it has some defined content
2269      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2270      * by the depth value.
2271      */
2272     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2273     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2274     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2275     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2276     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2277     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2278
2279     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2280     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2281     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2282     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2283     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2284     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2285     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2286     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2287     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2288     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2289
2290     hr = IDirect3DDevice9_BeginScene(device);
2291     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2292     if(hr == D3D_OK)
2293     {
2294         /* Test the untransformed vertex path */
2295         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2296         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2297         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2298         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2299         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2300         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2301
2302         /* Test the transformed vertex path */
2303         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2304         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2305
2306         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2307         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2308         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2309         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2310         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2311         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2312
2313         hr = IDirect3DDevice9_EndScene(device);
2314         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2315     }
2316
2317     /* Do not test the exact corner pixels, but go pretty close to them */
2318
2319     /* Clipped because z > 1.0 */
2320     color = getPixelColor(device, 28, 238);
2321     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2322     color = getPixelColor(device, 28, 241);
2323     if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2324     {
2325         ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2326     }
2327     else
2328     {
2329         ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2330     }
2331
2332     /* Not clipped, > z buffer clear value(0.75) */
2333     color = getPixelColor(device, 31, 238);
2334     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2335     color = getPixelColor(device, 31, 241);
2336     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2337     color = getPixelColor(device, 100, 238);
2338     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2339     color = getPixelColor(device, 100, 241);
2340     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2341
2342     /* Not clipped, < z buffer clear value */
2343     color = getPixelColor(device, 104, 238);
2344     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2345     color = getPixelColor(device, 104, 241);
2346     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2347     color = getPixelColor(device, 318, 238);
2348     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2349     color = getPixelColor(device, 318, 241);
2350     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2351
2352     /* Clipped because z < 0.0 */
2353     color = getPixelColor(device, 321, 238);
2354     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2355     color = getPixelColor(device, 321, 241);
2356     if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2357     {
2358         ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2359     }
2360     else
2361     {
2362         ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2363     }
2364
2365     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2366     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2367
2368     /* Test the shader path */
2369     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2370         skip("Vertex shaders not supported\n");
2371         goto out;
2372     }
2373     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2374     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2375     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2376     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2377
2378     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2379
2380     IDirect3DDevice9_SetVertexDeclaration(device, decl);
2381     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2382     IDirect3DDevice9_SetVertexShader(device, shader);
2383     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2384
2385     hr = IDirect3DDevice9_BeginScene(device);
2386     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2387     if(hr == D3D_OK)
2388     {
2389         float colorf[] = {1.0, 0.0, 0.0, 1.0};
2390         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2391         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2392         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2393         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2394         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2395         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2396         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2397         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2398         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2399
2400         hr = IDirect3DDevice9_EndScene(device);
2401         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2402     }
2403
2404     IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2405     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2406     IDirect3DDevice9_SetVertexShader(device, NULL);
2407     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2408
2409     IDirect3DVertexDeclaration9_Release(decl);
2410     IDirect3DVertexShader9_Release(shader);
2411
2412     /* Z < 1.0 */
2413     color = getPixelColor(device, 28, 238);
2414     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2415
2416     /* 1.0 < z < 0.75 */
2417     color = getPixelColor(device, 31, 238);
2418     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2419     color = getPixelColor(device, 100, 238);
2420     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2421
2422     /* 0.75 < z < 0.0 */
2423     color = getPixelColor(device, 104, 238);
2424     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2425     color = getPixelColor(device, 318, 238);
2426     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2427
2428     /* 0.0 < z */
2429     color = getPixelColor(device, 321, 238);
2430     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2431
2432     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2433     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2434
2435     out:
2436     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2437     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2438     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2439     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2440     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2441     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2442 }
2443
2444 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2445 {
2446     D3DSURFACE_DESC desc;
2447     D3DLOCKED_RECT l;
2448     HRESULT hr;
2449     unsigned int x, y;
2450     DWORD *mem;
2451
2452     memset(&desc, 0, sizeof(desc));
2453     memset(&l, 0, sizeof(l));
2454     hr = IDirect3DSurface9_GetDesc(surface, &desc);
2455     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2456     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2457     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2458     if(FAILED(hr)) return;
2459
2460     for(y = 0; y < desc.Height; y++)
2461     {
2462         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2463         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2464         {
2465             mem[x] = color;
2466         }
2467     }
2468     hr = IDirect3DSurface9_UnlockRect(surface);
2469     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2470 }
2471
2472 /* This tests a variety of possible StretchRect() situations */
2473 static void stretchrect_test(IDirect3DDevice9 *device)
2474 {
2475     HRESULT hr;
2476     IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL, *tex_rt_dest640_480 = NULL;
2477     IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL, *surf_tex_rt_dest640_480 = NULL;
2478     IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2479     IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2480     IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2481     IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2482     IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2483     IDirect3DSurface9 *orig_rt = NULL;
2484     IDirect3DSurface9 *backbuffer = NULL;
2485     DWORD color;
2486
2487     RECT src_rect64 = {0, 0, 64, 64};
2488     RECT src_rect64_flipy = {0, 64, 64, 0};
2489     RECT dst_rect64 = {0, 0, 64, 64};
2490     RECT dst_rect64_flipy = {0, 64, 64, 0};
2491
2492     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2493     ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2494     if(!orig_rt) {
2495         goto out;
2496     }
2497
2498     /* Create our temporary surfaces in system memory */
2499     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2500     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2501     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2502     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2503
2504     /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2505     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2506     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2507     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2508     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2509     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2510     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2511
2512     /* Create render target surfaces */
2513     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2514     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2515     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2516     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2517     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2518     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2519     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2520     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2521
2522     /* Create render target textures */
2523     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2524     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2525     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2526     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2527     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2528     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2529     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
2530     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2531     if (tex_rt32) {
2532         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2533         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2534     }
2535     if (tex_rt64) {
2536         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2537         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2538     }
2539     if (tex_rt_dest64) {
2540         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2541         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2542     }
2543     if (tex_rt_dest64) {
2544         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
2545         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2546     }
2547
2548     /* Create regular textures in D3DPOOL_DEFAULT */
2549     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2550     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2551     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2552     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2553     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2554     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2555     if (tex32) {
2556         hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2557         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2558     }
2559     if (tex64) {
2560         hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2561         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2562     }
2563     if (tex_dest64) {
2564         hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2565         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2566     }
2567
2568     /*********************************************************************
2569      * Tests for when the source parameter is an offscreen plain surface *
2570      *********************************************************************/
2571
2572     /* Fill the offscreen 64x64 surface with green */
2573     if (surf_offscreen64)
2574         fill_surface(surf_offscreen64, 0xff00ff00);
2575
2576     /* offscreenplain ==> offscreenplain, same size */
2577     if(surf_offscreen64 && surf_offscreen_dest64) {
2578         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2579         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2580
2581         if (hr == D3D_OK) {
2582             color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2583             ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2584         }
2585
2586         /* Blit without scaling */
2587         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64, 0);
2588         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2589
2590         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2591         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_offscreen_dest64, &dst_rect64, 0);
2592         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2593
2594         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2595         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64_flipy, 0);
2596         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2597     }
2598
2599     /* offscreenplain ==> rendertarget texture, same size */
2600     if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2601         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2602         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2603
2604         /* We can't lock rendertarget textures, so copy to our temp surface first */
2605         if (hr == D3D_OK) {
2606             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2607             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2608         }
2609
2610         if (hr == D3D_OK) {
2611             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2612             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2613         }
2614
2615         /* Blit without scaling */
2616         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2617         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2618
2619         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2620         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2621         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2622
2623         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2624         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2625         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2626     }
2627
2628     /* offscreenplain ==> rendertarget surface, same size */
2629     if(surf_offscreen64 && surf_rt_dest64) {
2630         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2631         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2632
2633         if (hr == D3D_OK) {
2634             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2635             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2636         }
2637
2638         /* Blit without scaling */
2639         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2640         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2641
2642         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2643         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2644         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2645
2646         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2647         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2648         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2649     }
2650
2651     /* offscreenplain ==> texture, same size (should fail) */
2652     if(surf_offscreen64 && surf_tex_dest64) {
2653         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2654         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2655     }
2656
2657     /* Fill the smaller offscreen surface with red */
2658     fill_surface(surf_offscreen32, 0xffff0000);
2659
2660     /* offscreenplain ==> offscreenplain, scaling (should fail) */
2661     if(surf_offscreen32 && surf_offscreen64) {
2662         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2663         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2664     }
2665
2666     /* offscreenplain ==> rendertarget texture, scaling */
2667     if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2668         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2669         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2670
2671         /* We can't lock rendertarget textures, so copy to our temp surface first */
2672         if (hr == D3D_OK) {
2673             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2674             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2675         }
2676
2677         if (hr == D3D_OK) {
2678             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2679             ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2680         }
2681     }
2682
2683     /* offscreenplain ==> rendertarget surface, scaling */
2684     if(surf_offscreen32 && surf_rt_dest64) {
2685         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2686         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2687
2688         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2689         ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2690     }
2691
2692     /* offscreenplain ==> texture, scaling (should fail) */
2693     if(surf_offscreen32 && surf_tex_dest64) {
2694         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2695         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2696     }
2697
2698     /************************************************************
2699      * Tests for when the source parameter is a regular texture *
2700      ************************************************************/
2701
2702     /* Fill the surface of the regular texture with blue */
2703     if (surf_tex64 && surf_temp64) {
2704         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2705         fill_surface(surf_temp64, 0xff0000ff);
2706         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2707         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2708     }
2709
2710     /* texture ==> offscreenplain, same size */
2711     if(surf_tex64 && surf_offscreen64) {
2712         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2713         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2714     }
2715
2716     /* texture ==> rendertarget texture, same size */
2717     if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2718         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2719         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2720
2721         /* We can't lock rendertarget textures, so copy to our temp surface first */
2722         if (hr == D3D_OK) {
2723             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2724             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2725         }
2726
2727         if (hr == D3D_OK) {
2728             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2729             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2730         }
2731
2732         /* Blit without scaling */
2733         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2734         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2735
2736         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2737         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2738         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2739
2740         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2741         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2742         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2743     }
2744
2745     /* texture ==> rendertarget surface, same size */
2746     if(surf_tex64 && surf_rt_dest64) {
2747         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2748         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2749
2750         if (hr == D3D_OK) {
2751             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2752             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2753         }
2754
2755         /* Blit without scaling */
2756         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2757         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2758
2759         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2760         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2761         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2762
2763         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2764         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2765         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2766     }
2767
2768     /* texture ==> texture, same size (should fail) */
2769     if(surf_tex64 && surf_tex_dest64) {
2770         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2771         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2772     }
2773
2774     /* Fill the surface of the smaller regular texture with red */
2775     if (surf_tex32 && surf_temp32) {
2776         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2777         fill_surface(surf_temp32, 0xffff0000);
2778         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2779         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2780     }
2781
2782     /* texture ==> offscreenplain, scaling (should fail) */
2783     if(surf_tex32 && surf_offscreen64) {
2784         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2785         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2786     }
2787
2788     /* texture ==> rendertarget texture, scaling */
2789     if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2790         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, 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, 48, 48);
2801             ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2802         }
2803     }
2804
2805     /* texture ==> rendertarget surface, scaling */
2806     if(surf_tex32 && surf_rt_dest64) {
2807         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2808         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2809
2810         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2811         ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2812     }
2813
2814     /* texture ==> texture, scaling (should fail) */
2815     if(surf_tex32 && surf_tex_dest64) {
2816         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2817         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2818     }
2819
2820     /*****************************************************************
2821      * Tests for when the source parameter is a rendertarget texture *
2822      *****************************************************************/
2823
2824     /* Fill the surface of the rendertarget texture with white */
2825     if (surf_tex_rt64 && surf_temp64) {
2826         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2827         fill_surface(surf_temp64, 0xffffffff);
2828         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2829         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2830     }
2831
2832     /* rendertarget texture ==> offscreenplain, same size */
2833     if(surf_tex_rt64 && surf_offscreen64) {
2834         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2835         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2836     }
2837
2838     /* rendertarget texture ==> rendertarget texture, same size */
2839     if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2840         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2841         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2842
2843         /* We can't lock rendertarget textures, so copy to our temp surface first */
2844         if (hr == D3D_OK) {
2845             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2846             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2847         }
2848
2849         if (hr == D3D_OK) {
2850             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2851             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2852         }
2853
2854         /* Blit without scaling */
2855         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2856         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2857
2858         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2859         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2860         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2861
2862         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2863         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2864         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2865     }
2866
2867     /* rendertarget texture ==> rendertarget surface, same size */
2868     if(surf_tex_rt64 && surf_rt_dest64) {
2869         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2870         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2871
2872         if (hr == D3D_OK) {
2873             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2874             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2875         }
2876
2877         /* Blit without scaling */
2878         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2879         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2880
2881         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2882         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2883         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2884
2885         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2886         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2887         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2888     }
2889
2890     /* rendertarget texture ==> texture, same size (should fail) */
2891     if(surf_tex_rt64 && surf_tex_dest64) {
2892         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2893         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2894     }
2895
2896     /* Fill the surface of the smaller rendertarget texture with red */
2897     if (surf_tex_rt32 && surf_temp32) {
2898         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2899         fill_surface(surf_temp32, 0xffff0000);
2900         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2901         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2902     }
2903
2904     /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2905     if(surf_tex_rt32 && surf_offscreen64) {
2906         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2907         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2908     }
2909
2910     /* rendertarget texture ==> rendertarget texture, scaling */
2911     if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2912         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2913         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2914
2915         /* We can't lock rendertarget textures, so copy to our temp surface first */
2916         if (hr == D3D_OK) {
2917             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2918             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2919         }
2920
2921         if (hr == D3D_OK) {
2922             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2923             ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2924         }
2925     }
2926
2927     /* rendertarget texture ==> rendertarget surface, scaling */
2928     if(surf_tex_rt32 && surf_rt_dest64) {
2929         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2930         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2931
2932         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2933         ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2934     }
2935
2936     /* rendertarget texture ==> texture, scaling (should fail) */
2937     if(surf_tex_rt32 && surf_tex_dest64) {
2938         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2939         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2940     }
2941
2942     /*****************************************************************
2943      * Tests for when the source parameter is a rendertarget surface *
2944      *****************************************************************/
2945
2946     /* Fill the surface of the rendertarget surface with black */
2947     if (surf_rt64)
2948         fill_surface(surf_rt64, 0xff000000);
2949
2950     /* rendertarget texture ==> offscreenplain, same size */
2951     if(surf_rt64 && surf_offscreen64) {
2952         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2953         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2954     }
2955
2956     /* rendertarget surface ==> rendertarget texture, same size */
2957     if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2958         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2959         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2960
2961         /* We can't lock rendertarget textures, so copy to our temp surface first */
2962         if (hr == D3D_OK) {
2963             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2964             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2965         }
2966
2967         if (hr == D3D_OK) {
2968             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2969             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2970         }
2971
2972         /* Blit without scaling */
2973         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2974         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2975
2976         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2977         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2978         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2979
2980         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2981         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2982         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2983     }
2984
2985     /* rendertarget surface ==> rendertarget surface, same size */
2986     if(surf_rt64 && surf_rt_dest64) {
2987         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2988         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2989
2990         if (hr == D3D_OK) {
2991             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2992             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2993         }
2994
2995         /* Blit without scaling */
2996         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2997         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2998
2999         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3000         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64_flipy, 0);
3001         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3002
3003         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3004         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
3005         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3006     }
3007
3008     /* rendertarget surface ==> texture, same size (should fail) */
3009     if(surf_rt64 && surf_tex_dest64) {
3010         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
3011         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3012     }
3013
3014     /* Fill the surface of the smaller rendertarget texture with red */
3015     if (surf_rt32)
3016         fill_surface(surf_rt32, 0xffff0000);
3017
3018     /* rendertarget surface ==> offscreenplain, scaling (should fail) */
3019     if(surf_rt32 && surf_offscreen64) {
3020         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
3021         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3022     }
3023
3024     /* rendertarget surface ==> rendertarget texture, scaling */
3025     if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
3026         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
3027         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3028
3029         /* We can't lock rendertarget textures, so copy to our temp surface first */
3030         if (hr == D3D_OK) {
3031             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3032             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3033         }
3034
3035         if (hr == D3D_OK) {
3036             color = getPixelColorFromSurface(surf_temp64, 48, 48);
3037             ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3038         }
3039     }
3040
3041     /* rendertarget surface ==> rendertarget surface, scaling */
3042     if(surf_rt32 && surf_rt_dest64) {
3043         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
3044         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3045
3046         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3047         ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3048     }
3049
3050     /* rendertarget surface ==> texture, scaling (should fail) */
3051     if(surf_rt32 && surf_tex_dest64) {
3052         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
3053         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3054     }
3055
3056     /* backbuffer ==> surface tests (no scaling) */
3057     if(backbuffer && surf_tex_rt_dest640_480)
3058     {
3059         RECT src_rect = {0, 0, 640, 480};
3060         RECT src_rect_flipy = {0, 480, 640, 0};
3061         RECT dst_rect = {0, 0, 640, 480};
3062         RECT dst_rect_flipy = {0, 480, 640, 0};
3063
3064         /* Blit with NULL rectangles */
3065         hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, 0);
3066         ok( hr == D3D_OK, "StretchRect backbuffer ==> texture same size failed:\n");
3067
3068         /* Blit without scaling */
3069         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect, 0);
3070         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3071
3072         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3073         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy, surf_tex_rt_dest640_480, &dst_rect, 0);
3074         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3075
3076         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3077         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect_flipy, 0);
3078         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3079     }
3080
3081     /* TODO: Test format conversions */
3082
3083
3084 out:
3085     /* Clean up */
3086     if (backbuffer)
3087         IDirect3DSurface9_Release(backbuffer);
3088     if (surf_rt32)
3089         IDirect3DSurface9_Release(surf_rt32);
3090     if (surf_rt64)
3091         IDirect3DSurface9_Release(surf_rt64);
3092     if (surf_rt_dest64)
3093         IDirect3DSurface9_Release(surf_rt_dest64);
3094     if (surf_temp32)
3095         IDirect3DSurface9_Release(surf_temp32);
3096     if (surf_temp64)
3097         IDirect3DSurface9_Release(surf_temp64);
3098     if (surf_offscreen32)
3099         IDirect3DSurface9_Release(surf_offscreen32);
3100     if (surf_offscreen64)
3101         IDirect3DSurface9_Release(surf_offscreen64);
3102     if (surf_offscreen_dest64)
3103         IDirect3DSurface9_Release(surf_offscreen_dest64);
3104
3105     if (tex_rt32) {
3106         if (surf_tex_rt32)
3107             IDirect3DSurface9_Release(surf_tex_rt32);
3108         IDirect3DTexture9_Release(tex_rt32);
3109     }
3110     if (tex_rt64) {
3111         if (surf_tex_rt64)
3112             IDirect3DSurface9_Release(surf_tex_rt64);
3113         IDirect3DTexture9_Release(tex_rt64);
3114     }
3115     if (tex_rt_dest64) {
3116         if (surf_tex_rt_dest64)
3117             IDirect3DSurface9_Release(surf_tex_rt_dest64);
3118         IDirect3DTexture9_Release(tex_rt_dest64);
3119     }
3120     if (tex_rt_dest640_480) {
3121         if (surf_tex_rt_dest640_480)
3122             IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
3123         IDirect3DTexture9_Release(tex_rt_dest640_480);
3124     }
3125     if (tex32) {
3126         if (surf_tex32)
3127             IDirect3DSurface9_Release(surf_tex32);
3128         IDirect3DTexture9_Release(tex32);
3129     }
3130     if (tex64) {
3131         if (surf_tex64)
3132             IDirect3DSurface9_Release(surf_tex64);
3133         IDirect3DTexture9_Release(tex64);
3134     }
3135     if (tex_dest64) {
3136         if (surf_tex_dest64)
3137             IDirect3DSurface9_Release(surf_tex_dest64);
3138         IDirect3DTexture9_Release(tex_dest64);
3139     }
3140
3141     if (orig_rt) {
3142         hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
3143         ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
3144         IDirect3DSurface9_Release(orig_rt);
3145     }
3146 }
3147
3148 static void maxmip_test(IDirect3DDevice9 *device)
3149 {
3150     IDirect3DTexture9 *texture = NULL;
3151     IDirect3DSurface9 *surface = NULL;
3152     HRESULT hr;
3153     DWORD color;
3154     static const struct
3155     {
3156         struct
3157         {
3158             float x, y, z;
3159             float s, t;
3160         }
3161         v[4];
3162     }
3163     quads[] =
3164     {
3165         {{
3166             {-1.0, -1.0,  0.0,  0.0,  0.0},
3167             {-1.0,  0.0,  0.0,  0.0,  1.0},
3168             { 0.0, -1.0,  0.0,  1.0,  0.0},
3169             { 0.0,  0.0,  0.0,  1.0,  1.0},
3170         }},
3171         {{
3172             { 0.0, -1.0,  0.0,  0.0,  0.0},
3173             { 0.0,  0.0,  0.0,  0.0,  1.0},
3174             { 1.0, -1.0,  0.0,  1.0,  0.0},
3175             { 1.0,  0.0,  0.0,  1.0,  1.0},
3176         }},
3177         {{
3178             { 0.0,  0.0,  0.0,  0.0,  0.0},
3179             { 0.0,  1.0,  0.0,  0.0,  1.0},
3180             { 1.0,  0.0,  0.0,  1.0,  0.0},
3181             { 1.0,  1.0,  0.0,  1.0,  1.0},
3182         }},
3183         {{
3184             {-1.0,  0.0,  0.0,  0.0,  0.0},
3185             {-1.0,  1.0,  0.0,  0.0,  1.0},
3186             { 0.0,  0.0,  0.0,  1.0,  0.0},
3187             { 0.0,  1.0,  0.0,  1.0,  1.0},
3188         }},
3189     };
3190
3191     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
3192                                         &texture, NULL);
3193     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3194     if(!texture)
3195     {
3196         skip("Failed to create test texture\n");
3197         return;
3198     }
3199
3200     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3201     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3202     fill_surface(surface, 0xffff0000);
3203     IDirect3DSurface9_Release(surface);
3204     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
3205     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3206     fill_surface(surface, 0xff00ff00);
3207     IDirect3DSurface9_Release(surface);
3208     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3209     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3210     fill_surface(surface, 0xff0000ff);
3211     IDirect3DSurface9_Release(surface);
3212
3213     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3214     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3215     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3216     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3217
3218     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3219     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3220
3221     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3222     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3223
3224     hr = IDirect3DDevice9_BeginScene(device);
3225     if(SUCCEEDED(hr))
3226     {
3227         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3228         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3229         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3230         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3231
3232         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3233         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3234         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3235         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3236
3237         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3238         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3239         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3240         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3241
3242         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3243         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3244         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3245         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3246         hr = IDirect3DDevice9_EndScene(device);
3247         ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
3248     }
3249
3250     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
3251     color = getPixelColor(device, 160, 360);
3252     ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
3253     color = getPixelColor(device, 480, 360);
3254     ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
3255     color = getPixelColor(device, 480, 120);
3256     ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
3257     color = getPixelColor(device, 160, 120);
3258     ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
3259     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3260     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3261
3262     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3263     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3264
3265     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3266     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3267
3268     hr = IDirect3DDevice9_BeginScene(device);
3269     if(SUCCEEDED(hr))
3270     {
3271         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3272         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3273         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3274         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3275
3276         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3277         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3278         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3279         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3280
3281         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3282         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3283         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3284         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3285
3286         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3287         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3288         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3289         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3290         hr = IDirect3DDevice9_EndScene(device);
3291         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
3292     }
3293
3294     /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3295      * level 3 (> levels in texture) samples from the highest level in the
3296      * texture (level 2). */
3297     color = getPixelColor(device, 160, 360);
3298     ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
3299     color = getPixelColor(device, 480, 360);
3300     ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
3301     color = getPixelColor(device, 480, 120);
3302     ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
3303     color = getPixelColor(device, 160, 120);
3304     ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
3305     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3306     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3307
3308     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3309     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3310
3311     hr = IDirect3DDevice9_BeginScene(device);
3312     if(SUCCEEDED(hr))
3313     {
3314         DWORD ret;
3315
3316         /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
3317         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3318         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3319         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3320         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3321         ret = IDirect3DTexture9_SetLOD(texture, 1);
3322         ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
3323         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3324         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3325
3326         /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
3327         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3328         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3329         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3330         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3331         ret = IDirect3DTexture9_SetLOD(texture, 2);
3332         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3333         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3334         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3335
3336         /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
3337         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3338         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3339         ret = IDirect3DTexture9_SetLOD(texture, 1);
3340         ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
3341         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3342         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3343
3344         /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
3345         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3346         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3347         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3348         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3349         ret = IDirect3DTexture9_SetLOD(texture, 1);
3350         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3351         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3352         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3353         hr = IDirect3DDevice9_EndScene(device);
3354         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3355     }
3356
3357     /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3358      * level 3 (> levels in texture) samples from the highest level in the
3359      * texture (level 2). */
3360     color = getPixelColor(device, 160, 360);
3361     ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
3362     color = getPixelColor(device, 480, 360);
3363     ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
3364     color = getPixelColor(device, 480, 120);
3365     ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
3366     color = getPixelColor(device, 160, 120);
3367     ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
3368
3369     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3370     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3371
3372     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3373     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3374     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3375     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3376     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3377     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3378     IDirect3DTexture9_Release(texture);
3379 }
3380
3381 static void release_buffer_test(IDirect3DDevice9 *device)
3382 {
3383     IDirect3DVertexBuffer9 *vb = NULL;
3384     IDirect3DIndexBuffer9 *ib = NULL;
3385     HRESULT hr;
3386     BYTE *data;
3387     LONG ref;
3388
3389     static const struct vertex quad[] = {
3390         {-1.0,      -1.0,       0.1,        0xffff0000},
3391         {-1.0,       1.0,       0.1,        0xffff0000},
3392         { 1.0,       1.0,       0.1,        0xffff0000},
3393
3394         {-1.0,      -1.0,       0.1,        0xff00ff00},
3395         {-1.0,       1.0,       0.1,        0xff00ff00},
3396         { 1.0,       1.0,       0.1,        0xff00ff00}
3397     };
3398     short indices[] = {3, 4, 5};
3399
3400     /* Index and vertex buffers should always be creatable */
3401     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
3402                                               D3DPOOL_MANAGED, &vb, NULL);
3403     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
3404     if(!vb) {
3405         skip("Failed to create a vertex buffer\n");
3406         return;
3407     }
3408     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3409     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
3410     if(!ib) {
3411         skip("Failed to create an index buffer\n");
3412         return;
3413     }
3414
3415     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3416     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3417     memcpy(data, quad, sizeof(quad));
3418     hr = IDirect3DVertexBuffer9_Unlock(vb);
3419     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3420
3421     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3422     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3423     memcpy(data, indices, sizeof(indices));
3424     hr = IDirect3DIndexBuffer9_Unlock(ib);
3425     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3426
3427     hr = IDirect3DDevice9_SetIndices(device, ib);
3428     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3429     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3430     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3431     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3432     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3433
3434     /* Now destroy the bound index buffer and draw again */
3435     ref = IDirect3DIndexBuffer9_Release(ib);
3436     ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3437
3438     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3439     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3440
3441     hr = IDirect3DDevice9_BeginScene(device);
3442     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3443     if(SUCCEEDED(hr))
3444     {
3445         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3446          * making assumptions about the indices or vertices
3447          */
3448         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3449         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3450         hr = IDirect3DDevice9_EndScene(device);
3451         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3452     }
3453
3454     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3455     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3456
3457     hr = IDirect3DDevice9_SetIndices(device, NULL);
3458     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3459     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3460     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3461
3462     /* Index buffer was already destroyed as part of the test */
3463     IDirect3DVertexBuffer9_Release(vb);
3464 }
3465
3466 static void float_texture_test(IDirect3DDevice9 *device)
3467 {
3468     IDirect3D9 *d3d = NULL;
3469     HRESULT hr;
3470     IDirect3DTexture9 *texture = NULL;
3471     D3DLOCKED_RECT lr;
3472     float *data;
3473     DWORD color;
3474     float quad[] = {
3475         -1.0,      -1.0,       0.1,     0.0,    0.0,
3476         -1.0,       1.0,       0.1,     0.0,    1.0,
3477          1.0,      -1.0,       0.1,     1.0,    0.0,
3478          1.0,       1.0,       0.1,     1.0,    1.0,
3479     };
3480
3481     memset(&lr, 0, sizeof(lr));
3482     IDirect3DDevice9_GetDirect3D(device, &d3d);
3483     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3484                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3485         skip("D3DFMT_R32F textures not supported\n");
3486         goto out;
3487     }
3488
3489     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3490                                         D3DPOOL_MANAGED, &texture, NULL);
3491     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3492     if(!texture) {
3493         skip("Failed to create R32F texture\n");
3494         goto out;
3495     }
3496
3497     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3498     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3499     data = lr.pBits;
3500     *data = 0.0;
3501     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3502     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3503
3504     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3505     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3506
3507     hr = IDirect3DDevice9_BeginScene(device);
3508     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3509     if(SUCCEEDED(hr))
3510     {
3511         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3512         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3513
3514         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3515         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3516
3517         hr = IDirect3DDevice9_EndScene(device);
3518         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3519     }
3520     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3521     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3522
3523     color = getPixelColor(device, 240, 320);
3524     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3525
3526     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3527     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3528
3529 out:
3530     if(texture) IDirect3DTexture9_Release(texture);
3531     IDirect3D9_Release(d3d);
3532 }
3533
3534 static void g16r16_texture_test(IDirect3DDevice9 *device)
3535 {
3536     IDirect3D9 *d3d = NULL;
3537     HRESULT hr;
3538     IDirect3DTexture9 *texture = NULL;
3539     D3DLOCKED_RECT lr;
3540     DWORD *data;
3541     DWORD color;
3542     float quad[] = {
3543        -1.0,      -1.0,       0.1,     0.0,    0.0,
3544        -1.0,       1.0,       0.1,     0.0,    1.0,
3545         1.0,      -1.0,       0.1,     1.0,    0.0,
3546         1.0,       1.0,       0.1,     1.0,    1.0,
3547     };
3548
3549     memset(&lr, 0, sizeof(lr));
3550     IDirect3DDevice9_GetDirect3D(device, &d3d);
3551     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3552        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3553            skip("D3DFMT_G16R16 textures not supported\n");
3554            goto out;
3555     }
3556
3557     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3558                                         D3DPOOL_MANAGED, &texture, NULL);
3559     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3560     if(!texture) {
3561         skip("Failed to create D3DFMT_G16R16 texture\n");
3562         goto out;
3563     }
3564
3565     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3566     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3567     data = lr.pBits;
3568     *data = 0x0f00f000;
3569     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3570     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3571
3572     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3573     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3574
3575     hr = IDirect3DDevice9_BeginScene(device);
3576     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3577     if(SUCCEEDED(hr))
3578     {
3579         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3580         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3581
3582         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3583         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3584
3585         hr = IDirect3DDevice9_EndScene(device);
3586         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3587     }
3588     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3589     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3590
3591     color = getPixelColor(device, 240, 320);
3592     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3593        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3594
3595     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3596     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3597
3598 out:
3599     if(texture) IDirect3DTexture9_Release(texture);
3600     IDirect3D9_Release(d3d);
3601 }
3602
3603 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3604 {
3605     HRESULT hr;
3606     IDirect3D9 *d3d;
3607     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3608     D3DCAPS9 caps;
3609     IDirect3DTexture9 *texture = NULL;
3610     IDirect3DVolumeTexture9 *volume = NULL;
3611     unsigned int x, y, z;
3612     D3DLOCKED_RECT lr;
3613     D3DLOCKED_BOX lb;
3614     DWORD color;
3615     UINT w, h;
3616     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3617     float identity[16] = {1.0, 0.0, 0.0, 0.0,
3618                            0.0, 1.0, 0.0, 0.0,
3619                            0.0, 0.0, 1.0, 0.0,
3620                            0.0, 0.0, 0.0, 1.0};
3621     static const D3DVERTEXELEMENT9 decl_elements[] = {
3622         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3623         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3624         D3DDECL_END()
3625     };
3626     static const D3DVERTEXELEMENT9 decl_elements2[] = {
3627         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3628         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3629         D3DDECL_END()
3630     };
3631     static const D3DVERTEXELEMENT9 decl_elements3[] = {
3632         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3633         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3634         D3DDECL_END()
3635     };
3636     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3637                                                  0x00, 0xff, 0x00, 0x00,
3638                                                  0x00, 0x00, 0x00, 0x00,
3639                                                  0x00, 0x00, 0x00, 0x00};
3640
3641     memset(&lr, 0, sizeof(lr));
3642     memset(&lb, 0, sizeof(lb));
3643     IDirect3DDevice9_GetDirect3D(device, &d3d);
3644     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3645                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3646         fmt = D3DFMT_A16B16G16R16;
3647     }
3648     IDirect3D9_Release(d3d);
3649
3650     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3651     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3652     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3653     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3654     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3655     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3656     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3657     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3658     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3659     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3660     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3661     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3662     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3663     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3664     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3665     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3666     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3667     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3668     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3669     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3670     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3671     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3672     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3673     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3674
3675     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3676     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3677     w = min(1024, caps.MaxTextureWidth);
3678     h = min(1024, caps.MaxTextureHeight);
3679     hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3680                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3681     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3682     if(!texture) {
3683         skip("Failed to create the test texture\n");
3684         return;
3685     }
3686
3687     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3688      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3689      * 1.0 in red and green for the x and y coords
3690      */
3691     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3692     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3693     for(y = 0; y < h; y++) {
3694         for(x = 0; x < w; x++) {
3695             double r_f = (double) y / (double) h;
3696             double g_f = (double) x / (double) w;
3697             if(fmt == D3DFMT_A16B16G16R16) {
3698                 unsigned short r, g;
3699                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3700                 r = (unsigned short) (r_f * 65536.0);
3701                 g = (unsigned short) (g_f * 65536.0);
3702                 dst[0] = r;
3703                 dst[1] = g;
3704                 dst[2] = 0;
3705                 dst[3] = 65535;
3706             } else {
3707                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3708                 unsigned char r = (unsigned char) (r_f * 255.0);
3709                 unsigned char g = (unsigned char) (g_f * 255.0);
3710                 dst[0] = 0;
3711                 dst[1] = g;
3712                 dst[2] = r;
3713                 dst[3] = 255;
3714             }
3715         }
3716     }
3717     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3718     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3719     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3720     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3721
3722     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3723     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3724     hr = IDirect3DDevice9_BeginScene(device);
3725     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3726     if(SUCCEEDED(hr))
3727     {
3728         float quad1[] = {
3729             -1.0,      -1.0,       0.1,     1.0,    1.0,
3730             -1.0,       0.0,       0.1,     1.0,    1.0,
3731              0.0,      -1.0,       0.1,     1.0,    1.0,
3732              0.0,       0.0,       0.1,     1.0,    1.0,
3733         };
3734         float quad2[] = {
3735             -1.0,       0.0,       0.1,     1.0,    1.0,
3736             -1.0,       1.0,       0.1,     1.0,    1.0,
3737              0.0,       0.0,       0.1,     1.0,    1.0,
3738              0.0,       1.0,       0.1,     1.0,    1.0,
3739         };
3740         float quad3[] = {
3741              0.0,       0.0,       0.1,     0.5,    0.5,
3742              0.0,       1.0,       0.1,     0.5,    0.5,
3743              1.0,       0.0,       0.1,     0.5,    0.5,
3744              1.0,       1.0,       0.1,     0.5,    0.5,
3745         };
3746         float quad4[] = {
3747              320,       480,       0.1,     1.0,    0.0,    1.0,
3748              320,       240,       0.1,     1.0,    0.0,    1.0,
3749              640,       480,       0.1,     1.0,    0.0,    1.0,
3750              640,       240,       0.1,     1.0,    0.0,    1.0,
3751         };
3752         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3753                           0.0, 0.0, 0.0, 0.0,
3754                           0.0, 0.0, 0.0, 0.0,
3755                           0.0, 0.0, 0.0, 0.0};
3756
3757         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3758         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3759         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3760         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3761         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3762
3763         /* What happens with transforms enabled? */
3764         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3765         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3766         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3767         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3768
3769         /* What happens if 4 coords are used, but only 2 given ?*/
3770         mat[8] = 1.0;
3771         mat[13] = 1.0;
3772         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3773         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3774         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3775         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3776         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3777         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3778
3779         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3780          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3781          * due to the coords in the vertices. (turns out red, indeed)
3782          */
3783         memset(mat, 0, sizeof(mat));
3784         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3785         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3786         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3787         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3788         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3789         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3790         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3791         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3792
3793         hr = IDirect3DDevice9_EndScene(device);
3794         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3795     }
3796     color = getPixelColor(device, 160, 360);
3797     ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3798     color = getPixelColor(device, 160, 120);
3799     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3800     color = getPixelColor(device, 480, 120);
3801     ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
3802     color = getPixelColor(device, 480, 360);
3803     ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
3804     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3805     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3806
3807     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3808     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3809
3810     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3811     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3812     hr = IDirect3DDevice9_BeginScene(device);
3813     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3814     if(SUCCEEDED(hr))
3815     {
3816         float quad1[] = {
3817             -1.0,      -1.0,       0.1,     0.8,    0.2,
3818             -1.0,       0.0,       0.1,     0.8,    0.2,
3819              0.0,      -1.0,       0.1,     0.8,    0.2,
3820              0.0,       0.0,       0.1,     0.8,    0.2,
3821         };
3822         float quad2[] = {
3823             -1.0,       0.0,       0.1,     0.5,    1.0,
3824             -1.0,       1.0,       0.1,     0.5,    1.0,
3825              0.0,       0.0,       0.1,     0.5,    1.0,
3826              0.0,       1.0,       0.1,     0.5,    1.0,
3827         };
3828         float quad3[] = {
3829              0.0,       0.0,       0.1,     0.5,    1.0,
3830              0.0,       1.0,       0.1,     0.5,    1.0,
3831              1.0,       0.0,       0.1,     0.5,    1.0,
3832              1.0,       1.0,       0.1,     0.5,    1.0,
3833         };
3834         float quad4[] = {
3835              0.0,      -1.0,       0.1,     0.8,    0.2,
3836              0.0,       0.0,       0.1,     0.8,    0.2,
3837              1.0,      -1.0,       0.1,     0.8,    0.2,
3838              1.0,       0.0,       0.1,     0.8,    0.2,
3839         };
3840         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3841                           0.0, 0.0, 0.0, 0.0,
3842                           0.0, 1.0, 0.0, 0.0,
3843                           0.0, 0.0, 0.0, 0.0};
3844
3845         /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3846          */
3847         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3848         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3849         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3850         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3851
3852         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3853         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3854
3855         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3856          * it behaves like COUNT2 because normal textures require 2 coords
3857          */
3858         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3859         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3860         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3861         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3862
3863         /* Just to be sure, the same as quad2 above */
3864         memset(mat, 0, sizeof(mat));
3865         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3866         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3867         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3868         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3869         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3870         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3871
3872         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3873          * used? And what happens to the first?
3874          */
3875         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3876         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3877         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3878         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3879
3880         hr = IDirect3DDevice9_EndScene(device);
3881         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3882     }
3883     color = getPixelColor(device, 160, 360);
3884     ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
3885     color = getPixelColor(device, 160, 120);
3886     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3887     color = getPixelColor(device, 480, 120);
3888     ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
3889        "quad 3 has color %08x, expected 0x00ff8000\n", color);
3890     color = getPixelColor(device, 480, 360);
3891     ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
3892        "quad 4 has color %08x, expected 0x0033cc00\n", color);
3893     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3894     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3895
3896     IDirect3DTexture9_Release(texture);
3897
3898     /* Test projected textures, without any fancy matrices */
3899     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3900     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3901     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3902     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3903     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3904     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3905     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3906     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3907
3908     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3909     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3910     for(x = 0; x < 4; x++) {
3911         memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3912     }
3913     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3914     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3915     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3916     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3917
3918     hr = IDirect3DDevice9_BeginScene(device);
3919     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3920     if(SUCCEEDED(hr))
3921     {
3922         const float proj_quads[] = {
3923            -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3924             1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3925            -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3926             1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3927            -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3928             1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3929            -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3930             1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3931         };
3932
3933         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3934         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3935         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3936         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3937
3938         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3939         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3940         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3941         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3942
3943         hr = IDirect3DDevice9_EndScene(device);
3944         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3945     }
3946
3947     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3948     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3949     IDirect3DTexture9_Release(texture);
3950
3951     color = getPixelColor(device, 158, 118);
3952     ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3953     color = getPixelColor(device, 162, 118);
3954     ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3955     color = getPixelColor(device, 158, 122);
3956     ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3957     color = getPixelColor(device, 162, 122);
3958     ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3959
3960     color = getPixelColor(device, 158, 178);
3961     ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3962     color = getPixelColor(device, 162, 178);
3963     ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3964     color = getPixelColor(device, 158, 182);
3965     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3966     color = getPixelColor(device, 162, 182);
3967     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3968
3969     color = getPixelColor(device, 318, 118);
3970     ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3971     color = getPixelColor(device, 322, 118);
3972     ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3973     color = getPixelColor(device, 318, 122);
3974     ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3975     color = getPixelColor(device, 322, 122);
3976     ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3977
3978     color = getPixelColor(device, 318, 178);
3979     ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3980     color = getPixelColor(device, 322, 178);
3981     ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3982     color = getPixelColor(device, 318, 182);
3983     ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3984     color = getPixelColor(device, 322, 182);
3985     ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3986
3987     color = getPixelColor(device, 238, 298);
3988     ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3989     color = getPixelColor(device, 242, 298);
3990     ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3991     color = getPixelColor(device, 238, 302);
3992     ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3993     color = getPixelColor(device, 242, 302);
3994     ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3995
3996     color = getPixelColor(device, 238, 388);
3997     ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3998     color = getPixelColor(device, 242, 388);
3999     ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
4000     color = getPixelColor(device, 238, 392);
4001     ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
4002     color = getPixelColor(device, 242, 392);
4003     ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
4004
4005     color = getPixelColor(device, 478, 298);
4006     ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
4007     color = getPixelColor(device, 482, 298);
4008     ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
4009     color = getPixelColor(device, 478, 302);
4010     ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
4011     color = getPixelColor(device, 482, 302);
4012     ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
4013
4014     color = getPixelColor(device, 478, 388);
4015     ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
4016     color = getPixelColor(device, 482, 388);
4017     ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
4018     color = getPixelColor(device, 478, 392);
4019     ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
4020     color = getPixelColor(device, 482, 392);
4021     ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
4022
4023     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4024     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4025
4026     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
4027     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4028     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
4029      * Thus watch out if sampling from texels between 0 and 1.
4030      */
4031     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
4032     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
4033        "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
4034     if(!volume) {
4035         skip("Failed to create a volume texture\n");
4036         goto out;
4037     }
4038
4039     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
4040     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
4041     for(z = 0; z < 32; z++) {
4042         for(y = 0; y < 32; y++) {
4043             for(x = 0; x < 32; x++) {
4044                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
4045                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
4046                 float r_f = (float) x / 31.0;
4047                 float g_f = (float) y / 31.0;
4048                 float b_f = (float) z / 31.0;
4049
4050                 if(fmt == D3DFMT_A16B16G16R16) {
4051                     unsigned short *mem_s = mem;
4052                     mem_s[0]  = r_f * 65535.0;
4053                     mem_s[1]  = g_f * 65535.0;
4054                     mem_s[2]  = b_f * 65535.0;
4055                     mem_s[3]  = 65535;
4056                 } else {
4057                     unsigned char *mem_c = mem;
4058                     mem_c[0]  = b_f * 255.0;
4059                     mem_c[1]  = g_f * 255.0;
4060                     mem_c[2]  = r_f * 255.0;
4061                     mem_c[3]  = 255;
4062                 }
4063             }
4064         }
4065     }
4066     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
4067     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4068
4069     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
4070     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4071
4072     hr = IDirect3DDevice9_BeginScene(device);
4073     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4074     if(SUCCEEDED(hr))
4075     {
4076         float quad1[] = {
4077             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4078             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4079              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4080              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
4081         };
4082         float quad2[] = {
4083             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4084             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
4085              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4086              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
4087         };
4088         float quad3[] = {
4089              0.0,       0.0,       0.1,     0.0,    0.0,
4090              0.0,       1.0,       0.1,     0.0,    0.0,
4091              1.0,       0.0,       0.1,     0.0,    0.0,
4092              1.0,       1.0,       0.1,     0.0,    0.0
4093         };
4094         float quad4[] = {
4095              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4096              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4097              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4098              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
4099         };
4100         float mat[16] = {1.0, 0.0, 0.0, 0.0,
4101                          0.0, 0.0, 1.0, 0.0,
4102                          0.0, 1.0, 0.0, 0.0,
4103                          0.0, 0.0, 0.0, 1.0};
4104         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4105         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4106
4107         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
4108          * values
4109          */
4110         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4111         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4112         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4113         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4114         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4115         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4116
4117         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
4118          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
4119          * otherwise the w will be missing(blue).
4120          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
4121          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
4122          */
4123         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4124         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4125         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4126         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4127
4128         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
4129         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4130         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4131         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4132         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4133         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4134         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4135         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4136         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4137
4138         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
4139          * disable. ATI extends it up to the amount of values needed for the volume texture
4140          */
4141         memset(mat, 0, sizeof(mat));
4142         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4143         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4144         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4145         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4146         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4147         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4148         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4149         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4150
4151         hr = IDirect3DDevice9_EndScene(device);
4152         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4153     }
4154
4155     color = getPixelColor(device, 160, 360);
4156     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
4157     color = getPixelColor(device, 160, 120);
4158     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
4159        "quad 2 has color %08x, expected 0x00ffff00\n", color);
4160     color = getPixelColor(device, 480, 120);
4161     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
4162     color = getPixelColor(device, 480, 360);
4163     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
4164
4165     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4166     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4167
4168     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
4169     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4170     hr = IDirect3DDevice9_BeginScene(device);
4171     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4172     if(SUCCEEDED(hr))
4173     {
4174         float quad1[] = {
4175             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4176             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4177              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4178              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
4179         };
4180         float quad2[] = {
4181             -1.0,       0.0,       0.1,
4182             -1.0,       1.0,       0.1,
4183              0.0,       0.0,       0.1,
4184              0.0,       1.0,       0.1,
4185         };
4186         float quad3[] = {
4187              0.0,       0.0,       0.1,     1.0,
4188              0.0,       1.0,       0.1,     1.0,
4189              1.0,       0.0,       0.1,     1.0,
4190              1.0,       1.0,       0.1,     1.0
4191         };
4192         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
4193                            0.0, 0.0, 0.0, 0.0,
4194                            0.0, 0.0, 0.0, 0.0,
4195                            0.0, 1.0, 0.0, 0.0};
4196         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
4197                            1.0, 0.0, 0.0, 0.0,
4198                            0.0, 1.0, 0.0, 0.0,
4199                            0.0, 0.0, 1.0, 0.0};
4200         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4201         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4202
4203         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
4204          * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
4205          * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
4206          * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
4207          * 4th *input* coordinate.
4208          */
4209         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4210         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4211         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4212         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4213         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4214         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4215
4216         /* None passed */
4217         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4218         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4219         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4220         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4221         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4222         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4223
4224         /* 4 used, 1 passed */
4225         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4226         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4227         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
4228         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4229         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4230         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4231
4232         hr = IDirect3DDevice9_EndScene(device);
4233         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4234     }
4235     color = getPixelColor(device, 160, 360);
4236     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4237     color = getPixelColor(device, 160, 120);
4238     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4239     color = getPixelColor(device, 480, 120);
4240     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4241     /* Quad4: unused */
4242
4243     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4244     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4245
4246     IDirect3DVolumeTexture9_Release(volume);
4247
4248     out:
4249     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4250     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4251     IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
4252     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4253     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4254     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4255     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4256     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4257     IDirect3DVertexDeclaration9_Release(decl);
4258     IDirect3DVertexDeclaration9_Release(decl2);
4259     IDirect3DVertexDeclaration9_Release(decl3);
4260 }
4261
4262 static void texdepth_test(IDirect3DDevice9 *device)
4263 {
4264     IDirect3DPixelShader9 *shader;
4265     HRESULT hr;
4266     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
4267     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
4268     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
4269     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
4270     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
4271     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
4272     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
4273     DWORD shader_code[] = {
4274         0xffff0104,                                                                 /* ps_1_4               */
4275         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
4276         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
4277         0x0000fffd,                                                                 /* phase                */
4278         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
4279         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
4280         0x0000ffff                                                                  /* end                  */
4281     };
4282     DWORD color;
4283     float vertex[] = {
4284        -1.0,   -1.0,    0.0,
4285         1.0,   -1.0,    1.0,
4286        -1.0,    1.0,    0.0,
4287         1.0,    1.0,    1.0
4288     };
4289
4290     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4291     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4292
4293     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4294     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4295     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4296     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4297     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4298     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4299     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4300     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4301     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4302     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4303
4304     /* Fill the depth buffer with a gradient */
4305     hr = IDirect3DDevice9_BeginScene(device);
4306     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4307     if(SUCCEEDED(hr))
4308     {
4309         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4310         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4311         hr = IDirect3DDevice9_EndScene(device);
4312         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4313     }
4314
4315     /* Now perform the actual tests. Same geometry, but with the shader */
4316     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4317     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4318     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4319     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4320     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4321     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4322
4323     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4324     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4325     hr = IDirect3DDevice9_BeginScene(device);
4326     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4327     if(SUCCEEDED(hr))
4328     {
4329         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4330         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4331
4332         hr = IDirect3DDevice9_EndScene(device);
4333         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4334     }
4335
4336     color = getPixelColor(device, 158, 240);
4337     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4338     color = getPixelColor(device, 162, 240);
4339     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
4340
4341     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4342     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4343
4344     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4345     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4346
4347     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
4348     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4349     hr = IDirect3DDevice9_BeginScene(device);
4350     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4351     if(SUCCEEDED(hr))
4352     {
4353         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4354         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4355
4356         hr = IDirect3DDevice9_EndScene(device);
4357         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4358     }
4359
4360     color = getPixelColor(device, 318, 240);
4361     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4362     color = getPixelColor(device, 322, 240);
4363     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4364
4365     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4366     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4367
4368     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4369     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4370
4371     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4372     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4373     hr = IDirect3DDevice9_BeginScene(device);
4374     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4375     if(SUCCEEDED(hr))
4376     {
4377         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4378         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4379
4380         hr = IDirect3DDevice9_EndScene(device);
4381         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4382     }
4383
4384     color = getPixelColor(device, 1, 240);
4385     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4386
4387     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4388     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4389
4390     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4391     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4392
4393     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4394     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4395     hr = IDirect3DDevice9_BeginScene(device);
4396     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4397     if(SUCCEEDED(hr))
4398     {
4399         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4400         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4401
4402         hr = IDirect3DDevice9_EndScene(device);
4403         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4404     }
4405     color = getPixelColor(device, 318, 240);
4406     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4407     color = getPixelColor(device, 322, 240);
4408     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
4409
4410     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4411     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4412
4413     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4414     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4415
4416     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
4417     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4418     hr = IDirect3DDevice9_BeginScene(device);
4419     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4420     if(SUCCEEDED(hr))
4421     {
4422         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4423         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4424
4425         hr = IDirect3DDevice9_EndScene(device);
4426         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4427     }
4428
4429     color = getPixelColor(device, 1, 240);
4430     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4431
4432     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4433     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4434
4435     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4436     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4437
4438     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4439     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4440     hr = IDirect3DDevice9_BeginScene(device);
4441     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4442     if(SUCCEEDED(hr))
4443     {
4444         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4445         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4446
4447         hr = IDirect3DDevice9_EndScene(device);
4448         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4449     }
4450
4451     color = getPixelColor(device, 638, 240);
4452     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4453
4454     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4455     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4456
4457     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4458     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4459
4460     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4461     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4462     hr = IDirect3DDevice9_BeginScene(device);
4463     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4464     if(SUCCEEDED(hr))
4465     {
4466         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4467         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4468
4469         hr = IDirect3DDevice9_EndScene(device);
4470         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4471     }
4472
4473     color = getPixelColor(device, 638, 240);
4474     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4475
4476     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4477     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4478
4479     /* Cleanup */
4480     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4481     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4482     IDirect3DPixelShader9_Release(shader);
4483
4484     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4485     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4486     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4487     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4488 }
4489
4490 static void texkill_test(IDirect3DDevice9 *device)
4491 {
4492     IDirect3DPixelShader9 *shader;
4493     HRESULT hr;
4494     DWORD color;
4495
4496     const float vertex[] = {
4497     /*                          bottom  top    right    left */
4498         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
4499          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
4500         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
4501          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
4502     };
4503
4504     DWORD shader_code_11[] = {
4505     0xffff0101,                                                             /* ps_1_1                     */
4506     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4507     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
4508     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
4509     0x0000ffff                                                              /* end                        */
4510     };
4511     DWORD shader_code_20[] = {
4512     0xffff0200,                                                             /* ps_2_0                     */
4513     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
4514     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4515     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
4516     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
4517     0x0000ffff                                                              /* end                        */
4518     };
4519
4520     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4521     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4522     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4523     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4524
4525     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4526     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4527     hr = IDirect3DDevice9_BeginScene(device);
4528     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4529     if(SUCCEEDED(hr))
4530     {
4531         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4532         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4533         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4534         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4535         hr = IDirect3DDevice9_EndScene(device);
4536         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4537     }
4538     color = getPixelColor(device, 63, 46);
4539     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4540     color = getPixelColor(device, 66, 46);
4541     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4542     color = getPixelColor(device, 63, 49);
4543     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4544     color = getPixelColor(device, 66, 49);
4545     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4546
4547     color = getPixelColor(device, 578, 46);
4548     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4549     color = getPixelColor(device, 575, 46);
4550     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4551     color = getPixelColor(device, 578, 49);
4552     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4553     color = getPixelColor(device, 575, 49);
4554     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4555
4556     color = getPixelColor(device, 63, 430);
4557     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4558     color = getPixelColor(device, 63, 433);
4559     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4560     color = getPixelColor(device, 66, 433);
4561     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4562     color = getPixelColor(device, 66, 430);
4563     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4564
4565     color = getPixelColor(device, 578, 430);
4566     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4567     color = getPixelColor(device, 578, 433);
4568     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4569     color = getPixelColor(device, 575, 433);
4570     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4571     color = getPixelColor(device, 575, 430);
4572     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4573
4574     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4575     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4576
4577     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4578     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4579     IDirect3DPixelShader9_Release(shader);
4580
4581     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4582     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4583     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4584     if(FAILED(hr)) {
4585         skip("Failed to create 2.0 test shader, most likely not supported\n");
4586         return;
4587     }
4588
4589     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4590     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4591     hr = IDirect3DDevice9_BeginScene(device);
4592     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4593     if(SUCCEEDED(hr))
4594     {
4595         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4596         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4597         hr = IDirect3DDevice9_EndScene(device);
4598         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4599     }
4600
4601     color = getPixelColor(device, 63, 46);
4602     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4603     color = getPixelColor(device, 66, 46);
4604     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4605     color = getPixelColor(device, 63, 49);
4606     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4607     color = getPixelColor(device, 66, 49);
4608     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4609
4610     color = getPixelColor(device, 578, 46);
4611     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4612     color = getPixelColor(device, 575, 46);
4613     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4614     color = getPixelColor(device, 578, 49);
4615     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4616     color = getPixelColor(device, 575, 49);
4617     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4618
4619     color = getPixelColor(device, 63, 430);
4620     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4621     color = getPixelColor(device, 63, 433);
4622     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4623     color = getPixelColor(device, 66, 433);
4624     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4625     color = getPixelColor(device, 66, 430);
4626     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4627
4628     color = getPixelColor(device, 578, 430);
4629     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4630     color = getPixelColor(device, 578, 433);
4631     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4632     color = getPixelColor(device, 575, 433);
4633     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4634     color = getPixelColor(device, 575, 430);
4635     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4636
4637     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4638     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4639
4640     /* Cleanup */
4641     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4642     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4643     IDirect3DPixelShader9_Release(shader);
4644 }
4645
4646 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4647 {
4648     IDirect3D9 *d3d9;
4649     HRESULT hr;
4650     IDirect3DTexture9 *texture;
4651     IDirect3DPixelShader9 *shader;
4652     IDirect3DPixelShader9 *shader2;
4653     D3DLOCKED_RECT lr;
4654     DWORD color;
4655     DWORD shader_code[] = {
4656         0xffff0101,                             /* ps_1_1       */
4657         0x00000042, 0xb00f0000,                 /* tex t0       */
4658         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
4659         0x0000ffff                              /* end          */
4660     };
4661     DWORD shader_code2[] = {
4662         0xffff0101,                             /* ps_1_1       */
4663         0x00000042, 0xb00f0000,                 /* tex t0       */
4664         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
4665         0x0000ffff                              /* end          */
4666     };
4667
4668     float quad[] = {
4669        -1.0,   -1.0,   0.1,     0.5,    0.5,
4670         1.0,   -1.0,   0.1,     0.5,    0.5,
4671        -1.0,    1.0,   0.1,     0.5,    0.5,
4672         1.0,    1.0,   0.1,     0.5,    0.5,
4673     };
4674
4675     memset(&lr, 0, sizeof(lr));
4676     IDirect3DDevice9_GetDirect3D(device, &d3d9);
4677     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4678                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4679     IDirect3D9_Release(d3d9);
4680     if(FAILED(hr)) {
4681         skip("No D3DFMT_X8L8V8U8 support\n");
4682         return;
4683     };
4684
4685     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4686     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4687
4688     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4689     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4690     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4691     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4692     *((DWORD *) lr.pBits) = 0x11ca3141;
4693     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4694     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4695
4696     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4697     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4698     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4699     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4700
4701     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4702     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4703     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4704     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4705     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4706     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4707
4708     hr = IDirect3DDevice9_BeginScene(device);
4709     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4710     if(SUCCEEDED(hr))
4711     {
4712         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4713         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4714
4715         hr = IDirect3DDevice9_EndScene(device);
4716         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4717     }
4718     color = getPixelColor(device, 578, 430);
4719     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4720        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4721     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4722     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4723
4724     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4725     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4726     hr = IDirect3DDevice9_BeginScene(device);
4727     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4728     if(SUCCEEDED(hr))
4729     {
4730         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4731         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4732
4733         hr = IDirect3DDevice9_EndScene(device);
4734         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4735     }
4736     color = getPixelColor(device, 578, 430);
4737     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4738     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4739     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4740
4741     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4742     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4743     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4744     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4745     IDirect3DPixelShader9_Release(shader);
4746     IDirect3DPixelShader9_Release(shader2);
4747     IDirect3DTexture9_Release(texture);
4748 }
4749
4750 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4751 {
4752     HRESULT hr;
4753     IDirect3D9 *d3d;
4754     IDirect3DTexture9 *texture = NULL;
4755     IDirect3DSurface9 *surface;
4756     DWORD color;
4757     const RECT r1 = {256, 256, 512, 512};
4758     const RECT r2 = {512, 256, 768, 512};
4759     const RECT r3 = {256, 512, 512, 768};
4760     const RECT r4 = {512, 512, 768, 768};
4761     unsigned int x, y;
4762     D3DLOCKED_RECT lr;
4763     memset(&lr, 0, sizeof(lr));
4764
4765     IDirect3DDevice9_GetDirect3D(device, &d3d);
4766     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4767        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4768         skip("No autogenmipmap support\n");
4769         IDirect3D9_Release(d3d);
4770         return;
4771     }
4772     IDirect3D9_Release(d3d);
4773
4774     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4775     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4776
4777     /* Make the mipmap big, so that a smaller mipmap is used
4778      */
4779     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4780                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4781     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4782
4783     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4784     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4785     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4786     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4787     for(y = 0; y < 1024; y++) {
4788         for(x = 0; x < 1024; x++) {
4789             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4790             POINT pt;
4791
4792             pt.x = x;
4793             pt.y = y;
4794             if(PtInRect(&r1, pt)) {
4795                 *dst = 0xffff0000;
4796             } else if(PtInRect(&r2, pt)) {
4797                 *dst = 0xff00ff00;
4798             } else if(PtInRect(&r3, pt)) {
4799                 *dst = 0xff0000ff;
4800             } else if(PtInRect(&r4, pt)) {
4801                 *dst = 0xff000000;
4802             } else {
4803                 *dst = 0xffffffff;
4804             }
4805         }
4806     }
4807     hr = IDirect3DSurface9_UnlockRect(surface);
4808     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4809     IDirect3DSurface9_Release(surface);
4810
4811     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4812     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4813     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4814     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4815
4816     hr = IDirect3DDevice9_BeginScene(device);
4817     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4818     if(SUCCEEDED(hr)) {
4819         const float quad[] =  {
4820            -0.5,   -0.5,    0.1,    0.0,    0.0,
4821            -0.5,    0.5,    0.1,    0.0,    1.0,
4822             0.5,   -0.5,    0.1,    1.0,    0.0,
4823             0.5,    0.5,    0.1,    1.0,    1.0
4824         };
4825
4826         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4827         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4828         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4829         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4830         hr = IDirect3DDevice9_EndScene(device);
4831         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4832     }
4833     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4834     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4835     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4836     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4837     IDirect3DTexture9_Release(texture);
4838
4839     color = getPixelColor(device, 200, 200);
4840     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4841     color = getPixelColor(device, 280, 200);
4842     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4843     color = getPixelColor(device, 360, 200);
4844     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4845     color = getPixelColor(device, 440, 200);
4846     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4847     color = getPixelColor(device, 200, 270);
4848     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4849     color = getPixelColor(device, 280, 270);
4850     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4851     color = getPixelColor(device, 360, 270);
4852     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4853     color = getPixelColor(device, 440, 270);
4854     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4855     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4856     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4857 }
4858
4859 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4860 {
4861     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4862     IDirect3DVertexDeclaration9 *decl;
4863     HRESULT hr;
4864     DWORD color;
4865     DWORD shader_code_11[] =  {
4866         0xfffe0101,                                         /* vs_1_1           */
4867         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4868         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4869         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4870         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4871         0x0000ffff                                          /* end              */
4872     };
4873     DWORD shader_code_11_2[] =  {
4874         0xfffe0101,                                         /* vs_1_1           */
4875         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4876         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4877         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4878         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4879         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4880         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4881         0x0000ffff                                          /* end              */
4882     };
4883     DWORD shader_code_20[] =  {
4884         0xfffe0200,                                         /* vs_2_0           */
4885         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4886         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4887         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4888         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4889         0x0000ffff                                          /* end              */
4890     };
4891     DWORD shader_code_20_2[] =  {
4892         0xfffe0200,                                         /* vs_2_0           */
4893         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4894         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4895         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4896         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4897         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4898         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4899         0x0000ffff                                          /* end              */
4900     };
4901     static const D3DVERTEXELEMENT9 decl_elements[] = {
4902         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4903         D3DDECL_END()
4904     };
4905     float quad1[] = {
4906         -1.0,   -1.0,   0.1,
4907          0.0,   -1.0,   0.1,
4908         -1.0,    0.0,   0.1,
4909          0.0,    0.0,   0.1
4910     };
4911     float quad2[] = {
4912          0.0,   -1.0,   0.1,
4913          1.0,   -1.0,   0.1,
4914          0.0,    0.0,   0.1,
4915          1.0,    0.0,   0.1
4916     };
4917     float quad3[] = {
4918          0.0,    0.0,   0.1,
4919          1.0,    0.0,   0.1,
4920          0.0,    1.0,   0.1,
4921          1.0,    1.0,   0.1
4922     };
4923     float quad4[] = {
4924         -1.0,    0.0,   0.1,
4925          0.0,    0.0,   0.1,
4926         -1.0,    1.0,   0.1,
4927          0.0,    1.0,   0.1
4928     };
4929     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4930     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4931
4932     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4933     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4934
4935     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4936     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4937     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4938     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4939     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4940     if(FAILED(hr)) shader_20 = NULL;
4941     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4942     if(FAILED(hr)) shader_20_2 = NULL;
4943     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4944     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4945
4946     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4947     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4948     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4949     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4950     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4951     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4952
4953     hr = IDirect3DDevice9_BeginScene(device);
4954     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4955     if(SUCCEEDED(hr))
4956     {
4957         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4958         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4959         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4960         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4961
4962         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4963         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4964         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4965         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4966
4967         if(shader_20) {
4968             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4969             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4970             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4971             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4972         }
4973
4974         if(shader_20_2) {
4975             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4976             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4977             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4978             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4979         }
4980
4981         hr = IDirect3DDevice9_EndScene(device);
4982         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4983     }
4984
4985     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4986     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4987     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4988     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4989
4990     color = getPixelColor(device, 160, 360);
4991     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4992        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4993     color = getPixelColor(device, 480, 360);
4994     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4995        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4996     if(shader_20) {
4997         color = getPixelColor(device, 480, 120);
4998         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4999            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
5000     }
5001     if(shader_20_2) {
5002         color = getPixelColor(device, 160, 120);
5003         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5004            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5005     }
5006     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5007     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5008
5009     IDirect3DVertexDeclaration9_Release(decl);
5010     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
5011     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
5012     IDirect3DVertexShader9_Release(shader_11_2);
5013     IDirect3DVertexShader9_Release(shader_11);
5014 }
5015
5016 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
5017 {
5018     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
5019     HRESULT hr;
5020     DWORD color;
5021     DWORD shader_code_11[] =  {
5022         0xffff0101,                                         /* ps_1_1           */
5023         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5024         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5025         0x0000ffff                                          /* end              */
5026     };
5027     DWORD shader_code_12[] =  {
5028         0xffff0102,                                         /* ps_1_2           */
5029         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5030         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5031         0x0000ffff                                          /* end              */
5032     };
5033     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
5034      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
5035      * During development of this test, 1.3 shaders were verified too
5036      */
5037     DWORD shader_code_14[] =  {
5038         0xffff0104,                                         /* ps_1_4           */
5039         /* Try to make one constant local. It gets clamped too, although the binary contains
5040          * the bigger numbers
5041          */
5042         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
5043         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5044         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5045         0x0000ffff                                          /* end              */
5046     };
5047     DWORD shader_code_20[] =  {
5048         0xffff0200,                                         /* ps_2_0           */
5049         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5050         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5051         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
5052         0x0000ffff                                          /* end              */
5053     };
5054     float quad1[] = {
5055         -1.0,   -1.0,   0.1,
5056          0.0,   -1.0,   0.1,
5057         -1.0,    0.0,   0.1,
5058          0.0,    0.0,   0.1
5059     };
5060     float quad2[] = {
5061          0.0,   -1.0,   0.1,
5062          1.0,   -1.0,   0.1,
5063          0.0,    0.0,   0.1,
5064          1.0,    0.0,   0.1
5065     };
5066     float quad3[] = {
5067          0.0,    0.0,   0.1,
5068          1.0,    0.0,   0.1,
5069          0.0,    1.0,   0.1,
5070          1.0,    1.0,   0.1
5071     };
5072     float quad4[] = {
5073         -1.0,    0.0,   0.1,
5074          0.0,    0.0,   0.1,
5075         -1.0,    1.0,   0.1,
5076          0.0,    1.0,   0.1
5077     };
5078     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
5079     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
5080
5081     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5082     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5083
5084     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5085     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5086     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5087     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5088     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5089     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5090     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
5091     if(FAILED(hr)) shader_20 = NULL;
5092
5093     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5094     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5095     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5096     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5097     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5098     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5099
5100     hr = IDirect3DDevice9_BeginScene(device);
5101     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5102     if(SUCCEEDED(hr))
5103     {
5104         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5105         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5106         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5107         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5108
5109         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5110         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5111         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5112         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5113
5114         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5115         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5116         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5117         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5118
5119         if(shader_20) {
5120             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
5121             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5122             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
5123             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5124         }
5125
5126         hr = IDirect3DDevice9_EndScene(device);
5127         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5128     }
5129     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5130     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5131
5132     color = getPixelColor(device, 160, 360);
5133     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5134        "quad 1 has color %08x, expected 0x00808000\n", color);
5135     color = getPixelColor(device, 480, 360);
5136     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5137        "quad 2 has color %08x, expected 0x00808000\n", color);
5138     color = getPixelColor(device, 480, 120);
5139     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5140        "quad 3 has color %08x, expected 0x00808000\n", color);
5141     if(shader_20) {
5142         color = getPixelColor(device, 160, 120);
5143         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5144            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5145     }
5146     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5147     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5148
5149     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
5150     IDirect3DPixelShader9_Release(shader_14);
5151     IDirect3DPixelShader9_Release(shader_12);
5152     IDirect3DPixelShader9_Release(shader_11);
5153 }
5154
5155 static void dp2add_ps_test(IDirect3DDevice9 *device)
5156 {
5157     IDirect3DPixelShader9 *shader_dp2add = NULL;
5158     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
5159     HRESULT hr;
5160     DWORD color;
5161
5162     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
5163      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
5164      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
5165      * r0 first.
5166      * The result here for the r,g,b components should be roughly 0.5:
5167      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
5168     static const DWORD shader_code_dp2add[] =  {
5169         0xffff0200,                                                             /* ps_2_0                       */
5170         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
5171
5172         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5173         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
5174
5175         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
5176         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5177         0x0000ffff                                                              /* end                          */
5178     };
5179
5180     /* Test the _sat modifier, too.  Result here should be:
5181      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
5182      *      _SAT: ==> 1.0
5183      *   ADD: (1.0 + -0.5) = 0.5
5184      */
5185     static const DWORD shader_code_dp2add_sat[] =  {
5186         0xffff0200,                                                             /* ps_2_0                           */
5187         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
5188
5189         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
5190         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
5191         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
5192
5193         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
5194         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
5195         0x0000ffff                                                              /* end                              */
5196     };
5197
5198     const float quad[] = {
5199         -1.0,   -1.0,   0.1,
5200          1.0,   -1.0,   0.1,
5201         -1.0,    1.0,   0.1,
5202          1.0,    1.0,   0.1
5203     };
5204
5205
5206     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
5207     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5208
5209     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
5210     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5211
5212     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
5213     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5214
5215     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5216     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5217
5218     if (shader_dp2add) {
5219
5220         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5221         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5222
5223         hr = IDirect3DDevice9_BeginScene(device);
5224         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5225         if(SUCCEEDED(hr))
5226         {
5227             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5228             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5229
5230             hr = IDirect3DDevice9_EndScene(device);
5231             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5232         }
5233
5234         color = getPixelColor(device, 360, 240);
5235         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5236                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5237
5238         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5239         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5240
5241         IDirect3DPixelShader9_Release(shader_dp2add);
5242     } else {
5243         skip("dp2add shader creation failed\n");
5244     }
5245
5246     if (shader_dp2add_sat) {
5247
5248         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5249         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5250
5251         hr = IDirect3DDevice9_BeginScene(device);
5252         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5253         if(SUCCEEDED(hr))
5254         {
5255             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5256             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5257
5258             hr = IDirect3DDevice9_EndScene(device);
5259             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5260         }
5261
5262         color = getPixelColor(device, 360, 240);
5263         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5264                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5265
5266         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5267         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5268
5269         IDirect3DPixelShader9_Release(shader_dp2add_sat);
5270     } else {
5271         skip("dp2add shader creation failed\n");
5272     }
5273
5274     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5275     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5276 }
5277
5278 static void cnd_test(IDirect3DDevice9 *device)
5279 {
5280     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
5281     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
5282     HRESULT hr;
5283     DWORD color;
5284     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
5285      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
5286      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
5287      */
5288     DWORD shader_code_11[] =  {
5289         0xffff0101,                                                                 /* ps_1_1               */
5290         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5291         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5292         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
5293         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5294         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5295         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5296         0x0000ffff                                                                  /* end                  */
5297     };
5298     DWORD shader_code_12[] =  {
5299         0xffff0102,                                                                 /* ps_1_2               */
5300         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5301         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5302         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5303         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5304         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5305         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5306         0x0000ffff                                                                  /* end                  */
5307     };
5308     DWORD shader_code_13[] =  {
5309         0xffff0103,                                                                 /* ps_1_3               */
5310         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5311         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5312         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5313         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
5314         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5315         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5316         0x0000ffff                                                                  /* end                  */
5317     };
5318     DWORD shader_code_14[] =  {
5319         0xffff0104,                                                                 /* ps_1_3               */
5320         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
5321         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
5322         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
5323         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
5324         0x0000ffff                                                                  /* end                  */
5325     };
5326
5327     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
5328      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
5329      * set by the compiler, it was added manually after compilation. Note that the COISSUE
5330      * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
5331      * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
5332      * well enough.
5333      *
5334      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
5335      * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
5336      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
5337      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
5338      */
5339     DWORD shader_code_11_coissue[] =  {
5340         0xffff0101,                                                             /* ps_1_1                   */
5341         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5342         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5343         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5344         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5345         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5346         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5347         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5348         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5349         /* 0x40000000 = D3DSI_COISSUE */
5350         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5351         0x0000ffff                                                              /* end                      */
5352     };
5353     DWORD shader_code_12_coissue[] =  {
5354         0xffff0102,                                                             /* ps_1_2                   */
5355         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5356         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5357         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5358         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5359         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5360         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5361         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5362         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5363         /* 0x40000000 = D3DSI_COISSUE */
5364         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5365         0x0000ffff                                                              /* end                      */
5366     };
5367     DWORD shader_code_13_coissue[] =  {
5368         0xffff0103,                                                             /* ps_1_3                   */
5369         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5370         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5371         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5372         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5373         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5374         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5375         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5376         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5377         /* 0x40000000 = D3DSI_COISSUE */
5378         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5379         0x0000ffff                                                              /* end                      */
5380     };
5381     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
5382      * compare against 0.5
5383      */
5384     DWORD shader_code_14_coissue[] =  {
5385         0xffff0104,                                                             /* ps_1_4                   */
5386         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
5387         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
5388         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
5389         /* 0x40000000 = D3DSI_COISSUE */
5390         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
5391         0x0000ffff                                                              /* end                      */
5392     };
5393     float quad1[] = {
5394         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5395          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5396         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5397          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
5398     };
5399     float quad2[] = {
5400          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5401          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5402          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5403          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
5404     };
5405     float quad3[] = {
5406          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5407          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5408          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5409          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
5410     };
5411     float quad4[] = {
5412         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5413          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5414         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5415          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
5416     };
5417     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
5418     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
5419     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
5420     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
5421
5422     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5423     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5424
5425     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5426     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5427     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5428     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5429     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
5430     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5431     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5432     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5433     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
5434     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5435     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5436     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5437     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5438     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5439     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5440     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5441
5442     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5443     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5444     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5445     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5446     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5447     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5448
5449     hr = IDirect3DDevice9_BeginScene(device);
5450     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5451     if(SUCCEEDED(hr))
5452     {
5453         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5454         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5455         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5456         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5457
5458         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5459         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5460         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5461         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5462
5463         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5464         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5465         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5466         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5467
5468         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5469         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5470         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5471         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5472
5473         hr = IDirect3DDevice9_EndScene(device);
5474         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5475     }
5476
5477     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5478     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5479
5480     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5481     color = getPixelColor(device, 158, 118);
5482     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5483     color = getPixelColor(device, 162, 118);
5484     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5485     color = getPixelColor(device, 158, 122);
5486     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5487     color = getPixelColor(device, 162, 122);
5488     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5489
5490     /* 1.1 shader. All 3 components get set, based on the .w comparison */
5491     color = getPixelColor(device, 158, 358);
5492     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5493     color = getPixelColor(device, 162, 358);
5494     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5495         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5496     color = getPixelColor(device, 158, 362);
5497     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5498     color = getPixelColor(device, 162, 362);
5499     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5500         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5501
5502     /* 1.2 shader */
5503     color = getPixelColor(device, 478, 358);
5504     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5505     color = getPixelColor(device, 482, 358);
5506     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5507         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5508     color = getPixelColor(device, 478, 362);
5509     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5510     color = getPixelColor(device, 482, 362);
5511     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5512         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5513
5514     /* 1.3 shader */
5515     color = getPixelColor(device, 478, 118);
5516     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5517     color = getPixelColor(device, 482, 118);
5518     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5519         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5520     color = getPixelColor(device, 478, 122);
5521     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5522     color = getPixelColor(device, 482, 122);
5523     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5524         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5525
5526     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5527     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5528
5529     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5530     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5531     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5532     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5533     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5534     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5535
5536     hr = IDirect3DDevice9_BeginScene(device);
5537     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5538     if(SUCCEEDED(hr))
5539     {
5540         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5541         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5542         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5543         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5544
5545         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5546         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5547         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5548         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5549
5550         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5551         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5552         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5553         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5554
5555         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5556         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5557         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5558         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5559
5560         hr = IDirect3DDevice9_EndScene(device);
5561         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5562     }
5563
5564     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5565     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5566
5567     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5568      * that we swapped the values in c1 and c2 to make the other tests return some color
5569      */
5570     color = getPixelColor(device, 158, 118);
5571     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5572     color = getPixelColor(device, 162, 118);
5573     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5574     color = getPixelColor(device, 158, 122);
5575     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5576     color = getPixelColor(device, 162, 122);
5577     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5578
5579     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
5580      * (The Win7 nvidia driver always selects c2)
5581      */
5582     color = getPixelColor(device, 158, 358);
5583     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5584         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5585     color = getPixelColor(device, 162, 358);
5586     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5587         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5588     color = getPixelColor(device, 158, 362);
5589     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5590         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5591     color = getPixelColor(device, 162, 362);
5592     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5593         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5594
5595     /* 1.2 shader */
5596     color = getPixelColor(device, 478, 358);
5597     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5598         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5599     color = getPixelColor(device, 482, 358);
5600     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5601         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5602     color = getPixelColor(device, 478, 362);
5603     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5604         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5605     color = getPixelColor(device, 482, 362);
5606     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5607         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5608
5609     /* 1.3 shader */
5610     color = getPixelColor(device, 478, 118);
5611     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5612         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5613     color = getPixelColor(device, 482, 118);
5614     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5615         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5616     color = getPixelColor(device, 478, 122);
5617     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5618         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5619     color = getPixelColor(device, 482, 122);
5620     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5621         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5622
5623     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5624     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5625
5626     IDirect3DPixelShader9_Release(shader_14_coissue);
5627     IDirect3DPixelShader9_Release(shader_13_coissue);
5628     IDirect3DPixelShader9_Release(shader_12_coissue);
5629     IDirect3DPixelShader9_Release(shader_11_coissue);
5630     IDirect3DPixelShader9_Release(shader_14);
5631     IDirect3DPixelShader9_Release(shader_13);
5632     IDirect3DPixelShader9_Release(shader_12);
5633     IDirect3DPixelShader9_Release(shader_11);
5634 }
5635
5636 static void nested_loop_test(IDirect3DDevice9 *device) {
5637     const DWORD shader_code[] = {
5638         0xffff0300,                                                             /* ps_3_0               */
5639         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
5640         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5641         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
5642         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
5643         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5644         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5645         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
5646         0x0000001d,                                                             /* endloop              */
5647         0x0000001d,                                                             /* endloop              */
5648         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
5649         0x0000ffff                                                              /* end                  */
5650     };
5651     const DWORD vshader_code[] = {
5652         0xfffe0300,                                                             /* vs_3_0               */
5653         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
5654         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
5655         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
5656         0x0000ffff                                                              /* end                  */
5657     };
5658     IDirect3DPixelShader9 *shader;
5659     IDirect3DVertexShader9 *vshader;
5660     HRESULT hr;
5661     DWORD color;
5662     const float quad[] = {
5663         -1.0,   -1.0,   0.1,
5664          1.0,   -1.0,   0.1,
5665         -1.0,    1.0,   0.1,
5666          1.0,    1.0,   0.1
5667     };
5668
5669     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5670     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5671     hr = IDirect3DDevice9_SetPixelShader(device, shader);
5672     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5673     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
5674     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
5675     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
5676     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5677     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5678     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5679     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5680     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5681
5682     hr = IDirect3DDevice9_BeginScene(device);
5683     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5684     if(SUCCEEDED(hr))
5685     {
5686         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5687         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5688         hr = IDirect3DDevice9_EndScene(device);
5689         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5690     }
5691
5692     color = getPixelColor(device, 360, 240);
5693     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5694        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5695
5696     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5697     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5698
5699     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5700     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5701     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5702     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5703     IDirect3DPixelShader9_Release(shader);
5704     IDirect3DVertexShader9_Release(vshader);
5705 }
5706
5707 struct varying_test_struct
5708 {
5709     const DWORD             *shader_code;
5710     IDirect3DPixelShader9   *shader;
5711     DWORD                   color, color_rhw;
5712     const char              *name;
5713     BOOL                    todo, todo_rhw;
5714 };
5715
5716 struct hugeVertex
5717 {
5718     float pos_x,        pos_y,      pos_z,      rhw;
5719     float weight_1,     weight_2,   weight_3,   weight_4;
5720     float index_1,      index_2,    index_3,    index_4;
5721     float normal_1,     normal_2,   normal_3,   normal_4;
5722     float fog_1,        fog_2,      fog_3,      fog_4;
5723     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
5724     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
5725     float binormal_1,   binormal_2, binormal_3, binormal_4;
5726     float depth_1,      depth_2,    depth_3,    depth_4;
5727     DWORD diffuse, specular;
5728 };
5729
5730 static void pretransformed_varying_test(IDirect3DDevice9 *device) {
5731     /* dcl_position: fails to compile */
5732     const DWORD blendweight_code[] = {
5733         0xffff0300,                             /* ps_3_0                   */
5734         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
5735         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5736         0x0000ffff                              /* end                      */
5737     };
5738     const DWORD blendindices_code[] = {
5739         0xffff0300,                             /* ps_3_0                   */
5740         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
5741         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5742         0x0000ffff                              /* end                      */
5743     };
5744     const DWORD normal_code[] = {
5745         0xffff0300,                             /* ps_3_0                   */
5746         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
5747         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5748         0x0000ffff                              /* end                      */
5749     };
5750     /* psize: fails? */
5751     const DWORD texcoord0_code[] = {
5752         0xffff0300,                             /* ps_3_0                   */
5753         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
5754         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5755         0x0000ffff                              /* end                      */
5756     };
5757     const DWORD tangent_code[] = {
5758         0xffff0300,                             /* ps_3_0                   */
5759         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
5760         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5761         0x0000ffff                              /* end                      */
5762     };
5763     const DWORD binormal_code[] = {
5764         0xffff0300,                             /* ps_3_0                   */
5765         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
5766         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5767         0x0000ffff                              /* end                      */
5768     };
5769     /* tessfactor: fails */
5770     /* positiont: fails */
5771     const DWORD color_code[] = {
5772         0xffff0300,                             /* ps_3_0                   */
5773         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
5774         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5775         0x0000ffff                              /* end                      */
5776     };
5777     const DWORD fog_code[] = {
5778         0xffff0300,                             /* ps_3_0                   */
5779         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
5780         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5781         0x0000ffff                              /* end                      */
5782     };
5783     const DWORD depth_code[] = {
5784         0xffff0300,                             /* ps_3_0                   */
5785         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
5786         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5787         0x0000ffff                              /* end                      */
5788     };
5789     const DWORD specular_code[] = {
5790         0xffff0300,                             /* ps_3_0                   */
5791         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
5792         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5793         0x0000ffff                              /* end                      */
5794     };
5795     /* sample: fails */
5796
5797     struct varying_test_struct tests[] = {
5798        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
5799        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
5800        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
5801        /* Why does dx not forward the texcoord? */
5802        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
5803        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
5804        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
5805        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
5806        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
5807        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
5808        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
5809     };
5810     /* Declare a monster vertex type :-) */
5811     static const D3DVERTEXELEMENT9 decl_elements[] = {
5812         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
5813         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5814         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5815         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5816         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5817         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5818         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5819         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5820         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5821         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5822         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5823         D3DDECL_END()
5824     };
5825     struct hugeVertex data[4] = {
5826         {
5827             -1.0,   -1.0,   0.1,    1.0,
5828              0.1,    0.1,   0.1,    0.1,
5829              0.2,    0.2,   0.2,    0.2,
5830              0.3,    0.3,   0.3,    0.3,
5831              0.4,    0.4,   0.4,    0.4,
5832              0.50,   0.55,  0.55,   0.55,
5833              0.6,    0.6,   0.6,    0.7,
5834              0.7,    0.7,   0.7,    0.6,
5835              0.8,    0.8,   0.8,    0.8,
5836              0xe6e6e6e6, /* 0.9 * 256 */
5837              0x224488ff  /* Nothing special */
5838         },
5839         {
5840              1.0,   -1.0,   0.1,    1.0,
5841              0.1,    0.1,   0.1,    0.1,
5842              0.2,    0.2,   0.2,    0.2,
5843              0.3,    0.3,   0.3,    0.3,
5844              0.4,    0.4,   0.4,    0.4,
5845              0.50,   0.55,  0.55,   0.55,
5846              0.6,    0.6,   0.6,    0.7,
5847              0.7,    0.7,   0.7,    0.6,
5848              0.8,    0.8,   0.8,    0.8,
5849              0xe6e6e6e6, /* 0.9 * 256 */
5850              0x224488ff /* Nothing special */
5851         },
5852         {
5853             -1.0,    1.0,   0.1,    1.0,
5854              0.1,    0.1,   0.1,    0.1,
5855              0.2,    0.2,   0.2,    0.2,
5856              0.3,    0.3,   0.3,    0.3,
5857              0.4,    0.4,   0.4,    0.4,
5858              0.50,   0.55,  0.55,   0.55,
5859              0.6,    0.6,   0.6,    0.7,
5860              0.7,    0.7,   0.7,    0.6,
5861              0.8,    0.8,   0.8,    0.8,
5862              0xe6e6e6e6, /* 0.9 * 256 */
5863              0x224488ff /* Nothing special */
5864         },
5865         {
5866              1.0,    1.0,   0.1,    1.0,
5867              0.1,    0.1,   0.1,    0.1,
5868              0.2,    0.2,   0.2,    0.2,
5869              0.3,    0.3,   0.3,    0.3,
5870              0.4,    0.4,   0.4,    0.4,
5871              0.50,   0.55,  0.55,   0.55,
5872              0.6,    0.6,   0.6,    0.7,
5873              0.7,    0.7,   0.7,    0.6,
5874              0.8,    0.8,   0.8,    0.8,
5875              0xe6e6e6e6, /* 0.9 * 256 */
5876              0x224488ff /* Nothing special */
5877         },
5878     };
5879     struct hugeVertex data2[4];
5880     IDirect3DVertexDeclaration9 *decl;
5881     HRESULT hr;
5882     unsigned int i;
5883     DWORD color, r, g, b, r_e, g_e, b_e;
5884
5885     memcpy(data2, data, sizeof(data2));
5886     data2[0].pos_x = 0;     data2[0].pos_y = 0;
5887     data2[1].pos_x = 640;   data2[1].pos_y = 0;
5888     data2[2].pos_x = 0;     data2[2].pos_y = 480;
5889     data2[3].pos_x = 640;   data2[3].pos_y = 480;
5890
5891     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5892     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5893     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5894     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5895
5896     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5897     {
5898         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5899         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5900            tests[i].name, hr);
5901     }
5902
5903     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5904     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5905     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5906     {
5907         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5908         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5909
5910         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5911         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5912
5913         hr = IDirect3DDevice9_BeginScene(device);
5914         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5915         if(SUCCEEDED(hr))
5916         {
5917             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5918             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5919             hr = IDirect3DDevice9_EndScene(device);
5920             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5921         }
5922
5923         color = getPixelColor(device, 360, 240);
5924         r = color & 0x00ff0000 >> 16;
5925         g = color & 0x0000ff00 >>  8;
5926         b = color & 0x000000ff;
5927         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5928         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
5929         b_e = tests[i].color_rhw & 0x000000ff;
5930
5931         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5932         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5933
5934         if(tests[i].todo_rhw) {
5935             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5936              * pipeline
5937              */
5938             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5939                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5940                          tests[i].name, color, tests[i].color_rhw);
5941         } else {
5942             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5943                "Test %s returned color 0x%08x, expected 0x%08x\n",
5944                tests[i].name, color, tests[i].color_rhw);
5945         }
5946     }
5947
5948     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5949     {
5950         IDirect3DPixelShader9_Release(tests[i].shader);
5951     }
5952
5953     IDirect3DVertexDeclaration9_Release(decl);
5954 }
5955
5956 static void test_compare_instructions(IDirect3DDevice9 *device)
5957 {
5958     DWORD shader_sge_vec_code[] = {
5959         0xfffe0101,                                         /* vs_1_1                   */
5960         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5961         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5962         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5963         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
5964         0x0000ffff                                          /* end                      */
5965     };
5966     DWORD shader_slt_vec_code[] = {
5967         0xfffe0101,                                         /* vs_1_1                   */
5968         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5969         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5970         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5971         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
5972         0x0000ffff                                          /* end                      */
5973     };
5974     DWORD shader_sge_scalar_code[] = {
5975         0xfffe0101,                                         /* vs_1_1                   */
5976         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5977         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5978         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5979         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
5980         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
5981         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
5982         0x0000ffff                                          /* end                      */
5983     };
5984     DWORD shader_slt_scalar_code[] = {
5985         0xfffe0101,                                         /* vs_1_1                   */
5986         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5987         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5988         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5989         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
5990         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
5991         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
5992         0x0000ffff                                          /* end                      */
5993     };
5994     IDirect3DVertexShader9 *shader_sge_vec;
5995     IDirect3DVertexShader9 *shader_slt_vec;
5996     IDirect3DVertexShader9 *shader_sge_scalar;
5997     IDirect3DVertexShader9 *shader_slt_scalar;
5998     HRESULT hr, color;
5999     float quad1[] =  {
6000         -1.0,   -1.0,   0.1,
6001          0.0,   -1.0,   0.1,
6002         -1.0,    0.0,   0.1,
6003          0.0,    0.0,   0.1
6004     };
6005     float quad2[] =  {
6006          0.0,   -1.0,   0.1,
6007          1.0,   -1.0,   0.1,
6008          0.0,    0.0,   0.1,
6009          1.0,    0.0,   0.1
6010     };
6011     float quad3[] =  {
6012         -1.0,    0.0,   0.1,
6013          0.0,    0.0,   0.1,
6014         -1.0,    1.0,   0.1,
6015          0.0,    1.0,   0.1
6016     };
6017     float quad4[] =  {
6018          0.0,    0.0,   0.1,
6019          1.0,    0.0,   0.1,
6020          0.0,    1.0,   0.1,
6021          1.0,    1.0,   0.1
6022     };
6023     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
6024     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
6025
6026     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6027     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6028
6029     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
6030     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6031     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
6032     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6033     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
6034     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6035     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
6036     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6037     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6038     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6039     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
6040     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6041     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6042     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
6043
6044     hr = IDirect3DDevice9_BeginScene(device);
6045     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6046     if(SUCCEEDED(hr))
6047     {
6048         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
6049         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6050         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6051         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6052
6053         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
6054         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6055         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
6056         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6057
6058         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
6059         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6060         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6061         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6062
6063         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6064         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6065
6066         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
6067         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6068         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6069         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6070
6071         hr = IDirect3DDevice9_EndScene(device);
6072         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6073     }
6074
6075     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6076     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6077
6078     color = getPixelColor(device, 160, 360);
6079     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
6080     color = getPixelColor(device, 480, 360);
6081     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
6082     color = getPixelColor(device, 160, 120);
6083     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
6084     color = getPixelColor(device, 480, 160);
6085     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
6086
6087     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6088     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6089
6090     IDirect3DVertexShader9_Release(shader_sge_vec);
6091     IDirect3DVertexShader9_Release(shader_slt_vec);
6092     IDirect3DVertexShader9_Release(shader_sge_scalar);
6093     IDirect3DVertexShader9_Release(shader_slt_scalar);
6094 }
6095
6096 static void test_vshader_input(IDirect3DDevice9 *device)
6097 {
6098     static const DWORD swapped_shader_code_3[] =
6099     {
6100         0xfffe0300,                                         /* vs_3_0               */
6101         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6102         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6103         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6104         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6105         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6106         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6107         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6108         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6109         0x0000ffff                                          /* end                  */
6110     };
6111     static const DWORD swapped_shader_code_1[] =
6112     {
6113         0xfffe0101,                                         /* vs_1_1               */
6114         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6115         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6116         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6117         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6118         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6119         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6120         0x0000ffff                                          /* end                  */
6121     };
6122     static const DWORD swapped_shader_code_2[] =
6123     {
6124         0xfffe0200,                                         /* vs_2_0               */
6125         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6126         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6127         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6128         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6129         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6130         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6131         0x0000ffff                                          /* end                  */
6132     };
6133     static const DWORD texcoord_color_shader_code_3[] =
6134     {
6135         0xfffe0300,                                         /* vs_3_0               */
6136         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6137         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6138         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6139         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6140         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6141         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
6142         0x0000ffff                                          /* end                  */
6143     };
6144     static const DWORD texcoord_color_shader_code_2[] =
6145     {
6146         0xfffe0200,                                         /* vs_2_0               */
6147         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6148         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6149         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6150         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6151         0x0000ffff                                          /* end                  */
6152     };
6153     static const DWORD texcoord_color_shader_code_1[] =
6154     {
6155         0xfffe0101,                                         /* vs_1_1               */
6156         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6157         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6158         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6159         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6160         0x0000ffff                                          /* end                  */
6161     };
6162     static const DWORD color_color_shader_code_3[] =
6163     {
6164         0xfffe0300,                                         /* vs_3_0               */
6165         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6166         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6167         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6168         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6169         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6170         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
6171         0x0000ffff                                          /* end                  */
6172     };
6173     static const DWORD color_color_shader_code_2[] =
6174     {
6175         0xfffe0200,                                         /* vs_2_0               */
6176         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6177         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6178         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6179         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1      */
6180         0x0000ffff                                          /* end                  */
6181     };
6182     static const DWORD color_color_shader_code_1[] =
6183     {
6184         0xfffe0101,                                         /* vs_1_1               */
6185         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6186         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6187         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6188         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1      */
6189         0x0000ffff                                          /* end                  */
6190     };
6191     static const DWORD ps3_code[] =
6192     {
6193         0xffff0300,                                         /* ps_3_0               */
6194         0x0200001f, 0x8000000a, 0x900f0000,                 /* dcl_color0 v0        */
6195         0x02000001, 0x800f0800, 0x90e40000,                 /* mov oC0, v0          */
6196         0x0000ffff                                          /* end                  */
6197     };
6198     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6199     IDirect3DPixelShader9 *ps;
6200     HRESULT hr;
6201     DWORD color;
6202     float quad1[] =  {
6203         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6204          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6205         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6206          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6207     };
6208     float quad2[] =  {
6209          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6210          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6211          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6212          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6213     };
6214     float quad3[] =  {
6215         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
6216          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
6217         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
6218          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6219     };
6220     float quad4[] =  {
6221          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6222          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6223          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6224          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6225     };
6226     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6227         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6228         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6229         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6230         D3DDECL_END()
6231     };
6232     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6233         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6234         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6235         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6236         D3DDECL_END()
6237     };
6238     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6239         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6240         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6241         D3DDECL_END()
6242     };
6243     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6244         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6245         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6246         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
6247         D3DDECL_END()
6248     };
6249     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6250         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6251         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6252         D3DDECL_END()
6253     };
6254     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6255         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6256         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6257         D3DDECL_END()
6258     };
6259     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6260         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6261         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6262         D3DDECL_END()
6263     };
6264     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6265         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6266         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6267         D3DDECL_END()
6268     };
6269     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6270     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6271     unsigned int i;
6272     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6273     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6274
6275     struct vertex quad1_color[] =  {
6276        {-1.0,   -1.0,   0.1,    0x00ff8040},
6277        { 0.0,   -1.0,   0.1,    0x00ff8040},
6278        {-1.0,    0.0,   0.1,    0x00ff8040},
6279        { 0.0,    0.0,   0.1,    0x00ff8040}
6280     };
6281     struct vertex quad2_color[] =  {
6282        { 0.0,   -1.0,   0.1,    0x00ff8040},
6283        { 1.0,   -1.0,   0.1,    0x00ff8040},
6284        { 0.0,    0.0,   0.1,    0x00ff8040},
6285        { 1.0,    0.0,   0.1,    0x00ff8040}
6286     };
6287     struct vertex quad3_color[] =  {
6288        {-1.0,    0.0,   0.1,    0x00ff8040},
6289        { 0.0,    0.0,   0.1,    0x00ff8040},
6290        {-1.0,    1.0,   0.1,    0x00ff8040},
6291        { 0.0,    1.0,   0.1,    0x00ff8040}
6292     };
6293     float quad4_color[] =  {
6294          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6295          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6296          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6297          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6298     };
6299
6300     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6301     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6302     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6303     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6304     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6305     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6306     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6307     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6308
6309     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6310     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6311     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6312     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6313     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6314     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6315     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6316     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6317
6318     hr = IDirect3DDevice9_CreatePixelShader(device, ps3_code, &ps);
6319     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6320
6321     for(i = 1; i <= 3; i++) {
6322         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6323         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6324         if(i == 3) {
6325             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6326             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6327             hr = IDirect3DDevice9_SetPixelShader(device, ps);
6328             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6329         } else if(i == 2){
6330             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6331             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6332         } else if(i == 1) {
6333             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6334             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6335         }
6336
6337         hr = IDirect3DDevice9_BeginScene(device);
6338         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6339         if(SUCCEEDED(hr))
6340         {
6341             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6342             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6343
6344             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6345             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6346             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6347             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6348
6349             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6350             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6351             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6352             if(i == 3 || i == 2) {
6353                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6354             } else if(i == 1) {
6355                 /* Succeeds or fails, depending on SW or HW vertex processing */
6356                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6357             }
6358
6359             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6360             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6361             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6362             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6363
6364             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6365             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6366             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6367             if(i == 3 || i == 2) {
6368                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6369             } else if(i == 1) {
6370                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6371             }
6372
6373             hr = IDirect3DDevice9_EndScene(device);
6374             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6375         }
6376
6377         if(i == 3 || i == 2) {
6378             color = getPixelColor(device, 160, 360);
6379             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6380                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6381
6382             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6383             color = getPixelColor(device, 480, 360);
6384             ok(color == 0x00FFFF00 || color ==0x00FF0000,
6385                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6386             color = getPixelColor(device, 160, 120);
6387             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6388             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6389                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6390
6391             color = getPixelColor(device, 480, 160);
6392             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6393         } else if(i == 1) {
6394             color = getPixelColor(device, 160, 360);
6395             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6396                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6397             color = getPixelColor(device, 480, 360);
6398             /* Accept the clear color as well in this case, since SW VP returns an error */
6399             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6400             color = getPixelColor(device, 160, 120);
6401             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6402                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6403             color = getPixelColor(device, 480, 160);
6404             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6405         }
6406
6407         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6408         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6409
6410         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6411         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6412
6413         /* Now find out if the whole streams are re-read, or just the last active value for the
6414          * vertices is used.
6415          */
6416         hr = IDirect3DDevice9_BeginScene(device);
6417         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6418         if(SUCCEEDED(hr))
6419         {
6420             float quad1_modified[] =  {
6421                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6422                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6423                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6424                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6425             };
6426             float quad2_modified[] =  {
6427                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6428                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6429                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6430                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6431             };
6432
6433             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6434             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6435
6436             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6437             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6438             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6439             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6440
6441             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6442             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6443             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6444             if(i == 3 || i == 2) {
6445                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6446             } else if(i == 1) {
6447                 /* Succeeds or fails, depending on SW or HW vertex processing */
6448                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6449             }
6450
6451             hr = IDirect3DDevice9_EndScene(device);
6452             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6453         }
6454
6455         color = getPixelColor(device, 480, 350);
6456         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6457          * as well.
6458          *
6459          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6460          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6461          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6462          * refrast's result.
6463          *
6464          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6465          */
6466         ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6467            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6468
6469         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6470         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6471
6472         IDirect3DDevice9_SetVertexShader(device, NULL);
6473         IDirect3DDevice9_SetPixelShader(device, NULL);
6474         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6475
6476         IDirect3DVertexShader9_Release(swapped_shader);
6477     }
6478
6479     for(i = 1; i <= 3; i++) {
6480         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6481         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6482         if(i == 3) {
6483             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6484             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6485             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6486             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6487             hr = IDirect3DDevice9_SetPixelShader(device, ps);
6488             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6489         } else if(i == 2){
6490             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6491             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6492             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6493             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6494         } else if(i == 1) {
6495             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6496             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6497             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6498             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6499         }
6500
6501         hr = IDirect3DDevice9_BeginScene(device);
6502         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6503         if(SUCCEEDED(hr))
6504         {
6505             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6506             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6507             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6508             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6509             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6510             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6511
6512             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6513             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6514
6515             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6516             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6517             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6518             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6519             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6520             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6521
6522             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6523             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6524             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6525             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6526             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6527             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6528
6529             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6530             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6531             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6532             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6533
6534             hr = IDirect3DDevice9_EndScene(device);
6535             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6536         }
6537         IDirect3DDevice9_SetVertexShader(device, NULL);
6538         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6539         IDirect3DDevice9_SetPixelShader(device, NULL);
6540
6541         color = getPixelColor(device, 160, 360);
6542         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6543            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6544         color = getPixelColor(device, 480, 360);
6545         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6546            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6547         color = getPixelColor(device, 160, 120);
6548         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6549            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6550         color = getPixelColor(device, 480, 160);
6551         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6552            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6553
6554         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6555         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6556
6557         IDirect3DVertexShader9_Release(texcoord_color_shader);
6558         IDirect3DVertexShader9_Release(color_color_shader);
6559     }
6560
6561     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6562     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6563     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6564     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6565
6566     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6567     IDirect3DVertexDeclaration9_Release(decl_color_color);
6568     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6569     IDirect3DVertexDeclaration9_Release(decl_color_float);
6570
6571     IDirect3DPixelShader9_Release(ps);
6572 }
6573
6574 static void srgbtexture_test(IDirect3DDevice9 *device)
6575 {
6576     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6577      * texture stage state to render a quad using that texture.  The resulting
6578      * color components should be 0x36 (~ 0.21), per this formula:
6579      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6580      * This is true where srgb_color > 0.04045.
6581      */
6582     IDirect3D9 *d3d = NULL;
6583     HRESULT hr;
6584     LPDIRECT3DTEXTURE9 texture = NULL;
6585     LPDIRECT3DSURFACE9 surface = NULL;
6586     D3DLOCKED_RECT lr;
6587     DWORD color;
6588     float quad[] = {
6589         -1.0,       1.0,       0.0,     0.0,    0.0,
6590          1.0,       1.0,       0.0,     1.0,    0.0,
6591         -1.0,      -1.0,       0.0,     0.0,    1.0,
6592          1.0,      -1.0,       0.0,     1.0,    1.0,
6593     };
6594
6595
6596     memset(&lr, 0, sizeof(lr));
6597     IDirect3DDevice9_GetDirect3D(device, &d3d);
6598     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6599                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6600                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6601         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6602         goto out;
6603     }
6604
6605     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6606                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6607                                         &texture, NULL);
6608     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6609     if(!texture) {
6610         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6611         goto out;
6612     }
6613     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6614     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6615
6616     fill_surface(surface, 0xff7f7f7f);
6617     IDirect3DSurface9_Release(surface);
6618
6619     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6620     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6621     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6622     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6623
6624     hr = IDirect3DDevice9_BeginScene(device);
6625     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6626     if(SUCCEEDED(hr))
6627     {
6628         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6629         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6630
6631         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6632         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6633
6634
6635         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6636         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6637
6638         hr = IDirect3DDevice9_EndScene(device);
6639         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6640     }
6641
6642     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6643     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6644     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6645     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6646
6647     color = getPixelColor(device, 320, 240);
6648     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6649
6650     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6651     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6652
6653 out:
6654     if(texture) IDirect3DTexture9_Release(texture);
6655     IDirect3D9_Release(d3d);
6656 }
6657
6658 static void shademode_test(IDirect3DDevice9 *device)
6659 {
6660     /* Render a quad and try all of the different fixed function shading models. */
6661     HRESULT hr;
6662     DWORD color0, color1;
6663     DWORD color0_gouraud = 0, color1_gouraud = 0;
6664     DWORD shademode = D3DSHADE_FLAT;
6665     DWORD primtype = D3DPT_TRIANGLESTRIP;
6666     LPVOID data = NULL;
6667     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6668     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6669     UINT i, j;
6670     struct vertex quad_strip[] =
6671     {
6672         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6673         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6674         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6675         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6676     };
6677     struct vertex quad_list[] =
6678     {
6679         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6680         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6681         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6682
6683         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6684         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6685         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6686     };
6687
6688     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6689                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6690     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6691     if (FAILED(hr)) goto bail;
6692
6693     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6694                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6695     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6696     if (FAILED(hr)) goto bail;
6697
6698     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6699     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6700
6701     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6702     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6703
6704     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6705     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6706     memcpy(data, quad_strip, sizeof(quad_strip));
6707     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6708     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6709
6710     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6711     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6712     memcpy(data, quad_list, sizeof(quad_list));
6713     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6714     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6715
6716     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
6717      * the color fixups we have to do for FLAT shading will be dependent on that. */
6718     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6719     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6720
6721     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6722     for (j=0; j<2; j++) {
6723
6724         /* Inner loop just changes the D3DRS_SHADEMODE */
6725         for (i=0; i<3; i++) {
6726             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6727             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6728
6729             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6730             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6731
6732             hr = IDirect3DDevice9_BeginScene(device);
6733             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6734             if(SUCCEEDED(hr))
6735             {
6736                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6737                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6738
6739                 hr = IDirect3DDevice9_EndScene(device);
6740                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6741             }
6742
6743             /* Sample two spots from the output */
6744             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6745             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6746             switch(shademode) {
6747                 case D3DSHADE_FLAT:
6748                     /* Should take the color of the first vertex of each triangle */
6749                     if (0)
6750                     {
6751                         /* This test depends on EXT_provoking_vertex being
6752                          * available. This extension is currently (20090810)
6753                          * not common enough to let the test fail if it isn't
6754                          * present. */
6755                         ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
6756                         ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
6757                     }
6758                     shademode = D3DSHADE_GOURAUD;
6759                     break;
6760                 case D3DSHADE_GOURAUD:
6761                     /* Should be an interpolated blend */
6762
6763                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6764                        "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6765                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6766                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6767
6768                     color0_gouraud = color0;
6769                     color1_gouraud = color1;
6770
6771                     shademode = D3DSHADE_PHONG;
6772                     break;
6773                 case D3DSHADE_PHONG:
6774                     /* Should be the same as GOURAUD, since no hardware implements this */
6775                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6776                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6777                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6778                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6779
6780                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6781                             color0_gouraud, color0);
6782                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6783                             color1_gouraud, color1);
6784                     break;
6785             }
6786         }
6787
6788         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6789         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6790
6791         /* Now, do it all over again with a TRIANGLELIST */
6792         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6793         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6794         primtype = D3DPT_TRIANGLELIST;
6795         shademode = D3DSHADE_FLAT;
6796     }
6797
6798 bail:
6799     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6800     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6801     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6802     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6803
6804     if (vb_strip)
6805         IDirect3DVertexBuffer9_Release(vb_strip);
6806     if (vb_list)
6807         IDirect3DVertexBuffer9_Release(vb_list);
6808 }
6809
6810 static void alpha_test(IDirect3DDevice9 *device)
6811 {
6812     HRESULT hr;
6813     IDirect3DTexture9 *offscreenTexture;
6814     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6815     DWORD color;
6816
6817     struct vertex quad1[] =
6818     {
6819         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
6820         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
6821         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
6822         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
6823     };
6824     struct vertex quad2[] =
6825     {
6826         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
6827         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
6828         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
6829         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
6830     };
6831     static const float composite_quad[][5] = {
6832         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6833         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
6834         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6835         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
6836     };
6837
6838     /* Clear the render target with alpha = 0.5 */
6839     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6840     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6841
6842     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6843     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6844
6845     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6846     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6847     if(!backbuffer) {
6848         goto out;
6849     }
6850
6851     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6852     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6853     if(!offscreen) {
6854         goto out;
6855     }
6856
6857     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6858     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6859
6860     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6861     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6862     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6863     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6864     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6865     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6866     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6867     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6868     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6869     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6870
6871     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6872     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6873     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6874
6875         /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6876         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6877         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6878         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6879         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6880         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6881         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6882
6883         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6884         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6885         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6886         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6887         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6888         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6889
6890         /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6891          * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6892          * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6893         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6894         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6895         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6896         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6897
6898         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6899         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6900         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6901         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6902         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6903         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6904
6905         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6906         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6907         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6908         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6909         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6910         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6911
6912         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6913         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6914
6915         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6916          * Disable alpha blending for the final composition
6917          */
6918         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6919         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6920         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6921         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6922
6923         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6924         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6925         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6926         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6927         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6928         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6929
6930         hr = IDirect3DDevice9_EndScene(device);
6931         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6932     }
6933
6934     color = getPixelColor(device, 160, 360);
6935     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6936        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6937
6938     color = getPixelColor(device, 160, 120);
6939     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
6940        "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
6941
6942     color = getPixelColor(device, 480, 360);
6943     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6944        "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
6945
6946     color = getPixelColor(device, 480, 120);
6947     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
6948        "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
6949
6950     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6951
6952     out:
6953     /* restore things */
6954     if(backbuffer) {
6955         IDirect3DSurface9_Release(backbuffer);
6956     }
6957     if(offscreenTexture) {
6958         IDirect3DTexture9_Release(offscreenTexture);
6959     }
6960     if(offscreen) {
6961         IDirect3DSurface9_Release(offscreen);
6962     }
6963 }
6964
6965 struct vertex_shortcolor {
6966     float x, y, z;
6967     unsigned short r, g, b, a;
6968 };
6969 struct vertex_floatcolor {
6970     float x, y, z;
6971     float r, g, b, a;
6972 };
6973
6974 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6975 {
6976     HRESULT hr;
6977     BOOL s_ok, ub_ok, f_ok;
6978     DWORD color, size, i;
6979     void *data;
6980     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6981         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6982         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6983         D3DDECL_END()
6984     };
6985     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6986         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6987         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6988         D3DDECL_END()
6989     };
6990     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6991         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6992         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6993         D3DDECL_END()
6994     };
6995     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6996         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6997         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6998         D3DDECL_END()
6999     };
7000     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
7001         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7002         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7003         D3DDECL_END()
7004     };
7005     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
7006         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7007         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7008         D3DDECL_END()
7009     };
7010     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
7011         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
7012         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7013         D3DDECL_END()
7014     };
7015     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
7016     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
7017     IDirect3DVertexBuffer9 *vb, *vb2;
7018     struct vertex quad1[] =                             /* D3DCOLOR */
7019     {
7020         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
7021         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7022         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
7023         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7024     };
7025     struct vertex quad2[] =                             /* UBYTE4N */
7026     {
7027         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7028         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
7029         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7030         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
7031     };
7032     struct vertex_shortcolor quad3[] =                  /* short */
7033     {
7034         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7035         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7036         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7037         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7038     };
7039     struct vertex_floatcolor quad4[] =
7040     {
7041         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7042         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7043         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7044         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7045     };
7046     DWORD colors[] = {
7047         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7048         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7049         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7050         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7051         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7052         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7053         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7054         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7055         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7056         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7057         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7058         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7059         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7060         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7061         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7062         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7063     };
7064     float quads[] = {
7065         -1.0,   -1.0,     0.1,
7066         -1.0,    0.0,     0.1,
7067          0.0,   -1.0,     0.1,
7068          0.0,    0.0,     0.1,
7069
7070          0.0,   -1.0,     0.1,
7071          0.0,    0.0,     0.1,
7072          1.0,   -1.0,     0.1,
7073          1.0,    0.0,     0.1,
7074
7075          0.0,    0.0,     0.1,
7076          0.0,    1.0,     0.1,
7077          1.0,    0.0,     0.1,
7078          1.0,    1.0,     0.1,
7079
7080         -1.0,    0.0,     0.1,
7081         -1.0,    1.0,     0.1,
7082          0.0,    0.0,     0.1,
7083          0.0,    1.0,     0.1
7084     };
7085     struct tvertex quad_transformed[] = {
7086        {  90,    110,     0.1,      2.0,        0x00ffff00},
7087        { 570,    110,     0.1,      2.0,        0x00ffff00},
7088        {  90,    300,     0.1,      2.0,        0x00ffff00},
7089        { 570,    300,     0.1,      2.0,        0x00ffff00}
7090     };
7091     D3DCAPS9 caps;
7092
7093     memset(&caps, 0, sizeof(caps));
7094     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7095     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7096
7097     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7098     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7099
7100     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7101     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7102     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7103     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7104     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7105     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7106     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7107         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7108         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7109         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7110         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7111     } else {
7112         trace("D3DDTCAPS_UBYTE4N not supported\n");
7113         dcl_ubyte_2 = NULL;
7114         dcl_ubyte = NULL;
7115     }
7116     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7117     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7118     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7119     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7120
7121     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7122     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7123                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
7124     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7125
7126     hr = IDirect3DDevice9_BeginScene(device);
7127     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7128     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7129     if(SUCCEEDED(hr)) {
7130         if(dcl_color) {
7131             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7132             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7133             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7134             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7135         }
7136
7137         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7138          * accepts them, the nvidia driver accepts them all. All those differences even though we're
7139          * using software vertex processing. Doh!
7140          */
7141         if(dcl_ubyte) {
7142             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7143             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7144             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7145             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7146             ub_ok = SUCCEEDED(hr);
7147         }
7148
7149         if(dcl_short) {
7150             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7151             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7152             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7153             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7154             s_ok = SUCCEEDED(hr);
7155         }
7156
7157         if(dcl_float) {
7158             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7159             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7160             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7161             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7162             f_ok = SUCCEEDED(hr);
7163         }
7164
7165         hr = IDirect3DDevice9_EndScene(device);
7166         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7167     }
7168
7169     if(dcl_short) {
7170         color = getPixelColor(device, 480, 360);
7171         ok(color == 0x000000ff || !s_ok,
7172            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7173     }
7174     if(dcl_ubyte) {
7175         color = getPixelColor(device, 160, 120);
7176         ok(color == 0x0000ffff || !ub_ok,
7177            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7178     }
7179     if(dcl_color) {
7180         color = getPixelColor(device, 160, 360);
7181         ok(color == 0x00ffff00,
7182            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7183     }
7184     if(dcl_float) {
7185         color = getPixelColor(device, 480, 120);
7186         ok(color == 0x00ff0000 || !f_ok,
7187            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7188     }
7189     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7190
7191     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7192      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7193      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7194      * whether the immediate mode code works
7195      */
7196     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7197     hr = IDirect3DDevice9_BeginScene(device);
7198     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7199     if(SUCCEEDED(hr)) {
7200         if(dcl_color) {
7201             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7202             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7203             memcpy(data, quad1, sizeof(quad1));
7204             hr = IDirect3DVertexBuffer9_Unlock(vb);
7205             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7206             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7207             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7208             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7209             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7210             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7211             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7212         }
7213
7214         if(dcl_ubyte) {
7215             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7216             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7217             memcpy(data, quad2, sizeof(quad2));
7218             hr = IDirect3DVertexBuffer9_Unlock(vb);
7219             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7220             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7221             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7222             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7223             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7224             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7225             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7226                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7227             ub_ok = SUCCEEDED(hr);
7228         }
7229
7230         if(dcl_short) {
7231             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7232             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7233             memcpy(data, quad3, sizeof(quad3));
7234             hr = IDirect3DVertexBuffer9_Unlock(vb);
7235             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7236             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7237             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7238             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7239             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7240             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7241             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7242                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7243             s_ok = SUCCEEDED(hr);
7244         }
7245
7246         if(dcl_float) {
7247             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7248             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7249             memcpy(data, quad4, sizeof(quad4));
7250             hr = IDirect3DVertexBuffer9_Unlock(vb);
7251             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7252             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7253             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7254             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7255             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7256             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7257             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7258                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7259             f_ok = SUCCEEDED(hr);
7260         }
7261
7262         hr = IDirect3DDevice9_EndScene(device);
7263         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7264     }
7265
7266     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7267     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7268     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7269     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7270
7271     if(dcl_short) {
7272         color = getPixelColor(device, 480, 360);
7273         ok(color == 0x000000ff || !s_ok,
7274            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7275     }
7276     if(dcl_ubyte) {
7277         color = getPixelColor(device, 160, 120);
7278         ok(color == 0x0000ffff || !ub_ok,
7279            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7280     }
7281     if(dcl_color) {
7282         color = getPixelColor(device, 160, 360);
7283         ok(color == 0x00ffff00,
7284            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7285     }
7286     if(dcl_float) {
7287         color = getPixelColor(device, 480, 120);
7288         ok(color == 0x00ff0000 || !f_ok,
7289            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7290     }
7291     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7292
7293     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7294     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7295
7296     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7297     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7298     memcpy(data, quad_transformed, sizeof(quad_transformed));
7299     hr = IDirect3DVertexBuffer9_Unlock(vb);
7300     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7301
7302     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7303     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7304
7305     hr = IDirect3DDevice9_BeginScene(device);
7306     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7307     if(SUCCEEDED(hr)) {
7308         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7309         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7310         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7311         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7312
7313         hr = IDirect3DDevice9_EndScene(device);
7314         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7315     }
7316
7317     color = getPixelColor(device, 88, 108);
7318     ok(color == 0x000000ff,
7319        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7320     color = getPixelColor(device, 92, 108);
7321     ok(color == 0x000000ff,
7322        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7323     color = getPixelColor(device, 88, 112);
7324     ok(color == 0x000000ff,
7325        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7326     color = getPixelColor(device, 92, 112);
7327     ok(color == 0x00ffff00,
7328        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7329
7330     color = getPixelColor(device, 568, 108);
7331     ok(color == 0x000000ff,
7332        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7333     color = getPixelColor(device, 572, 108);
7334     ok(color == 0x000000ff,
7335        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7336     color = getPixelColor(device, 568, 112);
7337     ok(color == 0x00ffff00,
7338        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7339     color = getPixelColor(device, 572, 112);
7340     ok(color == 0x000000ff,
7341        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7342
7343     color = getPixelColor(device, 88, 298);
7344     ok(color == 0x000000ff,
7345        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7346     color = getPixelColor(device, 92, 298);
7347     ok(color == 0x00ffff00,
7348        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7349     color = getPixelColor(device, 88, 302);
7350     ok(color == 0x000000ff,
7351        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7352     color = getPixelColor(device, 92, 302);
7353     ok(color == 0x000000ff,
7354        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7355
7356     color = getPixelColor(device, 568, 298);
7357     ok(color == 0x00ffff00,
7358        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7359     color = getPixelColor(device, 572, 298);
7360     ok(color == 0x000000ff,
7361        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7362     color = getPixelColor(device, 568, 302);
7363     ok(color == 0x000000ff,
7364        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7365     color = getPixelColor(device, 572, 302);
7366     ok(color == 0x000000ff,
7367        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7368
7369     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7370
7371     /* This test is pointless without those two declarations: */
7372     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7373         skip("color-ubyte switching test declarations aren't supported\n");
7374         goto out;
7375     }
7376
7377     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7378     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7379     memcpy(data, quads, sizeof(quads));
7380     hr = IDirect3DVertexBuffer9_Unlock(vb);
7381     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7382     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7383                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7384     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7385     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7386     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7387     memcpy(data, colors, sizeof(colors));
7388     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7389     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7390
7391     for(i = 0; i < 2; i++) {
7392         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7393         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7394
7395         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7396         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7397         if(i == 0) {
7398             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7399         } else {
7400             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7401         }
7402         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7403
7404         hr = IDirect3DDevice9_BeginScene(device);
7405         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7406         ub_ok = FALSE;
7407         if(SUCCEEDED(hr)) {
7408             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7409             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7410             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7411             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7412                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7413             ub_ok = SUCCEEDED(hr);
7414
7415             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7416             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7417             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7418             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7419
7420             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7421             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7422             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7423             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7424                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7425             ub_ok = (SUCCEEDED(hr) && ub_ok);
7426
7427             hr = IDirect3DDevice9_EndScene(device);
7428             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7429         }
7430
7431         if(i == 0) {
7432             color = getPixelColor(device, 480, 360);
7433             ok(color == 0x00ff0000,
7434                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7435             color = getPixelColor(device, 160, 120);
7436             ok(color == 0x00ffffff,
7437                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7438             color = getPixelColor(device, 160, 360);
7439             ok(color == 0x000000ff || !ub_ok,
7440                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7441             color = getPixelColor(device, 480, 120);
7442             ok(color == 0x000000ff || !ub_ok,
7443                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7444         } else {
7445             color = getPixelColor(device, 480, 360);
7446             ok(color == 0x000000ff,
7447                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7448             color = getPixelColor(device, 160, 120);
7449             ok(color == 0x00ffffff,
7450                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7451             color = getPixelColor(device, 160, 360);
7452             ok(color == 0x00ff0000 || !ub_ok,
7453                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7454             color = getPixelColor(device, 480, 120);
7455             ok(color == 0x00ff0000 || !ub_ok,
7456                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7457         }
7458         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7459     }
7460
7461     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7462     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7463     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7464     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7465     IDirect3DVertexBuffer9_Release(vb2);
7466
7467     out:
7468     IDirect3DVertexBuffer9_Release(vb);
7469     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7470     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7471     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7472     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7473     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7474     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7475     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7476 }
7477
7478 struct vertex_float16color {
7479     float x, y, z;
7480     DWORD c1, c2;
7481 };
7482
7483 static void test_vshader_float16(IDirect3DDevice9 *device)
7484 {
7485     HRESULT hr;
7486     DWORD color;
7487     void *data;
7488     static const D3DVERTEXELEMENT9 decl_elements[] = {
7489         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7490         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7491         D3DDECL_END()
7492     };
7493     IDirect3DVertexDeclaration9 *vdecl = NULL;
7494     IDirect3DVertexBuffer9 *buffer = NULL;
7495     IDirect3DVertexShader9 *shader;
7496     DWORD shader_code[] = {
7497         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7498         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7499         0x90e40001, 0x0000ffff
7500     };
7501     struct vertex_float16color quad[] = {
7502         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7503         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7504         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7505         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7506
7507         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7508         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7509         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7510         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7511
7512         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7513         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7514         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7515         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7516
7517         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7518         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7519         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7520         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7521     };
7522
7523     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7524     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7525
7526     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7527     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7528     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7529     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7530     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7531     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7532
7533     hr = IDirect3DDevice9_BeginScene(device);
7534     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7535     if(SUCCEEDED(hr)) {
7536         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7537         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7538         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7539         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7540         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7541         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7542         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7543         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7544         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7545         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7546
7547         hr = IDirect3DDevice9_EndScene(device);
7548         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7549     }
7550     color = getPixelColor(device, 480, 360);
7551     ok(color == 0x00ff0000,
7552        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7553     color = getPixelColor(device, 160, 120);
7554     ok(color == 0x00000000,
7555        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7556     color = getPixelColor(device, 160, 360);
7557     ok(color == 0x0000ff00,
7558        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7559     color = getPixelColor(device, 480, 120);
7560     ok(color == 0x000000ff,
7561        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7562     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7563
7564     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7565     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7566
7567     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7568                                              D3DPOOL_MANAGED, &buffer, NULL);
7569     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7570     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7571     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7572     memcpy(data, quad, sizeof(quad));
7573     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7574     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7575     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7576     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7577
7578     hr = IDirect3DDevice9_BeginScene(device);
7579     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7580     if(SUCCEEDED(hr)) {
7581             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7582             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7583             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7584             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7585             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7586             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7587             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7588             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7589
7590             hr = IDirect3DDevice9_EndScene(device);
7591             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7592     }
7593
7594     color = getPixelColor(device, 480, 360);
7595     ok(color == 0x00ff0000,
7596        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7597     color = getPixelColor(device, 160, 120);
7598     ok(color == 0x00000000,
7599        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7600     color = getPixelColor(device, 160, 360);
7601     ok(color == 0x0000ff00,
7602        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7603     color = getPixelColor(device, 480, 120);
7604     ok(color == 0x000000ff,
7605        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7606     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7607
7608     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7609     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7610     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7611     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7612     IDirect3DDevice9_SetVertexShader(device, NULL);
7613     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7614
7615     IDirect3DVertexDeclaration9_Release(vdecl);
7616     IDirect3DVertexShader9_Release(shader);
7617     IDirect3DVertexBuffer9_Release(buffer);
7618 }
7619
7620 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7621 {
7622     D3DCAPS9 caps;
7623     IDirect3DTexture9 *texture;
7624     HRESULT hr;
7625     D3DLOCKED_RECT rect;
7626     unsigned int x, y;
7627     DWORD *dst, color;
7628     const float quad[] = {
7629         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
7630          1.0,   -1.0,   0.1,    1.2,   -0.2,
7631         -1.0,    1.0,   0.1,   -0.2,    1.2,
7632          1.0,    1.0,   0.1,    1.2,    1.2
7633     };
7634     memset(&caps, 0, sizeof(caps));
7635
7636     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7637     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7638     if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7639         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7640         ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7641            "Card has conditional NP2 support without power of two restriction set\n");
7642         skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7643         return;
7644     } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7645         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7646         return;
7647     }
7648
7649     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7650     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7651
7652     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7653     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7654
7655     memset(&rect, 0, sizeof(rect));
7656     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7657     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7658     for(y = 0; y < 10; y++) {
7659         for(x = 0; x < 10; x++) {
7660             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7661             if(x == 0 || x == 9 || y == 0 || y == 9) {
7662                 *dst = 0x00ff0000;
7663             } else {
7664                 *dst = 0x000000ff;
7665             }
7666         }
7667     }
7668     hr = IDirect3DTexture9_UnlockRect(texture, 0);
7669     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7670
7671     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7672     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7673     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7674     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7675     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7676     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7677     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7678     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7679
7680     hr = IDirect3DDevice9_BeginScene(device);
7681     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7682     if(SUCCEEDED(hr)) {
7683         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7684         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7685
7686         hr = IDirect3DDevice9_EndScene(device);
7687         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7688     }
7689
7690     color = getPixelColor(device,    1,  1);
7691     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
7692     color = getPixelColor(device, 639, 479);
7693     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7694
7695     color = getPixelColor(device, 135, 101);
7696     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7697     color = getPixelColor(device, 140, 101);
7698     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7699     color = getPixelColor(device, 135, 105);
7700     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7701     color = getPixelColor(device, 140, 105);
7702     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7703
7704     color = getPixelColor(device, 135, 376);
7705     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7706     color = getPixelColor(device, 140, 376);
7707     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7708     color = getPixelColor(device, 135, 379);
7709     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7710     color = getPixelColor(device, 140, 379);
7711     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7712
7713     color = getPixelColor(device, 500, 101);
7714     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7715     color = getPixelColor(device, 504, 101);
7716     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7717     color = getPixelColor(device, 500, 105);
7718     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7719     color = getPixelColor(device, 504, 105);
7720     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7721
7722     color = getPixelColor(device, 500, 376);
7723     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7724     color = getPixelColor(device, 504, 376);
7725     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7726     color = getPixelColor(device, 500, 380);
7727     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7728     color = getPixelColor(device, 504, 380);
7729     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7730
7731     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7732
7733     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7734     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7735     IDirect3DTexture9_Release(texture);
7736 }
7737
7738 static void vFace_register_test(IDirect3DDevice9 *device)
7739 {
7740     HRESULT hr;
7741     DWORD color;
7742     const DWORD shader_code[] = {
7743         0xffff0300,                                                             /* ps_3_0                     */
7744         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7745         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7746         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
7747         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
7748         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
7749         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
7750         0x0000ffff                                                              /* END                        */
7751     };
7752     const DWORD vshader_code[] = {
7753         0xfffe0300,                                                             /* vs_3_0               */
7754         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
7755         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
7756         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
7757         0x0000ffff                                                              /* end                  */
7758     };
7759     IDirect3DPixelShader9 *shader;
7760     IDirect3DVertexShader9 *vshader;
7761     IDirect3DTexture9 *texture;
7762     IDirect3DSurface9 *surface, *backbuffer;
7763     const float quad[] = {
7764         -1.0,   -1.0,   0.1,
7765          1.0,   -1.0,   0.1,
7766         -1.0,    0.0,   0.1,
7767
7768          1.0,   -1.0,   0.1,
7769          1.0,    0.0,   0.1,
7770         -1.0,    0.0,   0.1,
7771
7772         -1.0,    0.0,   0.1,
7773         -1.0,    1.0,   0.1,
7774          1.0,    0.0,   0.1,
7775
7776          1.0,    0.0,   0.1,
7777         -1.0,    1.0,   0.1,
7778          1.0,    1.0,   0.1,
7779     };
7780     const float blit[] = {
7781          0.0,   -1.0,   0.1,    0.0,    0.0,
7782          1.0,   -1.0,   0.1,    1.0,    0.0,
7783          0.0,    1.0,   0.1,    0.0,    1.0,
7784          1.0,    1.0,   0.1,    1.0,    1.0,
7785     };
7786
7787     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
7788     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7789     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7790     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7791     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7792     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7793     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7794     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7795     hr = IDirect3DDevice9_SetPixelShader(device, shader);
7796     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7797     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
7798     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7799     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7800     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7801     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7802     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7803
7804     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7805     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7806
7807     hr = IDirect3DDevice9_BeginScene(device);
7808     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7809     if(SUCCEEDED(hr)) {
7810         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7811         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7812         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7813         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7814         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7815         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7816         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7817         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7818         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7819         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7820         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7821
7822         /* Blit the texture onto the back buffer to make it visible */
7823         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7824         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
7825         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7826         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7827         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7828         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7829         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7830         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7831         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7832         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7833         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7834         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7835
7836         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7837         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7838
7839         hr = IDirect3DDevice9_EndScene(device);
7840         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7841     }
7842
7843     color = getPixelColor(device, 160, 360);
7844     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7845     color = getPixelColor(device, 160, 120);
7846     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7847     color = getPixelColor(device, 480, 360);
7848     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7849     color = getPixelColor(device, 480, 120);
7850     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7851     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7852
7853     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7854     IDirect3DDevice9_SetTexture(device, 0, NULL);
7855     IDirect3DPixelShader9_Release(shader);
7856     IDirect3DVertexShader9_Release(vshader);
7857     IDirect3DSurface9_Release(surface);
7858     IDirect3DSurface9_Release(backbuffer);
7859     IDirect3DTexture9_Release(texture);
7860 }
7861
7862 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7863 {
7864     HRESULT hr;
7865     DWORD color;
7866     int i;
7867     D3DCAPS9 caps;
7868     BOOL L6V5U5_supported = FALSE;
7869     IDirect3DTexture9 *tex1, *tex2;
7870     D3DLOCKED_RECT locked_rect;
7871
7872     static const float quad[][7] = {
7873         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7874         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7875         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7876         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7877     };
7878
7879     static const D3DVERTEXELEMENT9 decl_elements[] = {
7880         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7881         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7882         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7883         D3DDECL_END()
7884     };
7885
7886     /* use asymmetric matrix to test loading */
7887     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7888     float scale, offset;
7889
7890     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7891     IDirect3DTexture9           *texture            = NULL;
7892
7893     memset(&caps, 0, sizeof(caps));
7894     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7895     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7896     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7897         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7898         return;
7899     } else {
7900         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7901          * They report that it is not supported, but after that bump mapping works properly. So just test
7902          * if the format is generally supported, and check the BUMPENVMAP flag
7903          */
7904         IDirect3D9 *d3d9;
7905
7906         IDirect3DDevice9_GetDirect3D(device, &d3d9);
7907         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7908                                           D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
7909         L6V5U5_supported = SUCCEEDED(hr);
7910         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7911                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7912         IDirect3D9_Release(d3d9);
7913         if(FAILED(hr)) {
7914             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7915             return;
7916         }
7917     }
7918
7919     /* Generate the textures */
7920     generate_bumpmap_textures(device);
7921
7922     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7923     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7924     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7925     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7926     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7927     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7928     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7929     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7930
7931     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7932     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7933     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7934     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7935     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7936     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7937
7938     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7939     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7940     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7941     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7942     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7943     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7944
7945     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7946     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7947
7948     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7949     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7950
7951     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7952     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7953
7954
7955     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7956     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7957     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7958     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7959
7960     hr = IDirect3DDevice9_BeginScene(device);
7961     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7962
7963     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7964     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7965
7966     hr = IDirect3DDevice9_EndScene(device);
7967     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7968
7969     /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
7970      * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
7971      * But since testing the color match is not the purpose of the test don't be too picky
7972      */
7973     color = getPixelColor(device, 320-32, 240);
7974     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7975     color = getPixelColor(device, 320+32, 240);
7976     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7977     color = getPixelColor(device, 320, 240-32);
7978     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7979     color = getPixelColor(device, 320, 240+32);
7980     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7981     color = getPixelColor(device, 320, 240);
7982     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7983     color = getPixelColor(device, 320+32, 240+32);
7984     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7985     color = getPixelColor(device, 320-32, 240+32);
7986     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7987     color = getPixelColor(device, 320+32, 240-32);
7988     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7989     color = getPixelColor(device, 320-32, 240-32);
7990     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7991     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7992     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7993
7994     for(i = 0; i < 2; i++) {
7995         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7996         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7997         IDirect3DTexture9_Release(texture); /* For the GetTexture */
7998         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7999         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
8000         IDirect3DTexture9_Release(texture); /* To destroy it */
8001     }
8002
8003     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
8004         skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
8005         goto cleanup;
8006     }
8007     if(L6V5U5_supported == FALSE) {
8008         skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
8009         goto cleanup;
8010     }
8011
8012     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
8013     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8014     /* This test only tests the luminance part. The bumpmapping part was already tested above and
8015      * would only make this test more complicated
8016      */
8017     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
8018     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8019     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8020     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8021
8022     memset(&locked_rect, 0, sizeof(locked_rect));
8023     hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
8024     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8025     *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
8026     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8027     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8028
8029     memset(&locked_rect, 0, sizeof(locked_rect));
8030     hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
8031     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8032     *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
8033     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8034     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8035
8036     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8037     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8038     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8039     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8040
8041     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
8042     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8043     scale = 2.0;
8044     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8045     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8046     offset = 0.1;
8047     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8048     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8049
8050     hr = IDirect3DDevice9_BeginScene(device);
8051     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8052     if(SUCCEEDED(hr)) {
8053         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8054         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8055         hr = IDirect3DDevice9_EndScene(device);
8056         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8057     }
8058
8059     color = getPixelColor(device, 320, 240);
8060     /* red:   1.0  * (0.25 * 2.0 + 0.1) = 1.0  * 0.6 = 0.6  = 0x99
8061      * green: 0.5  * (0.25 * 2.0 + 0.1) = 0.5  * 0.6 = 0.3  = 0x4c
8062      * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
8063      */
8064     ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
8065     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8066     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8067
8068     /* Check a result scale factor > 1.0 */
8069     scale = 10;
8070     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8071     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8072     offset = 10;
8073     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8074     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8075
8076     hr = IDirect3DDevice9_BeginScene(device);
8077     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8078     if(SUCCEEDED(hr)) {
8079         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8080         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8081         hr = IDirect3DDevice9_EndScene(device);
8082         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8083     }
8084     color = getPixelColor(device, 320, 240);
8085     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8086     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8087     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8088
8089     /* Check clamping in the scale factor calculation */
8090     scale = 1000;
8091     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8092     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8093     offset = -1;
8094     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8095     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8096
8097     hr = IDirect3DDevice9_BeginScene(device);
8098     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8099     if(SUCCEEDED(hr)) {
8100         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8101         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8102         hr = IDirect3DDevice9_EndScene(device);
8103         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8104     }
8105     color = getPixelColor(device, 320, 240);
8106     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8107     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8108     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8109
8110     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8111     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8112     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8113     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8114
8115     IDirect3DTexture9_Release(tex1);
8116     IDirect3DTexture9_Release(tex2);
8117
8118 cleanup:
8119     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8120     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8121     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8122     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8123
8124     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8125     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8126     IDirect3DVertexDeclaration9_Release(vertex_declaration);
8127 }
8128
8129 static void stencil_cull_test(IDirect3DDevice9 *device) {
8130     HRESULT hr;
8131     IDirect3DSurface9 *depthstencil = NULL;
8132     D3DSURFACE_DESC desc;
8133     float quad1[] = {
8134         -1.0,   -1.0,   0.1,
8135          0.0,   -1.0,   0.1,
8136         -1.0,    0.0,   0.1,
8137          0.0,    0.0,   0.1,
8138     };
8139     float quad2[] = {
8140          0.0,   -1.0,   0.1,
8141          1.0,   -1.0,   0.1,
8142          0.0,    0.0,   0.1,
8143          1.0,    0.0,   0.1,
8144     };
8145     float quad3[] = {
8146         0.0,    0.0,   0.1,
8147         1.0,    0.0,   0.1,
8148         0.0,    1.0,   0.1,
8149         1.0,    1.0,   0.1,
8150     };
8151     float quad4[] = {
8152         -1.0,    0.0,   0.1,
8153          0.0,    0.0,   0.1,
8154         -1.0,    1.0,   0.1,
8155          0.0,    1.0,   0.1,
8156     };
8157     struct vertex painter[] = {
8158        {-1.0,   -1.0,   0.0,    0x00000000},
8159        { 1.0,   -1.0,   0.0,    0x00000000},
8160        {-1.0,    1.0,   0.0,    0x00000000},
8161        { 1.0,    1.0,   0.0,    0x00000000},
8162     };
8163     WORD indices_cw[]  = {0, 1, 3};
8164     WORD indices_ccw[] = {0, 2, 3};
8165     unsigned int i;
8166     DWORD color;
8167
8168     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8169     if(depthstencil == NULL) {
8170         skip("No depth stencil buffer\n");
8171         return;
8172     }
8173     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8174     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8175     IDirect3DSurface9_Release(depthstencil);
8176     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8177         skip("No 4 or 8 bit stencil surface\n");
8178         return;
8179     }
8180
8181     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8182     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8183     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8184
8185     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8186     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8187     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8188     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8189     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8190     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8191     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8192     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8193
8194     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8195     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8196     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8197     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8198     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8199     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8200
8201     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8202     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8203     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8204     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8205
8206     /* First pass: Fill the stencil buffer with some values... */
8207     hr = IDirect3DDevice9_BeginScene(device);
8208     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8209     if(SUCCEEDED(hr))
8210     {
8211         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8212         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8213         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8214                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8215         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8216         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8217                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8218         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8219
8220         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8221         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8222         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8223         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8224         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8225                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8226         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8227         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8228                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8229         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8230
8231         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8232         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8233         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8234                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8235         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8236         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8237                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8238         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8239
8240         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8241         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8242         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8243                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8244         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8245         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8246                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8247         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8248
8249         hr = IDirect3DDevice9_EndScene(device);
8250         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8251     }
8252
8253     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8254     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8255     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8256     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8257     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8258     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8259     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8260     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8261     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8262     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8263     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8264     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8265     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8266
8267     /* 2nd pass: Make the stencil values visible */
8268     hr = IDirect3DDevice9_BeginScene(device);
8269     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8270     if(SUCCEEDED(hr))
8271     {
8272         IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8273         for(i = 0; i < 16; i++) {
8274             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8275             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8276
8277             painter[0].diffuse = (i * 16); /* Creates shades of blue */
8278             painter[1].diffuse = (i * 16);
8279             painter[2].diffuse = (i * 16);
8280             painter[3].diffuse = (i * 16);
8281             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8282             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8283         }
8284         hr = IDirect3DDevice9_EndScene(device);
8285         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8286     }
8287
8288     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8289     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8290
8291     color = getPixelColor(device, 160, 420);
8292     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8293     color = getPixelColor(device, 160, 300);
8294     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8295
8296     color = getPixelColor(device, 480, 420);
8297     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8298     color = getPixelColor(device, 480, 300);
8299     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8300
8301     color = getPixelColor(device, 160, 180);
8302     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8303     color = getPixelColor(device, 160, 60);
8304     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8305
8306     color = getPixelColor(device, 480, 180);
8307     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8308     color = getPixelColor(device, 480, 60);
8309     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8310
8311     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8312     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8313 }
8314
8315 static void vpos_register_test(IDirect3DDevice9 *device)
8316 {
8317     HRESULT hr;
8318     DWORD color;
8319     const DWORD shader_code[] = {
8320     0xffff0300,                                                             /* ps_3_0                     */
8321     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8322     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8323     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8324     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8325     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8326     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8327     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8328     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8329     0x0000ffff                                                              /* end                        */
8330     };
8331     const DWORD shader_frac_code[] = {
8332     0xffff0300,                                                             /* ps_3_0                     */
8333     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8334     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8335     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8336     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8337     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8338     0x0000ffff                                                              /* end                        */
8339     };
8340     const DWORD vshader_code[] = {
8341         0xfffe0300,                                                             /* vs_3_0               */
8342         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
8343         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
8344         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
8345         0x0000ffff                                                              /* end                  */
8346     };
8347     IDirect3DVertexShader9 *vshader;
8348     IDirect3DPixelShader9 *shader, *shader_frac;
8349     IDirect3DSurface9 *surface = NULL, *backbuffer;
8350     const float quad[] = {
8351         -1.0,   -1.0,   0.1,    0.0,    0.0,
8352          1.0,   -1.0,   0.1,    1.0,    0.0,
8353         -1.0,    1.0,   0.1,    0.0,    1.0,
8354          1.0,    1.0,   0.1,    1.0,    1.0,
8355     };
8356     D3DLOCKED_RECT lr;
8357     float constant[4] = {1.0, 0.0, 320, 240};
8358     DWORD *pos;
8359
8360     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8361     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8362     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8363     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8364     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8365     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8366     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8367     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8368     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8369     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8370     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8371     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8372     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8373     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8374     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8375     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8376
8377     hr = IDirect3DDevice9_BeginScene(device);
8378     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8379     if(SUCCEEDED(hr)) {
8380         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8381         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8382         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8383         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8384         hr = IDirect3DDevice9_EndScene(device);
8385         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8386     }
8387
8388     /* This has to be pixel exact */
8389     color = getPixelColor(device, 319, 239);
8390     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8391     color = getPixelColor(device, 320, 239);
8392     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8393     color = getPixelColor(device, 319, 240);
8394     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8395     color = getPixelColor(device, 320, 240);
8396     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8397     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8398
8399     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8400                                              &surface, NULL);
8401     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8402     hr = IDirect3DDevice9_BeginScene(device);
8403     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8404     if(SUCCEEDED(hr)) {
8405         constant[2] = 16; constant[3] = 16;
8406         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8407         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8408         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8409         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8410         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8411         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8412         hr = IDirect3DDevice9_EndScene(device);
8413         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8414     }
8415     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8416     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8417
8418     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8419     color = *pos & 0x00ffffff;
8420     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8421     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8422     color = *pos & 0x00ffffff;
8423     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8424     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8425     color = *pos & 0x00ffffff;
8426     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8427     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8428     color = *pos & 0x00ffffff;
8429     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8430
8431     hr = IDirect3DSurface9_UnlockRect(surface);
8432     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8433
8434     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8435      * have full control over the multisampling setting inside this test
8436      */
8437     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8438     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8439     hr = IDirect3DDevice9_BeginScene(device);
8440     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8441     if(SUCCEEDED(hr)) {
8442         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8443         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8444         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8445         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8446         hr = IDirect3DDevice9_EndScene(device);
8447         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8448     }
8449     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8450     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8451
8452     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8453     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8454
8455     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8456     color = *pos & 0x00ffffff;
8457     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8458
8459     hr = IDirect3DSurface9_UnlockRect(surface);
8460     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8461
8462     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8463     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8464     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8465     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8466     IDirect3DPixelShader9_Release(shader);
8467     IDirect3DPixelShader9_Release(shader_frac);
8468     IDirect3DVertexShader9_Release(vshader);
8469     if(surface) IDirect3DSurface9_Release(surface);
8470     IDirect3DSurface9_Release(backbuffer);
8471 }
8472
8473 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
8474 {
8475     D3DCOLOR color;
8476
8477     color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
8478     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8479     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8480     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8481     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8482
8483     ++r;
8484     color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
8485     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8486     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8487     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8488     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8489
8490     return TRUE;
8491 }
8492
8493 static void pointsize_test(IDirect3DDevice9 *device)
8494 {
8495     HRESULT hr;
8496     D3DCAPS9 caps;
8497     D3DMATRIX matrix;
8498     D3DMATRIX identity;
8499     float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8500     DWORD color;
8501     IDirect3DSurface9 *rt, *backbuffer;
8502     IDirect3DTexture9 *tex1, *tex2;
8503     RECT rect = {0, 0, 128, 128};
8504     D3DLOCKED_RECT lr;
8505     const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8506                                 0x00000000, 0x00000000};
8507     const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8508                                 0x00000000, 0x0000ff00};
8509
8510     const float vertices[] = {
8511         64,     64,     0.1,
8512         128,    64,     0.1,
8513         192,    64,     0.1,
8514         256,    64,     0.1,
8515         320,    64,     0.1,
8516         384,    64,     0.1,
8517         448,    64,     0.1,
8518         512,    64,     0.1,
8519     };
8520
8521     /* 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 */
8522     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;
8523     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;
8524     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;
8525     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;
8526
8527     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;
8528     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;
8529     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;
8530     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;
8531
8532     memset(&caps, 0, sizeof(caps));
8533     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8534     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8535     if(caps.MaxPointSize < 32.0) {
8536         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8537         return;
8538     }
8539
8540     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8541     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8542     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8543     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8544     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8545     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8546     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8547     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8548
8549     hr = IDirect3DDevice9_BeginScene(device);
8550     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8551     if (SUCCEEDED(hr))
8552     {
8553         ptsize = 15.0;
8554         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8555         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8556         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8557         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8558
8559         ptsize = 31.0;
8560         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8561         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8562         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8563         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8564
8565         ptsize = 30.75;
8566         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8567         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8568         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8569         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8570
8571         if (caps.MaxPointSize >= 63.0)
8572         {
8573             ptsize = 63.0;
8574             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8575             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8576             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8577             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8578
8579             ptsize = 62.75;
8580             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8581             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8582             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8583             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8584         }
8585
8586         ptsize = 1.0;
8587         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8588         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8589         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8590         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8591
8592         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8593         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8594         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8595         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8596
8597         /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8598         ptsize = 15.0;
8599         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8600         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8601         ptsize = 1.0;
8602         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8603         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8604         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8605         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8606
8607         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8608         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8609
8610         /* pointsize < pointsize_min < pointsize_max?
8611          * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
8612         ptsize = 1.0;
8613         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8614         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8615         ptsize = 15.0;
8616         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8617         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8618         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8619         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8620
8621         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8622         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8623
8624         hr = IDirect3DDevice9_EndScene(device);
8625         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8626     }
8627
8628     ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
8629     ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
8630     ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
8631
8632     if (caps.MaxPointSize >= 63.0)
8633     {
8634         ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
8635         ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
8636     }
8637
8638     ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
8639     /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
8640     ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
8641     /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
8642     ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
8643
8644     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8645
8646     /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8647      * generates texture coordinates for the point(result: Yes, it does)
8648      *
8649      * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8650      * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8651      * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8652      */
8653     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8654     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8655
8656     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8657     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8658     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8659     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8660     memset(&lr, 0, sizeof(lr));
8661     hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8662     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8663     memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8664     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8665     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8666     memset(&lr, 0, sizeof(lr));
8667     hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8668     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8669     memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8670     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8671     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8672     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8673     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8674     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8675     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8676     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8677     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8678     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8679     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8680     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8681     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8682     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8683     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8684     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8685     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8686
8687     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8688     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8689     ptsize = 32.0;
8690     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8691     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8692
8693     hr = IDirect3DDevice9_BeginScene(device);
8694     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8695     if(SUCCEEDED(hr))
8696     {
8697         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8698         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8699         hr = IDirect3DDevice9_EndScene(device);
8700         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8701     }
8702
8703     color = getPixelColor(device, 64-4, 64-4);
8704     ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
8705     color = getPixelColor(device, 64-4, 64+4);
8706     ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
8707     color = getPixelColor(device, 64+4, 64+4);
8708     ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
8709     color = getPixelColor(device, 64+4, 64-4);
8710     ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
8711     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8712
8713     U(matrix).m[0][0] =  1.0f / 64.0f;
8714     U(matrix).m[1][1] = -1.0f / 64.0f;
8715     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8716     ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
8717
8718     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
8719     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
8720
8721     hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
8722             D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
8723     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
8724
8725     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
8726     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8727     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 0.0f, 0);
8728     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
8729
8730     hr = IDirect3DDevice9_BeginScene(device);
8731     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
8732     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8733     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
8734     hr = IDirect3DDevice9_EndScene(device);
8735     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
8736
8737     hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
8738     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
8739     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8740     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8741     IDirect3DSurface9_Release(backbuffer);
8742     IDirect3DSurface9_Release(rt);
8743
8744     color = getPixelColor(device, 64-4, 64-4);
8745     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
8746             "Expected color 0x00ff0000, got 0x%08x.\n", color);
8747     color = getPixelColor(device, 64+4, 64-4);
8748     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
8749             "Expected color 0x00ffff00, got 0x%08x.\n", color);
8750     color = getPixelColor(device, 64-4, 64+4);
8751     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
8752             "Expected color 0x00000000, got 0x%08x.\n", color);
8753     color = getPixelColor(device, 64+4, 64+4);
8754     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
8755             "Expected color 0x0000ff00, got 0x%08x.\n", color);
8756
8757     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8758     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
8759
8760     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8761     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8762     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8763     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8764     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8765     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8766     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8767     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8768     IDirect3DTexture9_Release(tex1);
8769     IDirect3DTexture9_Release(tex2);
8770
8771     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
8772     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8773     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8774     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8775     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8776     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8777 }
8778
8779 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8780 {
8781     static const DWORD vshader_code[] =
8782     {
8783         0xfffe0300,                                                             /* vs_3_0                     */
8784         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0            */
8785         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0            */
8786         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                 */
8787         0x0000ffff                                                              /* end                        */
8788     };
8789     static const DWORD pshader_code1[] =
8790     {
8791         0xffff0300,                                                             /* ps_3_0                     */
8792         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8793         0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
8794         0x0000ffff                                                              /* end                        */
8795     };
8796     static const DWORD pshader_code2[] =
8797     {
8798         0xffff0300,                                                             /* ps_3_0                     */
8799         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8800         0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
8801         0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
8802         0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1                */
8803         0x0000ffff                                                              /* end                        */
8804     };
8805
8806     HRESULT hr;
8807     IDirect3DVertexShader9 *vs;
8808     IDirect3DPixelShader9 *ps1, *ps2;
8809     IDirect3DTexture9 *tex1, *tex2;
8810     IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
8811     D3DCAPS9 caps;
8812     DWORD color;
8813     UINT i, j;
8814     float quad[] = {
8815        -1.0,   -1.0,    0.1,
8816         1.0,   -1.0,    0.1,
8817        -1.0,    1.0,    0.1,
8818         1.0,    1.0,    0.1,
8819     };
8820     float texquad[] = {
8821        -1.0,   -1.0,    0.1,    0.0,    0.0,
8822         0.0,   -1.0,    0.1,    1.0,    0.0,
8823        -1.0,    1.0,    0.1,    0.0,    1.0,
8824         0.0,    1.0,    0.1,    1.0,    1.0,
8825
8826         0.0,   -1.0,    0.1,    0.0,    0.0,
8827         1.0,   -1.0,    0.1,    1.0,    0.0,
8828         0.0,    1.0,    0.1,    0.0,    1.0,
8829         1.0,    1.0,    0.1,    1.0,    1.0,
8830     };
8831
8832     memset(&caps, 0, sizeof(caps));
8833     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8834     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8835     if(caps.NumSimultaneousRTs < 2) {
8836         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8837         return;
8838     }
8839
8840     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8841     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8842
8843     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
8844             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
8845     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
8846
8847     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
8848             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8849     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8850     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
8851             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8852     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8853     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
8854     ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
8855     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code1, &ps1);
8856     ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
8857     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code2, &ps2);
8858     ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
8859
8860     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8861     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8862     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8863     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8864     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8865     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8866
8867     hr = IDirect3DDevice9_SetVertexShader(device, vs);
8868     ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
8869     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8870     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8871     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8872     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8873     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8874     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8875
8876     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
8877     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
8878     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
8879     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8880     color = getPixelColorFromSurface(readback, 8, 8);
8881     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
8882             "Expected color 0x000000ff, got 0x%08x.\n", color);
8883     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
8884     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8885     color = getPixelColorFromSurface(readback, 8, 8);
8886     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
8887             "Expected color 0x000000ff, got 0x%08x.\n", color);
8888
8889     /* Render targets not written by the pixel shader should be unmodified. */
8890     hr = IDirect3DDevice9_SetPixelShader(device, ps1);
8891     ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
8892     hr = IDirect3DDevice9_BeginScene(device);
8893     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
8894     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8895     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
8896     hr = IDirect3DDevice9_EndScene(device);
8897     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
8898     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
8899     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8900     color = getPixelColorFromSurface(readback, 8, 8);
8901     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
8902             "Expected color 0xff00ff00, got 0x%08x.\n", color);
8903     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
8904     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8905     for (i = 6; i < 10; ++i)
8906     {
8907         for (j = 6; j < 10; ++j)
8908         {
8909             color = getPixelColorFromSurface(readback, j, i);
8910             ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
8911                     "Expected color 0xff0000ff, got 0x%08x at %u, %u.\n", color, j, i);
8912         }
8913     }
8914
8915     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
8916     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
8917     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
8918     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8919     color = getPixelColorFromSurface(readback, 8, 8);
8920     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
8921             "Expected color 0x0000ff00, got 0x%08x.\n", color);
8922     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
8923     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8924     color = getPixelColorFromSurface(readback, 8, 8);
8925     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
8926             "Expected color 0x0000ff00, got 0x%08x.\n", color);
8927
8928     hr = IDirect3DDevice9_SetPixelShader(device, ps2);
8929     ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
8930
8931     hr = IDirect3DDevice9_BeginScene(device);
8932     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8933     if(SUCCEEDED(hr)) {
8934         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8935         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8936
8937         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8938         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
8939         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8940         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8941         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8942         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8943         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8944         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8945         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8946         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8947
8948         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8949         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8950         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8951         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8952
8953         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8954         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8955         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8956         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8957
8958         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8959         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8960
8961         hr = IDirect3DDevice9_EndScene(device);
8962         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8963     }
8964
8965     color = getPixelColor(device, 160, 240);
8966     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8967     color = getPixelColor(device, 480, 240);
8968     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8969     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8970
8971     IDirect3DPixelShader9_Release(ps2);
8972     IDirect3DPixelShader9_Release(ps1);
8973     IDirect3DVertexShader9_Release(vs);
8974     IDirect3DTexture9_Release(tex1);
8975     IDirect3DTexture9_Release(tex2);
8976     IDirect3DSurface9_Release(surf1);
8977     IDirect3DSurface9_Release(surf2);
8978     IDirect3DSurface9_Release(backbuf);
8979     IDirect3DSurface9_Release(readback);
8980 }
8981
8982 struct formats {
8983     const char *fmtName;
8984     D3DFORMAT textureFormat;
8985     DWORD resultColorBlending;
8986     DWORD resultColorNoBlending;
8987 };
8988
8989 static const struct formats test_formats[] = {
8990   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
8991   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8992   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8993   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8994   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8995   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8996   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8997   { NULL, 0 }
8998 };
8999
9000 static void pixelshader_blending_test(IDirect3DDevice9 *device)
9001 {
9002     HRESULT hr;
9003     IDirect3DTexture9 *offscreenTexture = NULL;
9004     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
9005     IDirect3D9 *d3d = NULL;
9006     DWORD color;
9007     DWORD r0, g0, b0, r1, g1, b1;
9008     int fmt_index;
9009
9010     static const float quad[][5] = {
9011         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
9012         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
9013         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
9014         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
9015     };
9016
9017     /* Quad with R=0x10, G=0x20 */
9018     static const struct vertex quad1[] = {
9019         {-1.0f, -1.0f, 0.1f, 0x80102000},
9020         {-1.0f,  1.0f, 0.1f, 0x80102000},
9021         { 1.0f, -1.0f, 0.1f, 0x80102000},
9022         { 1.0f,  1.0f, 0.1f, 0x80102000},
9023     };
9024
9025     /* Quad with R=0x20, G=0x10 */
9026     static const struct vertex quad2[] = {
9027         {-1.0f, -1.0f, 0.1f, 0x80201000},
9028         {-1.0f,  1.0f, 0.1f, 0x80201000},
9029         { 1.0f, -1.0f, 0.1f, 0x80201000},
9030         { 1.0f,  1.0f, 0.1f, 0x80201000},
9031     };
9032
9033     IDirect3DDevice9_GetDirect3D(device, &d3d);
9034
9035     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9036     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
9037     if(!backbuffer) {
9038         goto out;
9039     }
9040
9041     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
9042     {
9043         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
9044
9045         if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
9046                 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
9047         {
9048             skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
9049             continue;
9050         }
9051
9052         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9053         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9054
9055         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
9056         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
9057         if(!offscreenTexture) {
9058             continue;
9059         }
9060
9061         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
9062         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
9063         if(!offscreen) {
9064             continue;
9065         }
9066
9067         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9068         ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9069
9070         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9071         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9072         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9073         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9074         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
9075         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
9076         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
9077         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
9078         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9079         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9080
9081         /* Below we will draw two quads with different colors and try to blend them together.
9082          * The result color is compared with the expected outcome.
9083          */
9084         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
9085             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
9086             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9087             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
9088             ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9089
9090             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9091             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9092
9093             /* Draw a quad using color 0x0010200 */
9094             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
9095             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9096             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
9097             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9098             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9099             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9100
9101             /* Draw a quad using color 0x0020100 */
9102             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9103             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9104             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
9105             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9106             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9107             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9108
9109             /* We don't want to blend the result on the backbuffer */
9110             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9111             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9112
9113             /* Prepare rendering the 'blended' texture quad to the backbuffer */
9114             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9115             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9116             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
9117             ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
9118
9119             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9120             ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9121
9122             /* This time with the texture */
9123             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9124             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
9125
9126             IDirect3DDevice9_EndScene(device);
9127         }
9128
9129         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
9130             /* Compare the color of the center quad with our expectation */
9131             color = getPixelColor(device, 320, 240);
9132             r0 = (color & 0x00ff0000) >> 16;
9133             g0 = (color & 0x0000ff00) >>  8;
9134             b0 = (color & 0x000000ff) >>  0;
9135
9136             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
9137             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
9138             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
9139
9140             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9141                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9142                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9143                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9144         } else {
9145             /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9146              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9147              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9148             color = getPixelColor(device, 320, 240);
9149             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);
9150         }
9151         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9152
9153         IDirect3DDevice9_SetTexture(device, 0, NULL);
9154         if(offscreenTexture) {
9155             IDirect3DTexture9_Release(offscreenTexture);
9156         }
9157         if(offscreen) {
9158             IDirect3DSurface9_Release(offscreen);
9159         }
9160     }
9161
9162 out:
9163     /* restore things */
9164     if(backbuffer) {
9165         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9166         IDirect3DSurface9_Release(backbuffer);
9167     }
9168 }
9169
9170 static void tssargtemp_test(IDirect3DDevice9 *device)
9171 {
9172     HRESULT hr;
9173     DWORD color;
9174     static const struct vertex quad[] = {
9175         {-1.0,     -1.0,    0.1,    0x00ff0000},
9176         { 1.0,     -1.0,    0.1,    0x00ff0000},
9177         {-1.0,      1.0,    0.1,    0x00ff0000},
9178         { 1.0,      1.0,    0.1,    0x00ff0000}
9179     };
9180     D3DCAPS9 caps;
9181
9182     memset(&caps, 0, sizeof(caps));
9183     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9184     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9185     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9186         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9187         return;
9188     }
9189
9190     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9191     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9192
9193     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9194     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9195     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9196     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9197
9198     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9199     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9200     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9201     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9202     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9203     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9204
9205     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9206     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9207     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9208     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9209     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9210     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9211
9212     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9213     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9214
9215     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9216     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9217     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9218     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9219
9220     hr = IDirect3DDevice9_BeginScene(device);
9221     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9222     if(SUCCEEDED(hr)) {
9223         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9224         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9225         hr = IDirect3DDevice9_EndScene(device);
9226         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9227     }
9228     color = getPixelColor(device, 320, 240);
9229     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9230     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9231
9232     /* Set stage 1 back to default */
9233     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9234     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9235     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9236     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9237     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9238     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9239     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9240     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9241     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9242     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9243 }
9244
9245 struct testdata
9246 {
9247     DWORD idxVertex; /* number of instances in the first stream */
9248     DWORD idxColor; /* number of instances in the second stream */
9249     DWORD idxInstance; /* should be 1 ?? */
9250     DWORD color1; /* color 1 instance */
9251     DWORD color2; /* color 2 instance */
9252     DWORD color3; /* color 3 instance */
9253     DWORD color4; /* color 4 instance */
9254     WORD strVertex; /* specify which stream to use 0-2*/
9255     WORD strColor;
9256     WORD strInstance;
9257 };
9258
9259 static const struct testdata testcases[]=
9260 {
9261     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
9262     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
9263     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
9264     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
9265     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  4 */
9266     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
9267     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
9268     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
9269     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  8 */
9270     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /*  9 */
9271     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 10 */
9272     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 11 */
9273     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 12 */
9274     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 13 */
9275 /*
9276     This draws one instance on some machines, no instance on others
9277     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2},
9278 */
9279 /*
9280     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
9281     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9282 */
9283 };
9284
9285 /* Drawing Indexed Geometry with instances*/
9286 static void stream_test(IDirect3DDevice9 *device)
9287 {
9288     IDirect3DVertexBuffer9 *vb = NULL;
9289     IDirect3DVertexBuffer9 *vb2 = NULL;
9290     IDirect3DVertexBuffer9 *vb3 = NULL;
9291     IDirect3DIndexBuffer9 *ib = NULL;
9292     IDirect3DVertexDeclaration9 *pDecl = NULL;
9293     IDirect3DVertexShader9 *shader = NULL;
9294     HRESULT hr;
9295     BYTE *data;
9296     DWORD color;
9297     DWORD ind;
9298     unsigned i;
9299
9300     const DWORD shader_code[] =
9301     {
9302         0xfffe0101,                                     /* vs_1_1 */
9303         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
9304         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
9305         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
9306         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
9307         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9308         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
9309         0x0000ffff
9310     };
9311
9312     const float quad[][3] =
9313     {
9314         {-0.5f, -0.5f,  1.1f}, /*0 */
9315         {-0.5f,  0.5f,  1.1f}, /*1 */
9316         { 0.5f, -0.5f,  1.1f}, /*2 */
9317         { 0.5f,  0.5f,  1.1f}, /*3 */
9318     };
9319
9320     const float vertcolor[][4] =
9321     {
9322         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9323         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9324         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9325         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9326     };
9327
9328     /* 4 position for 4 instances */
9329     const float instancepos[][3] =
9330     {
9331         {-0.6f,-0.6f, 0.0f},
9332         { 0.6f,-0.6f, 0.0f},
9333         { 0.6f, 0.6f, 0.0f},
9334         {-0.6f, 0.6f, 0.0f},
9335     };
9336
9337     short indices[] = {0, 1, 2, 1, 2, 3};
9338
9339     D3DVERTEXELEMENT9 decl[] =
9340     {
9341         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9342         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9343         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9344         D3DDECL_END()
9345     };
9346
9347     /* set the default value because it isn't done in wine? */
9348     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9349     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9350
9351     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9352     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9353     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9354
9355     /* check wrong cases */
9356     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9357     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9358     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9359     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9360     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9361     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9362     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9363     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9364     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9365     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9366     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9367     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9368     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9369     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9370     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9371     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9372     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9373     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9374     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9375     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9376
9377     /* set the default value back */
9378     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9379     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9380
9381     /* create all VertexBuffers*/
9382     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9383     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9384     if(!vb) {
9385         skip("Failed to create a vertex buffer\n");
9386         return;
9387     }
9388     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9389     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9390     if(!vb2) {
9391         skip("Failed to create a vertex buffer\n");
9392         goto out;
9393     }
9394     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9395     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9396     if(!vb3) {
9397         skip("Failed to create a vertex buffer\n");
9398         goto out;
9399     }
9400
9401     /* create IndexBuffer*/
9402     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9403     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9404     if(!ib) {
9405         skip("Failed to create a index buffer\n");
9406         goto out;
9407     }
9408
9409     /* copy all Buffers (Vertex + Index)*/
9410     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9411     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9412     memcpy(data, quad, sizeof(quad));
9413     hr = IDirect3DVertexBuffer9_Unlock(vb);
9414     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9415     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9416     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9417     memcpy(data, vertcolor, sizeof(vertcolor));
9418     hr = IDirect3DVertexBuffer9_Unlock(vb2);
9419     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9420     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9421     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9422     memcpy(data, instancepos, sizeof(instancepos));
9423     hr = IDirect3DVertexBuffer9_Unlock(vb3);
9424     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9425     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9426     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9427     memcpy(data, indices, sizeof(indices));
9428     hr = IDirect3DIndexBuffer9_Unlock(ib);
9429     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9430
9431     /* create VertexShader */
9432     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9433     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9434     if(!shader) {
9435         skip("Failed to create a vetex shader\n");
9436         goto out;
9437     }
9438
9439     hr = IDirect3DDevice9_SetVertexShader(device, shader);
9440     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9441
9442     hr = IDirect3DDevice9_SetIndices(device, ib);
9443     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9444
9445     /* run all tests */
9446     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9447     {
9448         struct testdata act = testcases[i];
9449         decl[0].Stream = act.strVertex;
9450         decl[1].Stream = act.strColor;
9451         decl[2].Stream = act.strInstance;
9452         /* create VertexDeclarations */
9453         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9454         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9455
9456         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9457         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9458
9459         hr = IDirect3DDevice9_BeginScene(device);
9460         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9461         if(SUCCEEDED(hr))
9462         {
9463             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9464             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9465
9466             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9467             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9468             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9469             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9470
9471             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9472             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9473             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9474             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9475
9476             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9477             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9478             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9479             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9480
9481             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
9482             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9483             hr = IDirect3DDevice9_EndScene(device);
9484             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9485
9486             /* set all StreamSource && StreamSourceFreq back to default */
9487             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9488             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9489             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9490             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9491             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9492             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9493             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9494             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9495             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9496             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9497             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9498             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9499         }
9500
9501         hr = IDirect3DVertexDeclaration9_Release(pDecl);
9502         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9503
9504         color = getPixelColor(device, 160, 360);
9505         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9506         color = getPixelColor(device, 480, 360);
9507         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9508         color = getPixelColor(device, 480, 120);
9509         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9510         color = getPixelColor(device, 160, 120);
9511         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9512
9513         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9514         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9515     }
9516
9517     hr = IDirect3DDevice9_SetIndices(device, NULL);
9518     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9519
9520 out:
9521     if(vb) IDirect3DVertexBuffer9_Release(vb);
9522     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9523     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9524     if(ib)IDirect3DIndexBuffer9_Release(ib);
9525     if(shader)IDirect3DVertexShader9_Release(shader);
9526 }
9527
9528 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9529     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9530     IDirect3DTexture9 *dsttex = NULL;
9531     HRESULT hr;
9532     DWORD color;
9533     D3DRECT r1 = {0,  0,  50,  50 };
9534     D3DRECT r2 = {50, 0,  100, 50 };
9535     D3DRECT r3 = {50, 50, 100, 100};
9536     D3DRECT r4 = {0,  50,  50, 100};
9537     const float quad[] = {
9538         -1.0,   -1.0,   0.1,    0.0,    0.0,
9539          1.0,   -1.0,   0.1,    1.0,    0.0,
9540         -1.0,    1.0,   0.1,    0.0,    1.0,
9541          1.0,    1.0,   0.1,    1.0,    1.0,
9542     };
9543
9544     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9545     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9546
9547     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9548     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9549     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9550     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9551
9552     if(!src || !dsttex) {
9553         skip("One or more test resources could not be created\n");
9554         goto cleanup;
9555     }
9556
9557     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9558     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9559
9560     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9561     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9562
9563     /* Clear the StretchRect destination for debugging */
9564     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9565     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9566     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9567     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9568
9569     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9570     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9571
9572     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9573     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9574     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9575     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9576     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9577     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9578     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9579     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9580
9581     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9582      * the target -> texture GL blit path
9583      */
9584     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9585     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9586     IDirect3DSurface9_Release(dst);
9587
9588     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9589     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9590
9591     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9592     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9593     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9594     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9595     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9596     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9597     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9598     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9599
9600     hr = IDirect3DDevice9_BeginScene(device);
9601     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9602     if(SUCCEEDED(hr)) {
9603         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9604         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9605         hr = IDirect3DDevice9_EndScene(device);
9606         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9607     }
9608
9609     color = getPixelColor(device, 160, 360);
9610     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9611     color = getPixelColor(device, 480, 360);
9612     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9613     color = getPixelColor(device, 480, 120);
9614     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9615     color = getPixelColor(device, 160, 120);
9616     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9617     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9618     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9619
9620     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9621     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9622     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9623     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9624
9625 cleanup:
9626     if(src) IDirect3DSurface9_Release(src);
9627     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9628     if(dsttex) IDirect3DTexture9_Release(dsttex);
9629 }
9630
9631 static void texop_test(IDirect3DDevice9 *device)
9632 {
9633     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9634     IDirect3DTexture9 *texture = NULL;
9635     D3DLOCKED_RECT locked_rect;
9636     D3DCOLOR color;
9637     D3DCAPS9 caps;
9638     HRESULT hr;
9639     unsigned i;
9640
9641     static const struct {
9642         float x, y, z;
9643         float s, t;
9644         D3DCOLOR diffuse;
9645     } quad[] = {
9646         {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9647         {-1.0f,  1.0f, 0.1f, -1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9648         { 1.0f, -1.0f, 0.1f,  1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9649         { 1.0f,  1.0f, 0.1f,  1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9650     };
9651
9652     static const D3DVERTEXELEMENT9 decl_elements[] = {
9653         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9654         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9655         {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9656         D3DDECL_END()
9657     };
9658
9659     static const struct {
9660         D3DTEXTUREOP op;
9661         const char *name;
9662         DWORD caps_flag;
9663         D3DCOLOR result;
9664     } test_data[] = {
9665         {D3DTOP_SELECTARG1,                "SELECTARG1",                D3DTEXOPCAPS_SELECTARG1,                D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9666         {D3DTOP_SELECTARG2,                "SELECTARG2",                D3DTEXOPCAPS_SELECTARG2,                D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9667         {D3DTOP_MODULATE,                  "MODULATE",                  D3DTEXOPCAPS_MODULATE,                  D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9668         {D3DTOP_MODULATE2X,                "MODULATE2X",                D3DTEXOPCAPS_MODULATE2X,                D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9669         {D3DTOP_MODULATE4X,                "MODULATE4X",                D3DTEXOPCAPS_MODULATE4X,                D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9670         {D3DTOP_ADD,                       "ADD",                       D3DTEXOPCAPS_ADD,                       D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9671         {D3DTOP_ADDSIGNED,                 "ADDSIGNED",                 D3DTEXOPCAPS_ADDSIGNED,                 D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9672         {D3DTOP_ADDSIGNED2X,               "ADDSIGNED2X",               D3DTEXOPCAPS_ADDSIGNED2X,               D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9673         {D3DTOP_SUBTRACT,                  "SUBTRACT",                  D3DTEXOPCAPS_SUBTRACT,                  D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9674         {D3DTOP_ADDSMOOTH,                 "ADDSMOOTH",                 D3DTEXOPCAPS_ADDSMOOTH,                 D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9675         {D3DTOP_BLENDDIFFUSEALPHA,         "BLENDDIFFUSEALPHA",         D3DTEXOPCAPS_BLENDDIFFUSEALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9676         {D3DTOP_BLENDTEXTUREALPHA,         "BLENDTEXTUREALPHA",         D3DTEXOPCAPS_BLENDTEXTUREALPHA,         D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9677         {D3DTOP_BLENDFACTORALPHA,          "BLENDFACTORALPHA",          D3DTEXOPCAPS_BLENDFACTORALPHA,          D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9678         {D3DTOP_BLENDTEXTUREALPHAPM,       "BLENDTEXTUREALPHAPM",       D3DTEXOPCAPS_BLENDTEXTUREALPHAPM,       D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9679         {D3DTOP_BLENDCURRENTALPHA,         "BLENDCURRENTALPHA",         D3DTEXOPCAPS_BLENDCURRENTALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9680         {D3DTOP_MODULATEALPHA_ADDCOLOR,    "MODULATEALPHA_ADDCOLOR",    D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR,    D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9681         {D3DTOP_MODULATECOLOR_ADDALPHA,    "MODULATECOLOR_ADDALPHA",    D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA,    D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9682         {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9683         {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9684         /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9685         {D3DTOP_DOTPRODUCT3,               "DOTPRODUCT3",               D3DTEXOPCAPS_DOTPRODUCT3,               D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9686         {D3DTOP_MULTIPLYADD,               "MULTIPLYADD",               D3DTEXOPCAPS_MULTIPLYADD,               D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9687         {D3DTOP_LERP,                      "LERP",                      D3DTEXOPCAPS_LERP,                      D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9688     };
9689
9690     memset(&caps, 0, sizeof(caps));
9691     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9692     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9693
9694     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9695     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9696     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9697     ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9698
9699     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9700     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9701     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9702     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9703     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9704     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9705     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9706     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9707     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9708
9709     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9710     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9711     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9712     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9713     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9714     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9715
9716     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9717     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9718
9719     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9720     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9721     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9722     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9723     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9724     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9725
9726     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9727     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9728
9729     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9730     {
9731         if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9732         {
9733             skip("tex operation %s not supported\n", test_data[i].name);
9734             continue;
9735         }
9736
9737         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9738         ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9739
9740         hr = IDirect3DDevice9_BeginScene(device);
9741         ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9742
9743         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9744         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9745
9746         hr = IDirect3DDevice9_EndScene(device);
9747         ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9748
9749         color = getPixelColor(device, 320, 240);
9750         ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9751                 test_data[i].name, color, test_data[i].result);
9752
9753         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9754         ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9755     }
9756
9757     if (texture) IDirect3DTexture9_Release(texture);
9758     if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9759 }
9760
9761 static void yuv_color_test(IDirect3DDevice9 *device) {
9762     HRESULT hr;
9763     IDirect3DSurface9 *surface = NULL, *target = NULL;
9764     unsigned int fmt, i;
9765     D3DFORMAT format;
9766     const char *fmt_string;
9767     D3DLOCKED_RECT lr;
9768     IDirect3D9 *d3d;
9769     HRESULT color;
9770     DWORD ref_color_left, ref_color_right;
9771
9772     struct {
9773         DWORD in;           /* The input color */
9774         DWORD uyvy_left;    /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9775         DWORD uyvy_right;   /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9776         DWORD yuy2_left;    /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9777         DWORD yuy2_right;   /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9778     } test_data[] = {
9779     /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9780      * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9781      * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9782      * that
9783      */
9784       { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9785       { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9786       { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9787       { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9788       { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9789       { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9790       { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9791       { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9792       { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9793       { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9794       { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9795       { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9796       { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9797       { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9798
9799       { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9800       { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9801       { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9802       { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9803     };
9804
9805     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9806     ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9807     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9808     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9809
9810     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9811     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9812
9813     for(fmt = 0; fmt < 2; fmt++) {
9814         if(fmt == 0) {
9815             format = D3DFMT_UYVY;
9816             fmt_string = "D3DFMT_UYVY";
9817         } else {
9818             format = D3DFMT_YUY2;
9819             fmt_string = "D3DFMT_YUY2";
9820         }
9821
9822         /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9823                        * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9824                        */
9825         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9826                                         D3DRTYPE_SURFACE, format) != D3D_OK) {
9827             skip("%s is not supported\n", fmt_string);
9828             continue;
9829         }
9830
9831         /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9832         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9833         ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9834
9835         for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9836             if(fmt == 0) {
9837                 ref_color_left = test_data[i].uyvy_left;
9838                 ref_color_right = test_data[i].uyvy_right;
9839             } else {
9840                 ref_color_left = test_data[i].yuy2_left;
9841                 ref_color_right = test_data[i].yuy2_right;
9842             }
9843
9844             memset(&lr, 0, sizeof(lr));
9845             hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9846             ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9847             *((DWORD *) lr.pBits) = test_data[i].in;
9848             hr = IDirect3DSurface9_UnlockRect(surface);
9849             ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9850
9851             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9852             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9853             hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9854             ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9855
9856             /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9857              * prevent running into precision problems, read a far left and far right pixel. In the future we may
9858              * want to add tests for the filtered pixels as well.
9859              *
9860              * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9861              * differently, so we need a max diff of 16
9862              */
9863             color = getPixelColor(device, 40, 240);
9864
9865             /* Newer versions of the Nvidia Windows driver mix up the U and V channels, breaking all the tests
9866              * where U != V. Skip the entire test if this bug in this case
9867              */
9868             if (broken(test_data[i].in == 0xff000000 && color == 0x00008800 && format == D3DFMT_UYVY))
9869             {
9870                 skip("Nvidia channel confusion bug detected, skipping YUV tests\n");
9871                 IDirect3DSurface9_Release(surface);
9872                 goto out;
9873             }
9874
9875             ok(color_match(color, ref_color_left, 18),
9876                "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9877                test_data[i].in, color, ref_color_left, fmt_string);
9878             color = getPixelColor(device, 600, 240);
9879             ok(color_match(color, ref_color_right, 18),
9880                "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9881                test_data[i].in, color, ref_color_right, fmt_string);
9882             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9883             ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9884         }
9885         IDirect3DSurface9_Release(surface);
9886     }
9887
9888 out:
9889     IDirect3DSurface9_Release(target);
9890     IDirect3D9_Release(d3d);
9891 }
9892
9893 static void texop_range_test(IDirect3DDevice9 *device)
9894 {
9895     static const struct {
9896         float x, y, z;
9897         D3DCOLOR diffuse;
9898     } quad[] = {
9899         {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9900         {-1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9901         { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9902         { 1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
9903     };
9904     HRESULT hr;
9905     IDirect3DTexture9 *texture;
9906     D3DLOCKED_RECT locked_rect;
9907     D3DCAPS9 caps;
9908     DWORD color;
9909
9910     /* We need ADD and SUBTRACT operations */
9911     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9912     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9913     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
9914         skip("D3DTOP_ADD is not supported, skipping value range test\n");
9915         return;
9916     }
9917     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
9918         skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
9919         return;
9920     }
9921
9922     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9923     ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
9924     /* Stage 1: result = diffuse(=1.0) + diffuse
9925      * stage 2: result = result - tfactor(= 0.5)
9926      */
9927     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9928     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9929     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9930     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9931     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9932     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9933     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9934     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9935     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9936     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9937     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9938     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9939     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9940     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9941
9942     hr = IDirect3DDevice9_BeginScene(device);
9943     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9944     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9945     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9946     hr = IDirect3DDevice9_EndScene(device);
9947     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9948
9949     color = getPixelColor(device, 320, 240);
9950     ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
9951        color);
9952     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9953     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9954
9955     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9956     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9957     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9958     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9959     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
9960     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9961     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9962     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9963     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9964
9965     /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
9966      * stage 2: result = result + diffuse(1.0)
9967      */
9968     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9969     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9970     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9971     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9972     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9973     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9974     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9975     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9976     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9977     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9978     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9979     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9980     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9981     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9982
9983     hr = IDirect3DDevice9_BeginScene(device);
9984     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9985     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9986     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9987     hr = IDirect3DDevice9_EndScene(device);
9988     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9989
9990     color = getPixelColor(device, 320, 240);
9991     ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
9992        color);
9993     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9994     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9995
9996     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9997     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9998     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9999     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10000     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
10001     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10002     IDirect3DTexture9_Release(texture);
10003 }
10004
10005 static void alphareplicate_test(IDirect3DDevice9 *device) {
10006     struct vertex quad[] = {
10007         { -1.0,    -1.0,    0.1,    0x80ff00ff },
10008         {  1.0,    -1.0,    0.1,    0x80ff00ff },
10009         { -1.0,     1.0,    0.1,    0x80ff00ff },
10010         {  1.0,     1.0,    0.1,    0x80ff00ff },
10011     };
10012     HRESULT hr;
10013     DWORD color;
10014
10015     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10016     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10017
10018     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10019     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10020
10021     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10022     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10023     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
10024     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10025
10026     hr = IDirect3DDevice9_BeginScene(device);
10027     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10028     if(SUCCEEDED(hr)) {
10029         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10030         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10031         hr = IDirect3DDevice9_EndScene(device);
10032         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10033     }
10034
10035     color = getPixelColor(device, 320, 240);
10036     ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
10037        color);
10038     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10039     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10040
10041     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10042     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10043
10044 }
10045
10046 static void dp3_alpha_test(IDirect3DDevice9 *device) {
10047     HRESULT hr;
10048     D3DCAPS9 caps;
10049     DWORD color;
10050     struct vertex quad[] = {
10051         { -1.0,    -1.0,    0.1,    0x408080c0 },
10052         {  1.0,    -1.0,    0.1,    0x408080c0 },
10053         { -1.0,     1.0,    0.1,    0x408080c0 },
10054         {  1.0,     1.0,    0.1,    0x408080c0 },
10055     };
10056
10057     memset(&caps, 0, sizeof(caps));
10058     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10059     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10060     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
10061         skip("D3DTOP_DOTPRODUCT3 not supported\n");
10062         return;
10063     }
10064
10065     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10066     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10067
10068     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10069     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10070
10071     /* dp3_x4 r0, diffuse_bias, tfactor_bias
10072      * mov r0.a, diffuse.a
10073      * mov r0, r0.a
10074      *
10075      * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
10076      * 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
10077      * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
10078      */
10079     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
10080     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10081     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10082     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10083     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10084     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10085     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
10086     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10087     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
10088     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10089     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10090     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10091     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
10092     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10093     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10094     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10095     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
10096     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10097
10098     hr = IDirect3DDevice9_BeginScene(device);
10099     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10100     if(SUCCEEDED(hr)) {
10101         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10102         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10103         hr = IDirect3DDevice9_EndScene(device);
10104         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10105     }
10106
10107     color = getPixelColor(device, 320, 240);
10108     ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
10109        color);
10110     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10111     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10112
10113     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10114     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10115     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10116     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10117     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10118     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10119 }
10120
10121 static void zwriteenable_test(IDirect3DDevice9 *device) {
10122     HRESULT hr;
10123     DWORD color;
10124     struct vertex quad1[] = {
10125         { -1.0,  -1.0,  0.1,    0x00ff0000},
10126         { -1.0,   1.0,  0.1,    0x00ff0000},
10127         {  1.0,  -1.0,  0.1,    0x00ff0000},
10128         {  1.0,   1.0,  0.1,    0x00ff0000},
10129     };
10130     struct vertex quad2[] = {
10131         { -1.0,  -1.0,  0.9,    0x0000ff00},
10132         { -1.0,   1.0,  0.9,    0x0000ff00},
10133         {  1.0,  -1.0,  0.9,    0x0000ff00},
10134         {  1.0,   1.0,  0.9,    0x0000ff00},
10135     };
10136
10137     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
10138     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10139
10140     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10141     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10142     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10143     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10144     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10145     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10146     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10147     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10148
10149     hr = IDirect3DDevice9_BeginScene(device);
10150     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10151     if(SUCCEEDED(hr)) {
10152         /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10153          * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10154          * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10155          * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10156          * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10157          * the screen is green, so zenable = D3DZB_FALSE and zwriteenable  = TRUE does NOT write to the z buffer.
10158          */
10159         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10160         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10161         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10162         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10163         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10164         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10165
10166         hr = IDirect3DDevice9_EndScene(device);
10167         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10168     }
10169
10170     color = getPixelColor(device, 320, 240);
10171     ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10172        color);
10173     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10174     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10175
10176     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10177     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10178 }
10179
10180 static void alphatest_test(IDirect3DDevice9 *device) {
10181 #define ALPHATEST_PASSED 0x0000ff00
10182 #define ALPHATEST_FAILED 0x00ff0000
10183     struct {
10184         D3DCMPFUNC  func;
10185         DWORD       color_less;
10186         DWORD       color_equal;
10187         DWORD       color_greater;
10188     } testdata[] = {
10189         {   D3DCMP_NEVER,           ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10190         {   D3DCMP_LESS,            ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10191         {   D3DCMP_EQUAL,           ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10192         {   D3DCMP_LESSEQUAL,       ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10193         {   D3DCMP_GREATER,         ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10194         {   D3DCMP_NOTEQUAL,        ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10195         {   D3DCMP_GREATEREQUAL,    ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10196         {   D3DCMP_ALWAYS,          ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10197     };
10198     unsigned int i, j;
10199     HRESULT hr;
10200     DWORD color;
10201     struct vertex quad[] = {
10202         {   -1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10203         {    1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10204         {   -1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10205         {    1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10206     };
10207     D3DCAPS9 caps;
10208
10209     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10210     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10211     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10212     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10213
10214     for(j = 0; j < 2; j++) {
10215         if(j == 1) {
10216             /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10217              * the alpha test either for performance reasons(floating point RTs) or to work
10218              * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10219              * codepath for ffp and shader in this case, and the test should cover both
10220              */
10221             IDirect3DPixelShader9 *ps;
10222             DWORD shader_code[] = {
10223                 0xffff0101,                                 /* ps_1_1           */
10224                 0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
10225                 0x0000ffff                                  /* end              */
10226             };
10227             memset(&caps, 0, sizeof(caps));
10228             IDirect3DDevice9_GetDeviceCaps(device, &caps);
10229             ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10230             if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10231                 break;
10232             }
10233
10234             hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10235             ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10236             IDirect3DDevice9_SetPixelShader(device, ps);
10237             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10238             IDirect3DPixelShader9_Release(ps);
10239         }
10240
10241         for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10242             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10243             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10244
10245             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10246             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10247             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10248             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10249             hr = IDirect3DDevice9_BeginScene(device);
10250             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10251             if(SUCCEEDED(hr)) {
10252                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10253                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10254                 hr = IDirect3DDevice9_EndScene(device);
10255                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10256             }
10257             color = getPixelColor(device, 320, 240);
10258             ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10259             color, testdata[i].color_less, testdata[i].func);
10260             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10261             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10262
10263             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10264             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10265             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10266             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10267             hr = IDirect3DDevice9_BeginScene(device);
10268             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10269             if(SUCCEEDED(hr)) {
10270                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10271                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10272                 hr = IDirect3DDevice9_EndScene(device);
10273                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10274             }
10275             color = getPixelColor(device, 320, 240);
10276             ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10277             color, testdata[i].color_equal, testdata[i].func);
10278             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10279             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10280
10281             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10282             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10283             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10284             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10285             hr = IDirect3DDevice9_BeginScene(device);
10286             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10287             if(SUCCEEDED(hr)) {
10288                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10289                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10290                 hr = IDirect3DDevice9_EndScene(device);
10291                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10292             }
10293             color = getPixelColor(device, 320, 240);
10294             ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10295             color, testdata[i].color_greater, testdata[i].func);
10296             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10297             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10298         }
10299     }
10300
10301     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10302     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10303     IDirect3DDevice9_SetPixelShader(device, NULL);
10304     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10305 }
10306
10307 static void sincos_test(IDirect3DDevice9 *device) {
10308     const DWORD sin_shader_code[] = {
10309         0xfffe0200,                                                                 /* vs_2_0                       */
10310         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10311         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10312         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10313         0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.y, r1.x, c0, c1    */
10314         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10315         0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002,                             /* mul oPos.y, r0.y, c2.w       */
10316         0x02000001, 0xd00f0000, 0xa0a60002,                                         /* mov oD0, c2.zyzz             */
10317         0x0000ffff                                                                  /* end                          */
10318     };
10319     const DWORD cos_shader_code[] = {
10320         0xfffe0200,                                                                 /* vs_2_0                       */
10321         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10322         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10323         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10324         0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.x, r1.x, c0, c1    */
10325         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10326         0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002,                             /* mul oPos.y, r0.x, c2.w       */
10327         0x02000001, 0xd00f0000, 0xa0a90002,                                         /* mov oD0, c2.yzzz             */
10328         0x0000ffff                                                                  /* end                          */
10329     };
10330     IDirect3DVertexShader9 *sin_shader, *cos_shader;
10331     HRESULT hr;
10332     struct {
10333         float x, y, z;
10334     } data[1280];
10335     unsigned int i;
10336     float sincosc1[4] = {D3DSINCOSCONST1};
10337     float sincosc2[4] = {D3DSINCOSCONST2};
10338
10339     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10340     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10341
10342     hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10343     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10344     hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10345     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10346     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10347     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10348     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10349     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10350     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10351     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10352
10353     /* Generate a point from -1 to 1 every 0.5 pixels */
10354     for(i = 0; i < 1280; i++) {
10355         data[i].x = (-640.0 + i) / 640.0;
10356         data[i].y = 0.0;
10357         data[i].z = 0.1;
10358     }
10359
10360     hr = IDirect3DDevice9_BeginScene(device);
10361     if(SUCCEEDED(hr)) {
10362         hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10363         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10364         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10365         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10366
10367         hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10368         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10369         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10370         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10371
10372         hr = IDirect3DDevice9_EndScene(device);
10373         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10374     }
10375     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10376     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10377     /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10378
10379     IDirect3DDevice9_SetVertexShader(device, NULL);
10380     IDirect3DVertexShader9_Release(sin_shader);
10381     IDirect3DVertexShader9_Release(cos_shader);
10382 }
10383
10384 static void loop_index_test(IDirect3DDevice9 *device) {
10385     const DWORD shader_code[] = {
10386         0xfffe0200,                                                 /* vs_2_0                   */
10387         0x0200001f, 0x80000000, 0x900f0000,                         /* dcl_position v0          */
10388         0x02000001, 0x800f0000, 0xa0e40000,                         /* mov r0, c0               */
10389         0x0200001b, 0xf0e40800, 0xf0e40000,                         /* loop aL, i0              */
10390         0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1]    */
10391         0x0000001d,                                                 /* endloop                  */
10392         0x02000001, 0xc00f0000, 0x90e40000,                         /* mov oPos, v0             */
10393         0x02000001, 0xd00f0000, 0x80e40000,                         /* mov oD0, r0              */
10394         0x0000ffff                                                  /* END                      */
10395     };
10396     IDirect3DVertexShader9 *shader;
10397     HRESULT hr;
10398     DWORD color;
10399     const float quad[] = {
10400         -1.0,   -1.0,   0.1,
10401          1.0,   -1.0,   0.1,
10402         -1.0,    1.0,   0.1,
10403          1.0,    1.0,   0.1
10404     };
10405     const float zero[4] = {0, 0, 0, 0};
10406     const float one[4] = {1, 1, 1, 1};
10407     int i0[4] = {2, 10, -3, 0};
10408     float values[4];
10409
10410     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10411     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10412     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10413     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10414     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10415     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10416     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10417     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10418
10419     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10420     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10421     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10422     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10423     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10424     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10425     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10426     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10427     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10428     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10429     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10430     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10431     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10432     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10433     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10434     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10435     values[0] = 1.0;
10436     values[1] = 1.0;
10437     values[2] = 0.0;
10438     values[3] = 0.0;
10439     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10440     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10441     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10442     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10443     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10444     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10445     values[0] = -1.0;
10446     values[1] = 0.0;
10447     values[2] = 0.0;
10448     values[3] = 0.0;
10449     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10450     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10451     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10452     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10453     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10454     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10455     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10456     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10457     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10458     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10459
10460     hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10461     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10462
10463     hr = IDirect3DDevice9_BeginScene(device);
10464     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10465     if(SUCCEEDED(hr))
10466     {
10467         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10468         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10469         hr = IDirect3DDevice9_EndScene(device);
10470         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10471     }
10472     color = getPixelColor(device, 320, 240);
10473     ok(color_match(color, 0x0000ff00, 1),
10474        "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10475     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10476     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10477
10478     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10479     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10480     IDirect3DVertexShader9_Release(shader);
10481 }
10482
10483 static void sgn_test(IDirect3DDevice9 *device) {
10484     const DWORD shader_code[] = {
10485         0xfffe0200,                                                             /* vs_2_0                       */
10486         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position o0              */
10487         0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10488         0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0   */
10489         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
10490         0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002,             /* sgn r0, c0, r1, r2           */
10491         0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001,                         /* add oD0, r0, c1              */
10492         0x0000ffff                                                              /* end                          */
10493     };
10494     IDirect3DVertexShader9 *shader;
10495     HRESULT hr;
10496     DWORD color;
10497     const float quad[] = {
10498         -1.0,   -1.0,   0.1,
10499          1.0,   -1.0,   0.1,
10500         -1.0,    1.0,   0.1,
10501          1.0,    1.0,   0.1
10502     };
10503
10504     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10505     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10506     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10507     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10508     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10509     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10510     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10511     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10512
10513     hr = IDirect3DDevice9_BeginScene(device);
10514     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10515     if(SUCCEEDED(hr))
10516     {
10517         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10518         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10519         hr = IDirect3DDevice9_EndScene(device);
10520         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10521     }
10522     color = getPixelColor(device, 320, 240);
10523     ok(color_match(color, 0x008000ff, 1),
10524        "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10525     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10526     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10527
10528     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10529     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10530     IDirect3DVertexShader9_Release(shader);
10531 }
10532
10533 static void viewport_test(IDirect3DDevice9 *device) {
10534     HRESULT hr;
10535     DWORD color;
10536     D3DVIEWPORT9 vp, old_vp;
10537     BOOL draw_failed = TRUE;
10538     const float quad[] =
10539     {
10540         -0.5,   -0.5,   0.1,
10541          0.5,   -0.5,   0.1,
10542         -0.5,    0.5,   0.1,
10543          0.5,    0.5,   0.1
10544     };
10545
10546     memset(&old_vp, 0, sizeof(old_vp));
10547     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10548     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10549
10550     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10551     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10552
10553     /* Test a viewport with Width and Height bigger than the surface dimensions
10554      *
10555      * TODO: Test Width < surface.width, but X + Width > surface.width
10556      * TODO: Test Width < surface.width, what happens with the height?
10557      *
10558      * The expected behavior is that the viewport behaves like the "default"
10559      * viewport with X = Y = 0, Width = surface_width, Height = surface_height,
10560      * MinZ = 0.0, MaxZ = 1.0.
10561      *
10562      * Starting with Windows 7 the behavior among driver versions is not
10563      * consistent. The SetViewport call is accepted on all drivers. Some
10564      * drivers(older nvidia ones) refuse to draw and return an error. Newer
10565      * nvidia drivers draw, but use the actual values in the viewport and only
10566      * display the upper left part on the surface.
10567      */
10568     memset(&vp, 0, sizeof(vp));
10569     vp.X = 0;
10570     vp.Y = 0;
10571     vp.Width = 10000;
10572     vp.Height = 10000;
10573     vp.MinZ = 0.0;
10574     vp.MaxZ = 0.0;
10575     hr = IDirect3DDevice9_SetViewport(device, &vp);
10576     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10577
10578     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10579     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10580     hr = IDirect3DDevice9_BeginScene(device);
10581     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10582     if(SUCCEEDED(hr))
10583     {
10584         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10585         ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "DrawPrimitiveUP failed (%08x)\n", hr);
10586         draw_failed = FAILED(hr);
10587         hr = IDirect3DDevice9_EndScene(device);
10588         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10589     }
10590
10591     if(!draw_failed)
10592     {
10593         color = getPixelColor(device, 158, 118);
10594         ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10595         color = getPixelColor(device, 162, 118);
10596         ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10597         color = getPixelColor(device, 158, 122);
10598         ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10599         color = getPixelColor(device, 162, 122);
10600         ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (162,122) has color %08x\n", color);
10601
10602         color = getPixelColor(device, 478, 358);
10603         ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (478,358 has color %08x\n", color);
10604         color = getPixelColor(device, 482, 358);
10605         ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10606         color = getPixelColor(device, 478, 362);
10607         ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10608         color = getPixelColor(device, 482, 362);
10609         ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10610     }
10611
10612     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10613     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10614
10615     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10616     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10617 }
10618
10619 /* This test tests depth clamping / clipping behaviour:
10620  *   - With software vertex processing, depth values are clamped to the
10621  *     minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
10622  *     when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
10623  *     same as regular vertices here.
10624  *   - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
10625  *     Normal vertices are always clipped. Pretransformed vertices are
10626  *     clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
10627  *   - The viewport's MinZ/MaxZ is irrelevant for this.
10628  */
10629 static void depth_clamp_test(IDirect3DDevice9 *device)
10630 {
10631     const struct tvertex quad1[] =
10632     {
10633         {  0.0f,   0.0f,  5.0f, 1.0f, 0xff002b7f},
10634         {640.0f,   0.0f,  5.0f, 1.0f, 0xff002b7f},
10635         {  0.0f, 480.0f,  5.0f, 1.0f, 0xff002b7f},
10636         {640.0f, 480.0f,  5.0f, 1.0f, 0xff002b7f},
10637     };
10638     const struct tvertex quad2[] =
10639     {
10640         {  0.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
10641         {640.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
10642         {  0.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
10643         {640.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
10644     };
10645     const struct tvertex quad3[] =
10646     {
10647         {112.0f, 108.0f,  5.0f, 1.0f, 0xffffffff},
10648         {208.0f, 108.0f,  5.0f, 1.0f, 0xffffffff},
10649         {112.0f, 204.0f,  5.0f, 1.0f, 0xffffffff},
10650         {208.0f, 204.0f,  5.0f, 1.0f, 0xffffffff},
10651     };
10652     const struct tvertex quad4[] =
10653     {
10654         { 42.0f,  41.0f, 10.0f, 1.0f, 0xffffffff},
10655         {112.0f,  41.0f, 10.0f, 1.0f, 0xffffffff},
10656         { 42.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
10657         {112.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
10658     };
10659     const struct vertex quad5[] =
10660     {
10661         { -0.5f,   0.5f, 10.0f,       0xff14f914},
10662         {  0.5f,   0.5f, 10.0f,       0xff14f914},
10663         { -0.5f,  -0.5f, 10.0f,       0xff14f914},
10664         {  0.5f,  -0.5f, 10.0f,       0xff14f914},
10665     };
10666     const struct vertex quad6[] =
10667     {
10668         { -1.0f,   0.5f, 10.0f,      0xfff91414},
10669         {  1.0f,   0.5f, 10.0f,      0xfff91414},
10670         { -1.0f,  0.25f, 10.0f,      0xfff91414},
10671         {  1.0f,  0.25f, 10.0f,      0xfff91414},
10672     };
10673
10674     D3DVIEWPORT9 vp;
10675     D3DCOLOR color;
10676     D3DCAPS9 caps;
10677     HRESULT hr;
10678
10679     vp.X = 0;
10680     vp.Y = 0;
10681     vp.Width = 640;
10682     vp.Height = 480;
10683     vp.MinZ = 0.0;
10684     vp.MaxZ = 7.5;
10685
10686     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10687     ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
10688
10689     hr = IDirect3DDevice9_SetViewport(device, &vp);
10690     if(FAILED(hr))
10691     {
10692         /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
10693          * the tests because the 7.5 is just intended to show that it doesn't have
10694          * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
10695          * viewport and continue.
10696          */
10697         ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
10698         vp.MaxZ = 1.0;
10699         hr = IDirect3DDevice9_SetViewport(device, &vp);
10700     }
10701     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10702
10703     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
10704     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10705
10706     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10707     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10708     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10709     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10710     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10711     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10712     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10713     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10714
10715     hr = IDirect3DDevice9_BeginScene(device);
10716     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10717
10718     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10719     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10720
10721     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10722     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10723     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10724     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10725
10726     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10727     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10728
10729     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10730     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10731     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
10732     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10733
10734     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10735     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10736
10737     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10738     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10739
10740     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
10741     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10742
10743     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10744     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10745
10746     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
10747     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10748
10749     hr = IDirect3DDevice9_EndScene(device);
10750     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10751
10752     if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
10753     {
10754         color = getPixelColor(device, 75, 75);
10755         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10756         color = getPixelColor(device, 150, 150);
10757         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10758         color = getPixelColor(device, 320, 240);
10759         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10760         color = getPixelColor(device, 320, 330);
10761         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10762         color = getPixelColor(device, 320, 330);
10763         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10764     }
10765     else
10766     {
10767         color = getPixelColor(device, 75, 75);
10768         ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10769         color = getPixelColor(device, 150, 150);
10770         ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10771         color = getPixelColor(device, 320, 240);
10772         ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10773         color = getPixelColor(device, 320, 330);
10774         ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10775         color = getPixelColor(device, 320, 330);
10776         ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10777     }
10778
10779     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10780     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10781
10782     vp.MinZ = 0.0;
10783     vp.MaxZ = 1.0;
10784     hr = IDirect3DDevice9_SetViewport(device, &vp);
10785     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10786 }
10787
10788 static void depth_bounds_test(IDirect3DDevice9 *device)
10789 {
10790     const struct tvertex quad1[] =
10791     {
10792         {    0,    0, 0.0f, 1, 0xfff9e814},
10793         {  640,    0, 0.0f, 1, 0xfff9e814},
10794         {    0,  480, 1.0f, 1, 0xfff9e814},
10795         {  640,  480, 1.0f, 1, 0xfff9e814},
10796     };
10797     const struct tvertex quad2[] =
10798     {
10799         {    0,    0,  0.6f, 1, 0xff002b7f},
10800         {  640,    0,  0.6f, 1, 0xff002b7f},
10801         {    0,  480,  0.6f, 1, 0xff002b7f},
10802         {  640,  480,  0.6f, 1, 0xff002b7f},
10803     };
10804     const struct tvertex quad3[] =
10805     {
10806         {    0,  100, 0.6f, 1, 0xfff91414},
10807         {  640,  100, 0.6f, 1, 0xfff91414},
10808         {    0,  160, 0.6f, 1, 0xfff91414},
10809         {  640,  160, 0.6f, 1, 0xfff91414},
10810     };
10811
10812     union {
10813         DWORD d;
10814         float f;
10815     } tmpvalue;
10816
10817     IDirect3D9 *d3d = NULL;
10818     IDirect3DSurface9 *offscreen_surface = NULL;
10819     D3DCOLOR color;
10820     HRESULT hr;
10821
10822     IDirect3DDevice9_GetDirect3D(device, &d3d);
10823     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
10824             0,  D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK) {
10825         skip("No NVDB (depth bounds test) support\n");
10826         IDirect3D9_Release(d3d);
10827         return;
10828     }
10829     IDirect3D9_Release(d3d);
10830
10831     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
10832             MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
10833     ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
10834     if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
10835
10836     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
10837     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10838
10839     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10840     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10841     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
10842     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10843     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10844     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10845     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
10846     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10847
10848
10849     hr = IDirect3DDevice9_BeginScene(device);
10850     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10851
10852     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10853     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10854
10855     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10856     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10857
10858     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
10859     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10860
10861     tmpvalue.f = 0.625;
10862     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
10863     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10864
10865     tmpvalue.f = 0.75;
10866     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
10867     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10868
10869     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10870     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10871
10872     tmpvalue.f = 0.75;
10873     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
10874     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10875
10876     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10877     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10878
10879     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
10880     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10881
10882     hr = IDirect3DDevice9_EndScene(device);
10883     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10884
10885     color = getPixelColor(device, 150, 130);
10886     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10887     color = getPixelColor(device, 150, 200);
10888     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10889     color = getPixelColor(device, 150, 300-5);
10890     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10891     color = getPixelColor(device, 150, 300+5);
10892     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
10893     color = getPixelColor(device, 150, 330);
10894     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10895     color = getPixelColor(device, 150, 360-5);
10896     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
10897     color = getPixelColor(device, 150, 360+5);
10898     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10899
10900     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10901     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10902 }
10903
10904 static void depth_buffer_test(IDirect3DDevice9 *device)
10905 {
10906     static const struct vertex quad1[] =
10907     {
10908         { -1.0,  1.0, 0.33f, 0xff00ff00},
10909         {  1.0,  1.0, 0.33f, 0xff00ff00},
10910         { -1.0, -1.0, 0.33f, 0xff00ff00},
10911         {  1.0, -1.0, 0.33f, 0xff00ff00},
10912     };
10913     static const struct vertex quad2[] =
10914     {
10915         { -1.0,  1.0, 0.50f, 0xffff00ff},
10916         {  1.0,  1.0, 0.50f, 0xffff00ff},
10917         { -1.0, -1.0, 0.50f, 0xffff00ff},
10918         {  1.0, -1.0, 0.50f, 0xffff00ff},
10919     };
10920     static const struct vertex quad3[] =
10921     {
10922         { -1.0,  1.0, 0.66f, 0xffff0000},
10923         {  1.0,  1.0, 0.66f, 0xffff0000},
10924         { -1.0, -1.0, 0.66f, 0xffff0000},
10925         {  1.0, -1.0, 0.66f, 0xffff0000},
10926     };
10927     static const DWORD expected_colors[4][4] =
10928     {
10929         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10930         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10931         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
10932         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
10933     };
10934
10935     IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
10936     unsigned int i, j;
10937     D3DVIEWPORT9 vp;
10938     D3DCOLOR color;
10939     HRESULT hr;
10940
10941     vp.X = 0;
10942     vp.Y = 0;
10943     vp.Width = 640;
10944     vp.Height = 480;
10945     vp.MinZ = 0.0;
10946     vp.MaxZ = 1.0;
10947
10948     hr = IDirect3DDevice9_SetViewport(device, &vp);
10949     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10950
10951     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10952     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10953     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10954     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10955     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10956     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10957     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10958     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10959     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10960     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10961
10962     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
10963     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10964     hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
10965             D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
10966     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10967     hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
10968             D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
10969     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10970     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
10971             D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
10972     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10973
10974     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
10975     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10976     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
10977     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10978
10979     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10980     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10981     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10982     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10983
10984     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
10985     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10986     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
10987     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10988
10989     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
10990     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10991     hr = IDirect3DDevice9_BeginScene(device);
10992     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10993     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10994     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10995     hr = IDirect3DDevice9_EndScene(device);
10996     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10997
10998     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10999     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11000     IDirect3DSurface9_Release(backbuffer);
11001     IDirect3DSurface9_Release(rt3);
11002     IDirect3DSurface9_Release(rt2);
11003     IDirect3DSurface9_Release(rt1);
11004
11005     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11006     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11007
11008     hr = IDirect3DDevice9_BeginScene(device);
11009     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11010     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11011     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11012     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11013     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11014     hr = IDirect3DDevice9_EndScene(device);
11015     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11016
11017     for (i = 0; i < 4; ++i)
11018     {
11019         for (j = 0; j < 4; ++j)
11020         {
11021             unsigned int x = 80 * ((2 * j) + 1);
11022             unsigned int y = 60 * ((2 * i) + 1);
11023             color = getPixelColor(device, x, y);
11024             ok(color_match(color, expected_colors[i][j], 0),
11025                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11026         }
11027     }
11028
11029     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11030     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11031 }
11032
11033 /* Test that partial depth copies work the way they're supposed to. The clear
11034  * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
11035  * the following draw should only copy back the part that was modified. */
11036 static void depth_buffer2_test(IDirect3DDevice9 *device)
11037 {
11038     static const struct vertex quad[] =
11039     {
11040         { -1.0,  1.0, 0.66f, 0xffff0000},
11041         {  1.0,  1.0, 0.66f, 0xffff0000},
11042         { -1.0, -1.0, 0.66f, 0xffff0000},
11043         {  1.0, -1.0, 0.66f, 0xffff0000},
11044     };
11045
11046     IDirect3DSurface9 *backbuffer, *rt1, *rt2;
11047     unsigned int i, j;
11048     D3DVIEWPORT9 vp;
11049     D3DCOLOR color;
11050     HRESULT hr;
11051
11052     vp.X = 0;
11053     vp.Y = 0;
11054     vp.Width = 640;
11055     vp.Height = 480;
11056     vp.MinZ = 0.0;
11057     vp.MaxZ = 1.0;
11058
11059     hr = IDirect3DDevice9_SetViewport(device, &vp);
11060     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11061
11062     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11063     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11064     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11065     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11066     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11067     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11068     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11069     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11070     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11071     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11072
11073     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11074             D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
11075     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11076     hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
11077             D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
11078     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11079     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11080     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11081
11082     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11083     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11084     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11085     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11086
11087     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11088     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11089     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
11090     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11091
11092     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11093     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11094     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11095     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11096
11097     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11098     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11099     IDirect3DSurface9_Release(backbuffer);
11100     IDirect3DSurface9_Release(rt2);
11101     IDirect3DSurface9_Release(rt1);
11102
11103     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11104     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11105
11106     hr = IDirect3DDevice9_BeginScene(device);
11107     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11108     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11109     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11110     hr = IDirect3DDevice9_EndScene(device);
11111     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11112
11113     for (i = 0; i < 4; ++i)
11114     {
11115         for (j = 0; j < 4; ++j)
11116         {
11117             unsigned int x = 80 * ((2 * j) + 1);
11118             unsigned int y = 60 * ((2 * i) + 1);
11119             color = getPixelColor(device, x, y);
11120             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
11121                     "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
11122         }
11123     }
11124
11125     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11126     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11127 }
11128
11129 static void depth_blit_test(IDirect3DDevice9 *device)
11130 {
11131     static const struct vertex quad1[] =
11132     {
11133         { -1.0,  1.0, 0.50f, 0xff00ff00},
11134         {  1.0,  1.0, 0.50f, 0xff00ff00},
11135         { -1.0, -1.0, 0.50f, 0xff00ff00},
11136         {  1.0, -1.0, 0.50f, 0xff00ff00},
11137     };
11138     static const struct vertex quad2[] =
11139     {
11140         { -1.0,  1.0, 0.66f, 0xff0000ff},
11141         {  1.0,  1.0, 0.66f, 0xff0000ff},
11142         { -1.0, -1.0, 0.66f, 0xff0000ff},
11143         {  1.0, -1.0, 0.66f, 0xff0000ff},
11144     };
11145     static const DWORD expected_colors[4][4] =
11146     {
11147         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11148         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11149         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
11150         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
11151     };
11152
11153     IDirect3DSurface9 *backbuffer, *ds1, *ds2;
11154     RECT src_rect, dst_rect;
11155     unsigned int i, j;
11156     D3DVIEWPORT9 vp;
11157     D3DCOLOR color;
11158     HRESULT hr;
11159
11160     vp.X = 0;
11161     vp.Y = 0;
11162     vp.Width = 640;
11163     vp.Height = 480;
11164     vp.MinZ = 0.0;
11165     vp.MaxZ = 1.0;
11166
11167     hr = IDirect3DDevice9_SetViewport(device, &vp);
11168     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11169
11170     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11171     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11172     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
11173     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11174     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
11175     ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
11176     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
11177     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11178
11179     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11180     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11181     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11182     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11183     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11184     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11185     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11186     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11187
11188     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11189     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11190     SetRect(&dst_rect, 0, 0, 480, 360);
11191     hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
11192     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11193     SetRect(&dst_rect, 0, 0, 320, 240);
11194     hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
11195     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11196
11197     /* Partial blit. */
11198     SetRect(&src_rect, 0, 0, 320, 240);
11199     SetRect(&dst_rect, 0, 0, 320, 240);
11200     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11201     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11202     /* Flipped. */
11203     SetRect(&src_rect, 0, 0, 640, 480);
11204     SetRect(&dst_rect, 0, 480, 640, 0);
11205     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11206     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11207     /* Full, explicit. */
11208     SetRect(&src_rect, 0, 0, 640, 480);
11209     SetRect(&dst_rect, 0, 0, 640, 480);
11210     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11211     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11212     /* Filtered blit. */
11213     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
11214     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11215     /* Depth -> color blit.*/
11216     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
11217     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11218     IDirect3DSurface9_Release(backbuffer);
11219
11220     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
11221     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11222     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
11223     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11224     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
11225     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11226     IDirect3DSurface9_Release(ds2);
11227     IDirect3DSurface9_Release(ds1);
11228
11229     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11230     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11231     hr = IDirect3DDevice9_BeginScene(device);
11232     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11233     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11234     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11235     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11236     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11237     hr = IDirect3DDevice9_EndScene(device);
11238     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11239
11240     for (i = 0; i < 4; ++i)
11241     {
11242         for (j = 0; j < 4; ++j)
11243         {
11244             unsigned int x = 80 * ((2 * j) + 1);
11245             unsigned int y = 60 * ((2 * i) + 1);
11246             color = getPixelColor(device, x, y);
11247             ok(color_match(color, expected_colors[i][j], 0),
11248                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11249         }
11250     }
11251
11252     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11253     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11254 }
11255
11256 static void intz_test(IDirect3DDevice9 *device)
11257 {
11258     static const DWORD ps_code[] =
11259     {
11260         0xffff0200,                                                             /* ps_2_0                       */
11261         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
11262         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
11263         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
11264         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
11265         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
11266         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
11267         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
11268         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
11269         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov oC0, r1                  */
11270         0x0000ffff,                                                             /* end                          */
11271     };
11272     struct
11273     {
11274         float x, y, z;
11275         float s, t, p, q;
11276     }
11277     quad[] =
11278     {
11279         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11280         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11281         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11282         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11283     };
11284     struct
11285     {
11286         UINT x, y;
11287         D3DCOLOR color;
11288     }
11289     expected_colors[] =
11290     {
11291         { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11292         {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11293         {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11294         {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11295         { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11296         {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11297         {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11298         {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11299     };
11300
11301     IDirect3DSurface9 *original_ds, *original_rt, *rt;
11302     IDirect3DTexture9 *texture;
11303     IDirect3DPixelShader9 *ps;
11304     IDirect3DSurface9 *ds;
11305     IDirect3D9 *d3d9;
11306     D3DCAPS9 caps;
11307     HRESULT hr;
11308     UINT i;
11309
11310     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11311     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11312     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11313     {
11314         skip("No pixel shader 2.0 support, skipping INTZ test.\n");
11315         return;
11316     }
11317
11318     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11319     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11320
11321     hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11322             D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
11323     if (FAILED(hr))
11324     {
11325         skip("No INTZ support, skipping INTZ test.\n");
11326         return;
11327     }
11328
11329     IDirect3D9_Release(d3d9);
11330
11331     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11332     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11333     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11334     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11335
11336     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
11337             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11338     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11339     hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
11340             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11341     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11342     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11343     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11344
11345     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11346     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11347     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11348     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11349     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11350     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11351     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11352     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11353     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11354     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11355
11356     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11357     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11358     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11359     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11360     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11361     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11362     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11363     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11364     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11365     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11366
11367     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11368     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11369     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11370     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11371     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11372     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11373     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11374     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11375
11376     /* Setup the depth/stencil surface. */
11377     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11378     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11379
11380     hr = IDirect3DDevice9_BeginScene(device);
11381     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11382     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11383     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11384     hr = IDirect3DDevice9_EndScene(device);
11385     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11386
11387     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11388     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11389     IDirect3DSurface9_Release(ds);
11390     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11391     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11392     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11393     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11394     hr = IDirect3DDevice9_SetPixelShader(device, ps);
11395     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11396
11397     /* Read the depth values back. */
11398     hr = IDirect3DDevice9_BeginScene(device);
11399     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11400     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11401     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11402     hr = IDirect3DDevice9_EndScene(device);
11403     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11404
11405     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11406     {
11407         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11408         ok(color_match(color, expected_colors[i].color, 1),
11409                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11410                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11411     }
11412
11413     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11414     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11415
11416     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11417     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11418     IDirect3DSurface9_Release(original_ds);
11419     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11420     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11421     IDirect3DTexture9_Release(texture);
11422     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11423     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11424     IDirect3DPixelShader9_Release(ps);
11425
11426     IDirect3DSurface9_Release(original_rt);
11427     IDirect3DSurface9_Release(rt);
11428 }
11429
11430 static void shadow_test(IDirect3DDevice9 *device)
11431 {
11432     static const DWORD ps_code[] =
11433     {
11434         0xffff0200,                                                             /* ps_2_0                       */
11435         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
11436         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
11437         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
11438         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
11439         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
11440         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
11441         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
11442         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
11443         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov 0C0, r1                  */
11444         0x0000ffff,                                                             /* end                          */
11445     };
11446     struct
11447     {
11448         D3DFORMAT format;
11449         const char *name;
11450     }
11451     formats[] =
11452     {
11453         {D3DFMT_D16_LOCKABLE,   "D3DFMT_D16_LOCKABLE"},
11454         {D3DFMT_D32,            "D3DFMT_D32"},
11455         {D3DFMT_D15S1,          "D3DFMT_D15S1"},
11456         {D3DFMT_D24S8,          "D3DFMT_D24S8"},
11457         {D3DFMT_D24X8,          "D3DFMT_D24X8"},
11458         {D3DFMT_D24X4S4,        "D3DFMT_D24X4S4"},
11459         {D3DFMT_D16,            "D3DFMT_D16"},
11460         {D3DFMT_D32F_LOCKABLE,  "D3DFMT_D32F_LOCKABLE"},
11461         {D3DFMT_D24FS8,         "D3DFMT_D24FS8"},
11462     };
11463     struct
11464     {
11465         float x, y, z;
11466         float s, t, p, q;
11467     }
11468     quad[] =
11469     {
11470         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
11471         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
11472         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
11473         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
11474     };
11475     struct
11476     {
11477         UINT x, y;
11478         D3DCOLOR color;
11479     }
11480     expected_colors[] =
11481     {
11482         {400,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11483         {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11484         {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11485         {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11486         {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11487         { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11488         { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11489         {240,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11490     };
11491
11492     IDirect3DSurface9 *original_ds, *original_rt, *rt;
11493     IDirect3DPixelShader9 *ps;
11494     IDirect3D9 *d3d9;
11495     D3DCAPS9 caps;
11496     HRESULT hr;
11497     UINT i;
11498
11499     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11500     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11501     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11502     {
11503         skip("No pixel shader 2.0 support, skipping shadow test.\n");
11504         return;
11505     }
11506
11507     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11508     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11509     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11510     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11511     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11512     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11513
11514     hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
11515             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11516     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11517     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11518     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11519
11520     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11521     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11522     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11523     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11524     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11525     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11526     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11527     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11528     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11529     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11530
11531     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11532     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11533     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11534     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11535     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11536     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11537     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11538     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11539     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11540     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11541
11542     for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
11543     {
11544         D3DFORMAT format = formats[i].format;
11545         IDirect3DTexture9 *texture;
11546         IDirect3DSurface9 *ds;
11547         unsigned int j;
11548
11549         hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11550                 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
11551         if (FAILED(hr)) continue;
11552
11553         hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
11554                 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
11555         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11556
11557         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11558         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11559
11560         hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11561         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11562
11563         hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11564         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11565
11566         IDirect3DDevice9_SetPixelShader(device, NULL);
11567         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11568
11569         /* Setup the depth/stencil surface. */
11570         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11571         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11572
11573         hr = IDirect3DDevice9_BeginScene(device);
11574         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11575         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11576         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11577         hr = IDirect3DDevice9_EndScene(device);
11578         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11579
11580         hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11581         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11582         IDirect3DSurface9_Release(ds);
11583
11584         hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11585         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11586
11587         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11588         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11589
11590         hr = IDirect3DDevice9_SetPixelShader(device, ps);
11591         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11592
11593         /* Do the actual shadow mapping. */
11594         hr = IDirect3DDevice9_BeginScene(device);
11595         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11596         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11597         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11598         hr = IDirect3DDevice9_EndScene(device);
11599         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11600
11601         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11602         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11603         IDirect3DTexture9_Release(texture);
11604
11605         for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
11606         {
11607             D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
11608             ok(color_match(color, expected_colors[j].color, 0),
11609                     "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
11610                     expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
11611                     formats[i].name, color);
11612         }
11613
11614         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11615         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11616     }
11617
11618     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11619     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11620     IDirect3DPixelShader9_Release(ps);
11621
11622     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11623     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11624     IDirect3DSurface9_Release(original_ds);
11625
11626     IDirect3DSurface9_Release(original_rt);
11627     IDirect3DSurface9_Release(rt);
11628
11629     IDirect3D9_Release(d3d9);
11630 }
11631
11632 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
11633 {
11634     const struct vertex quad1[] =
11635     {
11636         {-1.0f, -1.0f, 0.0f, 0xfff9e814},
11637         { 1.0f, -1.0f, 0.0f, 0xfff9e814},
11638         {-1.0f,  1.0f, 0.0f, 0xfff9e814},
11639         { 1.0f,  1.0f, 0.0f, 0xfff9e814},
11640     };
11641     const struct vertex quad2[] =
11642     {
11643         {-1.0f, -1.0f, 0.0f, 0xff002b7f},
11644         { 1.0f, -1.0f, 0.0f, 0xff002b7f},
11645         {-1.0f,  1.0f, 0.0f, 0xff002b7f},
11646         { 1.0f,  1.0f, 0.0f, 0xff002b7f},
11647     };
11648     D3DCOLOR color;
11649     HRESULT hr;
11650
11651     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
11652     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11653
11654     hr = IDirect3DDevice9_BeginScene(device);
11655     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11656
11657     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11658     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11659
11660     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
11661     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11662     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11663     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11664
11665     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
11666     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11667     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11668     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11669
11670     hr = IDirect3DDevice9_EndScene(device);
11671     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11672
11673     color = getPixelColor(device, 1, 240);
11674     ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
11675     color = getPixelColor(device, 638, 240);
11676     ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
11677
11678     color = getPixelColor(device, 1, 241);
11679     ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
11680     color = getPixelColor(device, 638, 241);
11681     ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
11682 }
11683
11684 static void clip_planes_test(IDirect3DDevice9 *device)
11685 {
11686     const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
11687
11688     const DWORD shader_code[] = {
11689         0xfffe0200, /* vs_2_0 */
11690         0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11691         0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
11692         0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
11693         0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
11694         0x0000ffff /* end */
11695     };
11696     IDirect3DVertexShader9 *shader;
11697
11698     IDirect3DTexture9 *offscreen = NULL;
11699     IDirect3DSurface9 *offscreen_surface, *original_rt;
11700     HRESULT hr;
11701
11702     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11703     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11704
11705     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11706     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11707     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
11708     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11709     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11710     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11711     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
11712     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11713
11714     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11715     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
11716     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11717     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
11718
11719     IDirect3DDevice9_SetClipPlane(device, 0, plane0);
11720
11721     clip_planes(device, "Onscreen FFP");
11722
11723     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
11724     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11725     hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
11726     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11727     hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
11728     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11729
11730     clip_planes(device, "Offscreen FFP");
11731
11732     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11733     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11734
11735     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
11736     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
11737     IDirect3DDevice9_SetVertexShader(device, shader);
11738     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
11739
11740     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11741     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11742
11743     clip_planes(device, "Onscreen vertex shader");
11744
11745     hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
11746     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11747
11748     clip_planes(device, "Offscreen vertex shader");
11749
11750     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11751     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11752
11753     IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
11754     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11755     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
11756     IDirect3DVertexShader9_Release(shader);
11757     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11758     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11759     IDirect3DSurface9_Release(original_rt);
11760     IDirect3DSurface9_Release(offscreen_surface);
11761     IDirect3DTexture9_Release(offscreen);
11762 }
11763
11764 static void fp_special_test(IDirect3DDevice9 *device)
11765 {
11766     static const DWORD vs_header[] =
11767     {
11768         0xfffe0200,                                                             /* vs_2_0                       */
11769         0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0   */
11770         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
11771         0x0200001f, 0x80000005, 0x900f0001,                                     /* dcl_texcoord0 v1             */
11772     };
11773
11774     static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001};         /* log r0.x, v1.x               */
11775     static const DWORD vs_pow[] =
11776             {0x03000020, 0x80010000, 0x90000001, 0x90000001};                   /* pow r0.x, v1.x, v1.x         */
11777     static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001};         /* nrm r0.xyz, v1.x             */
11778     static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001};        /* rcp r0.x, v1.x               */
11779     static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001};        /* rcp r0.x, -v1.x              */
11780     static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001};        /* rsq r0.x, v1.x               */
11781     static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001};        /* rsq r0.x, -v1.x              */
11782     static const DWORD vs_lit[] = {0x02000010, 0x800f0000, 0x90000001,          /* lit r0, v1.xxxx              */
11783             0x02000001, 0x80010000, 0x80aa0000};                                /* mov r0.x, v0.z               */
11784
11785     static const DWORD vs_footer[] =
11786     {
11787         0x03000005, 0x80020000, 0x80000000, 0xa0ff0000,                         /* mul r0.y, r0.x, c0.w         */
11788         0x0300000d, 0x80040000, 0x80000000, 0x80550000,                         /* sge r0.z, r0.x, r0.y         */
11789         0x0300000d, 0x80020000, 0x80e40000, 0x80000000,                         /* sge r0.y, r0, r0.x           */
11790         0x03000005, 0x80040000, 0x80550000, 0x80e40000,                         /* mul r0.z, r0.y, r0           */
11791         0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000,                         /* max r0.w, -r0.z, r0.z        */
11792         0x0300000c, 0x80020000, 0x80000000, 0x80000000,                         /* slt r0.y, r0.x, r0.x         */
11793         0x03000002, 0x80040000, 0x80550000, 0x80550000,                         /* add r0.z, r0.y, r0.y         */
11794         0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000,                         /* slt r0.y, c0.x, r0.w         */
11795         0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000,                         /* max r0.w, -r0.z, r0.z        */
11796         0x03000002, 0x80040000, 0x81550000, 0xa0e40000,                         /* add r0.z, -r0.y, c0          */
11797         0x0300000c, 0x80080000, 0xa0000000, 0x80e40000,                         /* slt r0.w, c0.x, r0           */
11798         0x03000005, 0x80040000, 0x80ff0000, 0x80e40000,                         /* mul r0.z, r0.w, r0           */
11799         0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000,             /* mad r0.y, r0.z, c0, r0       */
11800         0x02000001, 0xe0030000, 0x80e40000,                                     /* mov oT0.xy, r0               */
11801         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
11802         0x0000ffff,                                                             /* end                          */
11803     };
11804
11805     static const struct
11806     {
11807         const char *name;
11808         const DWORD *ops;
11809         DWORD size;
11810         D3DCOLOR r600;
11811         D3DCOLOR nv40;
11812         D3DCOLOR nv50;
11813     }
11814     vs_body[] =
11815     {
11816         /* The basic ideas here are:
11817          *     2.0 * +/-INF == +/-INF
11818          *     NAN != NAN
11819          *
11820          * The vertex shader value is written to the red component, with 0.0
11821          * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
11822          * result in 0x00. The pixel shader value is written to the green
11823          * component, but here 0.0 also results in 0x00. The actual value is
11824          * written to the blue component.
11825          *
11826          * There are considerable differences between graphics cards in how
11827          * these are handled, but pow and nrm never generate INF or NAN. */
11828         {"log",     vs_log,     sizeof(vs_log),     0x00000000, 0x00ff0000, 0x00ff7f00},
11829         {"pow",     vs_pow,     sizeof(vs_pow),     0x000000ff, 0x0000ff00, 0x000000ff},
11830         {"nrm",     vs_nrm,     sizeof(vs_nrm),     0x00ff0000, 0x0000ff00, 0x00ff0000},
11831         {"rcp1",    vs_rcp1,    sizeof(vs_rcp1),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
11832         {"rcp2",    vs_rcp2,    sizeof(vs_rcp2),    0x00000000, 0x00ff0000, 0x00ff7f00},
11833         {"rsq1",    vs_rsq1,    sizeof(vs_rsq1),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
11834         {"rsq2",    vs_rsq2,    sizeof(vs_rsq2),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
11835         {"lit",     vs_lit,     sizeof(vs_lit),     0x00ff0000, 0x00ff0000, 0x00ff0000},
11836     };
11837
11838     static const DWORD ps_code[] =
11839     {
11840         0xffff0200,                                                             /* ps_2_0                       */
11841         0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0   */
11842         0x0200001f, 0x80000000, 0xb0030000,                                     /* dcl t0.xy                    */
11843         0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000,                         /* max r1.x, t0, c0             */
11844         0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000,                         /* min r0.x, t0, c0             */
11845         0x03000002, 0x80010000, 0x80e40000, 0x81e40001,                         /* add r0.x, r0, -r1            */
11846         0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000,             /* mad r1.x, t0, c0.w. -t0      */
11847         0x02000023, 0x80010002, 0x80e40001,                                     /* abs r2.x, r1                 */
11848         0x02000023, 0x80010000, 0x80e40000,                                     /* abs r0.x, r0                 */
11849         0x02000023, 0x80010001, 0xb0e40000,                                     /* abs r1.x, t0                 */
11850         0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000,             /* cmp r2.x, -r2, c0.z, c0      */
11851         0x02000023, 0x80010002, 0x80e40002,                                     /* abs r2.x, r2                 */
11852         0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000,             /* cmp r1.x, -r1, c0.z, c0      */
11853         0x02000023, 0x80010001, 0x80e40001,                                     /* abs r1.x, r1                 */
11854         0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000,             /* cmp r3.x, -r2, c0.z, c0      */
11855         0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000,             /* cmp r2.x, -r1, c0.z, c0      */
11856         0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000,             /* cmp r0.x, -r0, c0.y, c0      */
11857         0x03000005, 0x80010002, 0x80e40002, 0x80e40003,                         /* mul r2.x, r2, r3             */
11858         0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000,             /* cmp r0.x, -r2, c0.z, r0      */
11859         0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000,             /* cmp r0.y, -r1.x, r0.x, c0.x  */
11860         0x02000001, 0x80050000, 0xb0c90000,                                     /* mov r0.xz, t0.yzxw           */
11861         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.w, c0.z               */
11862         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
11863         0x0000ffff,                                                             /* end                          */
11864     };
11865
11866     struct
11867     {
11868         float x, y, z;
11869         float s;
11870     }
11871     quad[] =
11872     {
11873         { -1.0f,  1.0f, 0.0f, 0.0f},
11874         {  1.0f,  1.0f, 1.0f, 0.0f},
11875         { -1.0f, -1.0f, 0.0f, 0.0f},
11876         {  1.0f, -1.0f, 1.0f, 0.0f},
11877     };
11878
11879     IDirect3DPixelShader9 *ps;
11880     UINT body_size = 0;
11881     DWORD *vs_code;
11882     D3DCAPS9 caps;
11883     HRESULT hr;
11884     UINT i;
11885
11886     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11887     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11888     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
11889     {
11890         skip("No shader model 2.0 support, skipping floating point specials test.\n");
11891         return;
11892     }
11893
11894     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
11895     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11896
11897     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11898     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11899     IDirect3DDevice9_SetPixelShader(device, ps);
11900     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11901
11902     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
11903     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11904
11905     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
11906     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11907
11908     for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
11909     {
11910         if (vs_body[i].size > body_size) body_size = vs_body[i].size;
11911     }
11912
11913     vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
11914     memcpy(vs_code, vs_header, sizeof(vs_header));
11915
11916     for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
11917     {
11918         DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
11919         IDirect3DVertexShader9 *vs;
11920         D3DCOLOR color;
11921
11922         memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
11923         offset += vs_body[i].size / sizeof(*vs_body[i].ops);
11924         memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
11925
11926         hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
11927         ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
11928         IDirect3DDevice9_SetVertexShader(device, vs);
11929         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
11930
11931         hr = IDirect3DDevice9_BeginScene(device);
11932         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11933         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11934         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11935         hr = IDirect3DDevice9_EndScene(device);
11936         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11937
11938         color = getPixelColor(device, 320, 240);
11939         ok(color_match(color, vs_body[i].r600, 1)
11940                 || color_match(color, vs_body[i].nv40, 1)
11941                 || color_match(color, vs_body[i].nv50, 1),
11942                 "Expected color 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
11943                 vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
11944
11945         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11946         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11947
11948         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11949         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
11950         IDirect3DVertexShader9_Release(vs);
11951     }
11952
11953     HeapFree(GetProcessHeap(), 0, vs_code);
11954
11955     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11956     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11957     IDirect3DPixelShader9_Release(ps);
11958 }
11959
11960 static void srgbwrite_format_test(IDirect3DDevice9 *device)
11961 {
11962     IDirect3D9 *d3d;
11963     IDirect3DSurface9 *rt, *backbuffer;
11964     IDirect3DTexture9 *texture;
11965     HRESULT hr;
11966     int i;
11967     DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
11968     static const struct
11969     {
11970         D3DFORMAT fmt;
11971         const char *name;
11972     }
11973     formats[] =
11974     {
11975         { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
11976         { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
11977         { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
11978         { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
11979         { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
11980     };
11981     static const struct
11982     {
11983         float x, y, z;
11984         float u, v;
11985     }
11986     quad[] =
11987     {
11988         {-1.0f,  -1.0f,  0.1f,   0.0f,   0.0f},
11989         {-1.0f,   1.0f,  0.1f,   1.0f,   0.0f},
11990         { 1.0f,  -1.0f,  0.1f,   0.0f,   1.0f},
11991         { 1.0f,   1.0f,  0.1f,   1.0f,   1.0f}
11992     };
11993
11994     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
11995     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11996     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11997     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11998     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
11999     ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
12000     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12001     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12002     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12003     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12004
12005     for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
12006     {
12007         if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12008                 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
12009         {
12010             skip("Format %s not supported as render target, skipping test.\n",
12011                     formats[i].name);
12012             continue;
12013         }
12014
12015         hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET, formats[i].fmt,
12016                                             D3DPOOL_DEFAULT, &texture, NULL);
12017         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12018         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
12019         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12020
12021         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
12022         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12023         hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12024         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12025         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
12026         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12027
12028         hr = IDirect3DDevice9_BeginScene(device);
12029         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12030         if(SUCCEEDED(hr))
12031         {
12032             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
12033             ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12034             hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
12035             ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12036             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12037             ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
12038
12039             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
12040             ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12041             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
12042             ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12043             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
12044             ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12045             hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12046             ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12047             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12048             ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
12049             hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12050             ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12051
12052             hr = IDirect3DDevice9_EndScene(device);
12053             ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12054         }
12055
12056         IDirect3DSurface9_Release(rt);
12057         IDirect3DTexture9_Release(texture);
12058
12059         color = getPixelColor(device, 360, 240);
12060         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12061                                     D3DUSAGE_QUERY_SRGBWRITE,
12062                                     D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
12063         {
12064             /* Big slop for R5G6B5 */
12065             ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
12066                 formats[i].name, color_srgb, color);
12067         }
12068         else
12069         {
12070             /* Big slop for R5G6B5 */
12071             ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
12072                 formats[i].name, color_rgb, color);
12073         }
12074
12075         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12076         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12077     }
12078
12079     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
12080     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12081
12082     IDirect3D9_Release(d3d);
12083     IDirect3DSurface9_Release(backbuffer);
12084 }
12085
12086 static void ds_size_test(IDirect3DDevice9 *device)
12087 {
12088     IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
12089     HRESULT hr;
12090     DWORD color;
12091     DWORD num_passes;
12092     struct
12093     {
12094         float x, y, z;
12095     }
12096     quad[] =
12097     {
12098         {-1.0,  -1.0,   0.0 },
12099         {-1.0,   1.0,   0.0 },
12100         { 1.0,  -1.0,   0.0 },
12101         { 1.0,   1.0,   0.0 }
12102     };
12103
12104     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
12105     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12106     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
12107     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#x.\n", hr);
12108     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
12109     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
12110
12111     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
12112     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12113     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
12114     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12115     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12116     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12117     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12118     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12119     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12120     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12121     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
12122     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#x.\n", hr);
12123     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12124     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12125     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
12126     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12127     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12128     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12129
12130     /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
12131      * but does not change the surface's contents. */
12132     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
12133     ok(SUCCEEDED(hr), "Target clear failed, hr %#x.\n", hr);
12134     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
12135     ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#x.\n", hr);
12136     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
12137     ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#x.\n", hr);
12138
12139     hr = IDirect3DDevice9_GetRenderTargetData(device, rt, readback);
12140     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTargetData failed, hr %#x.\n", hr);
12141     color = getPixelColorFromSurface(readback, 2, 2);
12142     ok(color == 0x000000FF, "DS size test: Pixel (2, 2) after clear is %#x, expected 0x000000FF\n", color);
12143     color = getPixelColorFromSurface(readback, 31, 31);
12144     ok(color == 0x000000FF, "DS size test: Pixel (31, 31) after clear is %#x, expected 0x000000FF\n", color);
12145     color = getPixelColorFromSurface(readback, 32, 32);
12146     ok(color == 0x000000FF, "DS size test: Pixel (32, 32) after clear is %#x, expected 0x000000FF\n", color);
12147     color = getPixelColorFromSurface(readback, 63, 63);
12148     ok(color == 0x000000FF, "DS size test: Pixel (63, 63) after clear is %#x, expected 0x000000FF\n", color);
12149
12150     /* Turning on any depth-related state results in a ValidateDevice failure */
12151     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12152     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12153     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12154     ok(hr == D3DERR_CONFLICTINGRENDERSTATE, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12155         "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12156     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12157     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12158     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12159     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12160     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12161     ok(hr == D3DERR_CONFLICTINGRENDERSTATE, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12162         "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12163
12164     /* Try to draw with the device in an invalid state */
12165     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12166     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12167     hr = IDirect3DDevice9_BeginScene(device);
12168     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12169     if(SUCCEEDED(hr))
12170     {
12171         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12172         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12173         hr = IDirect3DDevice9_EndScene(device);
12174         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12175     }
12176
12177     hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12178     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12179     hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
12180     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12181     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12182     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12183
12184     IDirect3DSurface9_Release(readback);
12185     IDirect3DSurface9_Release(ds);
12186     IDirect3DSurface9_Release(rt);
12187     IDirect3DSurface9_Release(old_rt);
12188     IDirect3DSurface9_Release(old_ds);
12189 }
12190
12191 static void unbound_sampler_test(IDirect3DDevice9 *device)
12192 {
12193     HRESULT hr;
12194     IDirect3DPixelShader9 *ps, *ps_cube, *ps_volume;
12195     IDirect3DSurface9 *rt, *old_rt;
12196     DWORD color;
12197
12198     static const DWORD ps_code[] =
12199     {
12200         0xffff0200,                                     /* ps_2_0           */
12201         0x0200001f, 0x90000000, 0xa00f0800,             /* dcl_2d s0        */
12202         0x0200001f, 0x80000000, 0xb00f0000,             /* dcl t0           */
12203         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12204         0x02000001, 0x800f0800, 0x80e40000,             /* mov oC0, r0      */
12205         0x0000ffff,                                     /* end              */
12206     };
12207     static const DWORD ps_code_cube[] =
12208     {
12209         0xffff0200,                                     /* ps_2_0           */
12210         0x0200001f, 0x98000000, 0xa00f0800,             /* dcl_cube s0      */
12211         0x0200001f, 0x80000000, 0xb00f0000,             /* dcl t0           */
12212         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12213         0x02000001, 0x800f0800, 0x80e40000,             /* mov oC0, r0      */
12214         0x0000ffff,                                     /* end              */
12215     };
12216     static const DWORD ps_code_volume[] =
12217     {
12218         0xffff0200,                                     /* ps_2_0           */
12219         0x0200001f, 0xa0000000, 0xa00f0800,             /* dcl_volume s0    */
12220         0x0200001f, 0x80000000, 0xb00f0000,             /* dcl t0           */
12221         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12222         0x02000001, 0x800f0800, 0x80e40000,             /* mov oC0, r0      */
12223         0x0000ffff,                                     /* end              */
12224     };
12225
12226     static const struct
12227     {
12228         float x, y, z;
12229         float u, v;
12230     }
12231     quad[] =
12232     {
12233         {-1.0f,  -1.0f,  0.1f,   0.0f,   0.0f},
12234         {-1.0f,   1.0f,  0.1f,   1.0f,   0.0f},
12235         { 1.0f,  -1.0f,  0.1f,   0.0f,   1.0f},
12236         { 1.0f,   1.0f,  0.1f,   1.0f,   1.0f}
12237     };
12238
12239     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12240     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStage failed, %#x.\n", hr);
12241
12242     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12243     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12244     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_cube, &ps_cube);
12245     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12246     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_volume, &ps_volume);
12247     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12248
12249     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
12250     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12251
12252     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12253     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12254
12255     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12256     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12257
12258     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 );
12259     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12260
12261     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x56ffffff, 0, 0);
12262     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
12263
12264     hr = IDirect3DDevice9_SetPixelShader(device, ps);
12265     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12266
12267     hr = IDirect3DDevice9_BeginScene(device);
12268     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12269     if(SUCCEEDED(hr))
12270     {
12271         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12272         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12273
12274         hr = IDirect3DDevice9_EndScene(device);
12275         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12276     }
12277
12278     color = getPixelColorFromSurface(rt, 32, 32);
12279     ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12280
12281     /* Now try with a cube texture */
12282     hr = IDirect3DDevice9_SetPixelShader(device, ps_cube);
12283     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12284
12285     hr = IDirect3DDevice9_BeginScene(device);
12286     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12287     if (SUCCEEDED(hr))
12288     {
12289         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12290         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12291
12292         hr = IDirect3DDevice9_EndScene(device);
12293         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12294     }
12295
12296     color = getPixelColorFromSurface(rt, 32, 32);
12297     ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12298
12299     /* And then with a volume texture */
12300     hr = IDirect3DDevice9_SetPixelShader(device, ps_volume);
12301     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12302
12303     hr = IDirect3DDevice9_BeginScene(device);
12304     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12305     if (SUCCEEDED(hr))
12306     {
12307         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12308         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12309
12310         hr = IDirect3DDevice9_EndScene(device);
12311         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12312     }
12313
12314     color = getPixelColorFromSurface(rt, 32, 32);
12315     ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12316
12317     hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12318     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12319
12320     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12321     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12322
12323     IDirect3DSurface9_Release(rt);
12324     IDirect3DSurface9_Release(old_rt);
12325     IDirect3DPixelShader9_Release(ps);
12326     IDirect3DPixelShader9_Release(ps_cube);
12327     IDirect3DPixelShader9_Release(ps_volume);
12328 }
12329
12330 static void update_surface_test(IDirect3DDevice9 *device)
12331 {
12332     static const BYTE blocks[][8] =
12333     {
12334         {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, /* White */
12335         {0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Red */
12336         {0xe0, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00}, /* Yellow */
12337         {0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Green */
12338         {0xff, 0x07, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Cyan */
12339         {0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Blue */
12340         {0x1f, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Magenta */
12341     };
12342     static const struct
12343     {
12344         UINT x, y;
12345         D3DCOLOR color;
12346     }
12347     expected_colors[] =
12348     {
12349         { 18, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0xff)},
12350         { 57, 240, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff)},
12351         {109, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0xff)},
12352         {184, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
12353         {290, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
12354         {440, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
12355         {584, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
12356     };
12357     static const struct
12358     {
12359         float x, y, z, w;
12360         float u, v;
12361     }
12362     tri[] =
12363     {
12364         {  0.0f, 480.0f, 0.0f,  1.0f,   0.0f, 0.0f},
12365         {  0.0f,   0.0f, 0.0f,  1.0f,   0.0f, 1.0f},
12366         {640.0f, 240.0f, 0.0f, 10.0f, 100.0f, 0.5f},
12367     };
12368     static const RECT rect_2x2 = {0, 0, 2, 2};
12369     static const struct
12370     {
12371         UINT src_level;
12372         UINT dst_level;
12373         const RECT *r;
12374         HRESULT hr;
12375     }
12376     block_size_tests[] =
12377     {
12378         {1, 0, NULL,      D3D_OK},
12379         {0, 1, NULL,      D3DERR_INVALIDCALL},
12380         {5, 4, NULL,      D3DERR_INVALIDCALL},
12381         {4, 5, NULL,      D3DERR_INVALIDCALL},
12382         {4, 5, &rect_2x2, D3DERR_INVALIDCALL},
12383         {5, 5, &rect_2x2, D3D_OK},
12384     };
12385
12386     IDirect3DSurface9 *src_surface, *dst_surface;
12387     IDirect3DTexture9 *src_tex, *dst_tex;
12388     IDirect3D9 *d3d;
12389     UINT count, i;
12390     HRESULT hr;
12391
12392     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
12393     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12394
12395     hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
12396             D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1);
12397     IDirect3D9_Release(d3d);
12398     if (FAILED(hr))
12399     {
12400         skip("DXT1 not supported, skipping test.\n");
12401         return;
12402     }
12403
12404     IDirect3D9_Release(d3d);
12405
12406     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &src_tex, NULL);
12407     ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12408     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &dst_tex, NULL);
12409     ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12410
12411     count = IDirect3DTexture9_GetLevelCount(src_tex);
12412     ok(count == 7, "Got level count %u, expected 7.\n", count);
12413
12414     for (i = 0; i < count; ++i)
12415     {
12416         UINT row_count, block_count, x, y;
12417         D3DSURFACE_DESC desc;
12418         BYTE *row, *block;
12419         D3DLOCKED_RECT r;
12420
12421         hr = IDirect3DTexture9_GetLevelDesc(src_tex, i, &desc);
12422         ok(SUCCEEDED(hr), "Failed to get level desc, hr %#x.\n", hr);
12423
12424         hr = IDirect3DTexture9_LockRect(src_tex, i, &r, NULL, 0);
12425         ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
12426
12427         row_count = ((desc.Height + 3) & ~3) / 4;
12428         block_count = ((desc.Width + 3) & ~3) / 4;
12429         row = r.pBits;
12430
12431         for (y = 0; y < row_count; ++y)
12432         {
12433             block = row;
12434             for (x = 0; x < block_count; ++x)
12435             {
12436                 memcpy(block, blocks[i], sizeof(blocks[i]));
12437                 block += sizeof(blocks[i]);
12438             }
12439             row += r.Pitch;
12440         }
12441
12442         hr = IDirect3DTexture9_UnlockRect(src_tex, i);
12443         ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
12444     }
12445
12446     for (i = 0; i < sizeof(block_size_tests) / sizeof(*block_size_tests); ++i)
12447     {
12448         hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, block_size_tests[i].src_level, &src_surface);
12449         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12450         hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, block_size_tests[i].dst_level, &dst_surface);
12451         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12452
12453         hr = IDirect3DDevice9_UpdateSurface(device, src_surface, block_size_tests[i].r, dst_surface, NULL);
12454         ok(hr == block_size_tests[i].hr, "Update surface returned %#x for test %u, expected %#x.\n",
12455                 hr, i, block_size_tests[i].hr);
12456
12457         IDirect3DSurface9_Release(dst_surface);
12458         IDirect3DSurface9_Release(src_surface);
12459     }
12460
12461     for (i = 0; i < count; ++i)
12462     {
12463         hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, i, &src_surface);
12464         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12465         hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, i, &dst_surface);
12466         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12467
12468         hr = IDirect3DDevice9_UpdateSurface(device, src_surface, NULL, dst_surface, NULL);
12469         ok(SUCCEEDED(hr), "Failed to update surface at level %u, hr %#x.\n", i, hr);
12470
12471         IDirect3DSurface9_Release(dst_surface);
12472         IDirect3DSurface9_Release(src_surface);
12473     }
12474
12475     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12476     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12477     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
12478     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12479     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
12480     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12481     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)dst_tex);
12482     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12483     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12484     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12485     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12486     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12487
12488     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
12489     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12490
12491     hr = IDirect3DDevice9_BeginScene(device);
12492     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12493     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 1, tri, sizeof(*tri));
12494     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12495     hr = IDirect3DDevice9_EndScene(device);
12496     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12497
12498     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
12499     {
12500         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
12501         ok(color_match(color, expected_colors[i].color, 0),
12502                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
12503                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
12504     }
12505
12506     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12507     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12508
12509     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12510     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12511     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
12512     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12513     IDirect3DTexture9_Release(dst_tex);
12514     IDirect3DTexture9_Release(src_tex);
12515 }
12516
12517 START_TEST(visual)
12518 {
12519     IDirect3DDevice9 *device_ptr;
12520     D3DCAPS9 caps;
12521     HRESULT hr;
12522     DWORD color;
12523
12524     d3d9_handle = LoadLibraryA("d3d9.dll");
12525     if (!d3d9_handle)
12526     {
12527         skip("Could not load d3d9.dll\n");
12528         return;
12529     }
12530
12531     device_ptr = init_d3d9();
12532     if (!device_ptr)
12533     {
12534         skip("Creating the device failed\n");
12535         return;
12536     }
12537
12538     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
12539
12540     /* Check for the reliability of the returned data */
12541     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
12542     if(FAILED(hr))
12543     {
12544         skip("Clear failed, can't assure correctness of the test results, skipping\n");
12545         goto cleanup;
12546     }
12547
12548     color = getPixelColor(device_ptr, 1, 1);
12549     if(color !=0x00ff0000)
12550     {
12551         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
12552         goto cleanup;
12553     }
12554     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
12555
12556     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
12557     if(FAILED(hr))
12558     {
12559         skip("Clear failed, can't assure correctness of the test results, skipping\n");
12560         goto cleanup;
12561     }
12562
12563     color = getPixelColor(device_ptr, 639, 479);
12564     if(color != 0x0000ddee)
12565     {
12566         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
12567         goto cleanup;
12568     }
12569     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
12570
12571     /* Now execute the real tests */
12572     depth_clamp_test(device_ptr);
12573     stretchrect_test(device_ptr);
12574     lighting_test(device_ptr);
12575     clear_test(device_ptr);
12576     color_fill_test(device_ptr);
12577     fog_test(device_ptr);
12578     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
12579     {
12580         test_cube_wrap(device_ptr);
12581     } else {
12582         skip("No cube texture support\n");
12583     }
12584     z_range_test(device_ptr);
12585     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
12586     {
12587         maxmip_test(device_ptr);
12588     }
12589     else
12590     {
12591         skip("No mipmap support\n");
12592     }
12593     offscreen_test(device_ptr);
12594     ds_size_test(device_ptr);
12595     alpha_test(device_ptr);
12596     shademode_test(device_ptr);
12597     srgbtexture_test(device_ptr);
12598     release_buffer_test(device_ptr);
12599     float_texture_test(device_ptr);
12600     g16r16_texture_test(device_ptr);
12601     pixelshader_blending_test(device_ptr);
12602     texture_transform_flags_test(device_ptr);
12603     autogen_mipmap_test(device_ptr);
12604     fixed_function_decl_test(device_ptr);
12605     conditional_np2_repeat_test(device_ptr);
12606     fixed_function_bumpmap_test(device_ptr);
12607     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
12608         stencil_cull_test(device_ptr);
12609     } else {
12610         skip("No two sided stencil support\n");
12611     }
12612     pointsize_test(device_ptr);
12613     tssargtemp_test(device_ptr);
12614     np2_stretch_rect_test(device_ptr);
12615     yuv_color_test(device_ptr);
12616     zwriteenable_test(device_ptr);
12617     alphatest_test(device_ptr);
12618     viewport_test(device_ptr);
12619
12620     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
12621     {
12622         test_constant_clamp_vs(device_ptr);
12623         test_compare_instructions(device_ptr);
12624     }
12625     else skip("No vs_1_1 support\n");
12626
12627     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
12628     {
12629         test_mova(device_ptr);
12630         loop_index_test(device_ptr);
12631         sincos_test(device_ptr);
12632         sgn_test(device_ptr);
12633         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
12634             test_vshader_input(device_ptr);
12635             test_vshader_float16(device_ptr);
12636             stream_test(device_ptr);
12637         } else {
12638             skip("No vs_3_0 support\n");
12639         }
12640     }
12641     else skip("No vs_2_0 support\n");
12642
12643     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
12644     {
12645         fog_with_shader_test(device_ptr);
12646     }
12647     else skip("No vs_1_1 and ps_1_1 support\n");
12648
12649     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
12650     {
12651         texbem_test(device_ptr);
12652         texdepth_test(device_ptr);
12653         texkill_test(device_ptr);
12654         x8l8v8u8_test(device_ptr);
12655         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
12656             constant_clamp_ps_test(device_ptr);
12657             cnd_test(device_ptr);
12658             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
12659                 dp2add_ps_test(device_ptr);
12660                 unbound_sampler_test(device_ptr);
12661                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0) && caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
12662                     nested_loop_test(device_ptr);
12663                     pretransformed_varying_test(device_ptr);
12664                     vFace_register_test(device_ptr);
12665                     vpos_register_test(device_ptr);
12666                     multiple_rendertargets_test(device_ptr);
12667                 } else {
12668                     skip("No ps_3_0 or vs_3_0 support\n");
12669                 }
12670             } else {
12671                 skip("No ps_2_0 support\n");
12672             }
12673         }
12674     }
12675     else skip("No ps_1_1 support\n");
12676
12677     texop_test(device_ptr);
12678     texop_range_test(device_ptr);
12679     alphareplicate_test(device_ptr);
12680     dp3_alpha_test(device_ptr);
12681     depth_buffer_test(device_ptr);
12682     depth_buffer2_test(device_ptr);
12683     depth_blit_test(device_ptr);
12684     intz_test(device_ptr);
12685     shadow_test(device_ptr);
12686     fp_special_test(device_ptr);
12687     depth_bounds_test(device_ptr);
12688     srgbwrite_format_test(device_ptr);
12689     clip_planes_test(device_ptr);
12690     update_surface_test(device_ptr);
12691
12692 cleanup:
12693     if(device_ptr) {
12694         D3DPRESENT_PARAMETERS present_parameters;
12695         IDirect3DSwapChain9 *swapchain;
12696         ULONG ref;
12697
12698         IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
12699         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
12700         IDirect3DSwapChain9_Release(swapchain);
12701         ref = IDirect3DDevice9_Release(device_ptr);
12702         ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
12703         DestroyWindow(present_parameters.hDeviceWindow);
12704     }
12705 }