winealsa: Map ALSA errors to AUDCLNT_E_*.
[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         win_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 static void cleanup_device(IDirect3DDevice9 *device)
212 {
213     if (device)
214     {
215         D3DPRESENT_PARAMETERS present_parameters;
216         IDirect3DSwapChain9 *swapchain;
217         ULONG ref;
218
219         IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
220         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
221         IDirect3DSwapChain9_Release(swapchain);
222         ref = IDirect3DDevice9_Release(device);
223         ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
224         DestroyWindow(present_parameters.hDeviceWindow);
225     }
226 }
227
228 struct vertex
229 {
230     float x, y, z;
231     DWORD diffuse;
232 };
233
234 struct tvertex
235 {
236     float x, y, z, rhw;
237     DWORD diffuse;
238 };
239
240 struct nvertex
241 {
242     float x, y, z;
243     float nx, ny, nz;
244     DWORD diffuse;
245 };
246
247 static void lighting_test(IDirect3DDevice9 *device)
248 {
249     HRESULT hr;
250     DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
251     DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
252     DWORD color;
253     D3DMATERIAL9 material, old_material;
254     DWORD cop, carg;
255     DWORD old_colorwrite;
256
257     float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
258                       0.0f, 1.0f, 0.0f, 0.0f,
259                       0.0f, 0.0f, 1.0f, 0.0f,
260                       0.0f, 0.0f, 0.0f, 1.0f };
261
262     struct vertex unlitquad[] =
263     {
264         {-1.0f, -1.0f,   0.1f,                          0xffff0000},
265         {-1.0f,  0.0f,   0.1f,                          0xffff0000},
266         { 0.0f,  0.0f,   0.1f,                          0xffff0000},
267         { 0.0f, -1.0f,   0.1f,                          0xffff0000},
268     };
269     struct vertex litquad[] =
270     {
271         {-1.0f,  0.0f,   0.1f,                          0xff00ff00},
272         {-1.0f,  1.0f,   0.1f,                          0xff00ff00},
273         { 0.0f,  1.0f,   0.1f,                          0xff00ff00},
274         { 0.0f,  0.0f,   0.1f,                          0xff00ff00},
275     };
276     struct nvertex unlitnquad[] =
277     {
278         { 0.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
279         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
280         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
281         { 1.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
282     };
283     struct nvertex litnquad[] =
284     {
285         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
286         { 0.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
287         { 1.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
288         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
289     };
290     WORD Indices[] = {0, 1, 2, 2, 3, 0};
291
292     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
293     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
294
295     /* Setup some states that may cause issues */
296     hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
297     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
298     hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
299     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
300     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
301     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
302     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
303     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
304     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
305     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
306     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
307     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
308     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
309     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
310     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
311     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
312     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
313     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
314     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
315     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
316     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
317     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
318     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &old_colorwrite);
319     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
320     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
321     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
322
323     hr = IDirect3DDevice9_SetFVF(device, 0);
324     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
325
326     hr = IDirect3DDevice9_SetFVF(device, fvf);
327     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
328
329     hr = IDirect3DDevice9_BeginScene(device);
330     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
331     if(hr == D3D_OK)
332     {
333         /* No lights are defined... That means, lit vertices should be entirely black */
334         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
335         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
336         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
337                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
338         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
339
340         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
341         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
342         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
343                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
344         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
345
346         hr = IDirect3DDevice9_SetFVF(device, nfvf);
347         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
348
349         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
350         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
351         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
352                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
353         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
354
355         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
356         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
357         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
358                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
359         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
360
361         IDirect3DDevice9_EndScene(device);
362         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
363     }
364
365     color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
366     ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
367     color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
368     ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
369     color = getPixelColor(device, 480, 360); /* Lower left quad - unlit with normals */
370     ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
371     color = getPixelColor(device, 480, 120); /* Upper left quad - lit with normals */
372     ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
373
374     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
375
376     hr = IDirect3DDevice9_GetMaterial(device, &old_material);
377     ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
378     memset(&material, 0, sizeof(material));
379     material.Diffuse.r = 0.0;
380     material.Diffuse.g = 0.0;
381     material.Diffuse.b = 0.0;
382     material.Diffuse.a = 1.0;
383     material.Ambient.r = 0.0;
384     material.Ambient.g = 0.0;
385     material.Ambient.b = 0.0;
386     material.Ambient.a = 0.0;
387     material.Specular.r = 0.0;
388     material.Specular.g = 0.0;
389     material.Specular.b = 0.0;
390     material.Specular.a = 0.0;
391     material.Emissive.r = 0.0;
392     material.Emissive.g = 0.0;
393     material.Emissive.b = 0.0;
394     material.Emissive.a = 0.0;
395     material.Power = 0.0;
396     IDirect3DDevice9_SetMaterial(device, &material);
397     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
398
399     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
400     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
401     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
402     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
403
404     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
405     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
406     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
407     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
408     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
409     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
410     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
411     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
412
413     hr = IDirect3DDevice9_BeginScene(device);
414     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
415     if(SUCCEEDED(hr)) {
416         struct vertex lighting_test[] = {
417             {-1.0,   -1.0,   0.1,    0x8000ff00},
418             { 1.0,   -1.0,   0.1,    0x80000000},
419             {-1.0,    1.0,   0.1,    0x8000ff00},
420             { 1.0,    1.0,   0.1,    0x80000000}
421         };
422         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
423         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
424         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
425         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
426
427         hr = IDirect3DDevice9_EndScene(device);
428         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
429     }
430
431     color = getPixelColor(device, 320, 240);
432     ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
433     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
434
435     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
436     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
437     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
438     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
439     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
440     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
441     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
442     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
443     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, old_colorwrite);
444     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
445     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
446     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
447     hr = IDirect3DDevice9_SetMaterial(device, &old_material);
448     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
449 }
450
451 static void clear_test(IDirect3DDevice9 *device)
452 {
453     /* Tests the correctness of clearing parameters */
454     HRESULT hr;
455     D3DRECT rect[2];
456     D3DRECT rect_negneg;
457     DWORD color;
458     D3DVIEWPORT9 old_vp, vp;
459     RECT scissor;
460     DWORD oldColorWrite;
461     BOOL invalid_clear_failed = FALSE;
462
463     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
464     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
465
466     /* Positive x, negative y */
467     rect[0].x1 = 0;
468     rect[0].y1 = 480;
469     rect[0].x2 = 320;
470     rect[0].y2 = 240;
471
472     /* Positive x, positive y */
473     rect[1].x1 = 0;
474     rect[1].y1 = 0;
475     rect[1].x2 = 320;
476     rect[1].y2 = 240;
477     /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
478      * returns D3D_OK, but ignores the rectangle silently
479      */
480     hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
481     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
482     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
483
484     /* negative x, negative y */
485     rect_negneg.x1 = 640;
486     rect_negneg.y1 = 240;
487     rect_negneg.x2 = 320;
488     rect_negneg.y2 = 0;
489     hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
490     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
491     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
492
493     color = getPixelColor(device, 160, 360); /* lower left quad */
494     ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
495     color = getPixelColor(device, 160, 120); /* upper left quad */
496     if(invalid_clear_failed) {
497         /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
498         ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
499     } else {
500         /* If the negative rectangle was dropped silently, the correct ones are cleared */
501         ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
502     }
503     color = getPixelColor(device, 480, 360); /* lower right quad  */
504     ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
505     color = getPixelColor(device, 480, 120); /* upper right quad */
506     ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
507
508     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
509
510     /* Hack to work around a nvidia windows driver bug. The clear below is supposed to
511      * clear the red quad in the top left part of the render target. For some reason it
512      * doesn't work if the clear color is 0xffffffff on some versions of the Nvidia Windows
513      * driver(tested on 8.17.12.5896, Win7). A clear with a different color works around
514      * this bug and fixes the clear with the white color. Even 0xfeffffff works, but let's
515      * pick some obvious value
516      */
517     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbabe, 0.0, 0);
518     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
519
520     /* Test how the viewport affects clears */
521     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
522     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
523     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
524     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
525
526     vp.X = 160;
527     vp.Y = 120;
528     vp.Width = 160;
529     vp.Height = 120;
530     vp.MinZ = 0.0;
531     vp.MaxZ = 1.0;
532     hr = IDirect3DDevice9_SetViewport(device, &vp);
533     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
534     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
535     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
536
537     vp.X = 320;
538     vp.Y = 240;
539     vp.Width = 320;
540     vp.Height = 240;
541     vp.MinZ = 0.0;
542     vp.MaxZ = 1.0;
543     hr = IDirect3DDevice9_SetViewport(device, &vp);
544     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
545     rect[0].x1 = 160;
546     rect[0].y1 = 120;
547     rect[0].x2 = 480;
548     rect[0].y2 = 360;
549     hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
550     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
551
552     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
553     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
554
555     color = getPixelColor(device, 158, 118);
556     ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
557     color = getPixelColor(device, 162, 118);
558     ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
559     color = getPixelColor(device, 158, 122);
560     ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
561     color = getPixelColor(device, 162, 122);
562     ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
563
564     color = getPixelColor(device, 318, 238);
565     ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
566     color = getPixelColor(device, 322, 238);
567     ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
568     color = getPixelColor(device, 318, 242);
569     ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
570     color = getPixelColor(device, 322, 242);
571     ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
572
573     color = getPixelColor(device, 478, 358);
574     ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
575     color = getPixelColor(device, 482, 358);
576     ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
577     color = getPixelColor(device, 478, 362);
578     ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
579     color = getPixelColor(device, 482, 362);
580     ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
581
582     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
583
584     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
585     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
586
587     scissor.left = 160;
588     scissor.right = 480;
589     scissor.top = 120;
590     scissor.bottom = 360;
591     hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
592     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
593     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
594     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
595
596     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
597     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
598     hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
599     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
600
601     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
602     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
603
604     color = getPixelColor(device, 158, 118);
605     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
606     color = getPixelColor(device, 162, 118);
607     ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
608     color = getPixelColor(device, 158, 122);
609     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
610     color = getPixelColor(device, 162, 122);
611     ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
612
613     color = getPixelColor(device, 158, 358);
614     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
615     color = getPixelColor(device, 162, 358);
616     ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
617     color = getPixelColor(device, 158, 358);
618     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
619     color = getPixelColor(device, 162, 362);
620     ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
621
622     color = getPixelColor(device, 478, 118);
623     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
624     color = getPixelColor(device, 478, 122);
625     ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
626     color = getPixelColor(device, 482, 122);
627     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
628     color = getPixelColor(device, 482, 358);
629     ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
630
631     color = getPixelColor(device, 478, 358);
632     ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
633     color = getPixelColor(device, 478, 362);
634     ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
635     color = getPixelColor(device, 482, 358);
636     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
637     color = getPixelColor(device, 482, 362);
638     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
639
640     color = getPixelColor(device, 318, 238);
641     ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
642     color = getPixelColor(device, 318, 242);
643     ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
644     color = getPixelColor(device, 322, 238);
645     ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
646     color = getPixelColor(device, 322, 242);
647     ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
648
649     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
650
651     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
652     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
653     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
654     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
655
656     /* Same nvidia windows driver trouble with white clears as earlier in the same test */
657     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbeef, 0.0, 0);
658     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
659
660     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
661     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
662
663     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
664     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
665
666     /* Colorwriteenable does not affect the clear */
667     color = getPixelColor(device, 320, 240);
668     ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
669
670     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
671 }
672
673 static void color_fill_test(IDirect3DDevice9 *device)
674 {
675     HRESULT hr;
676     IDirect3DSurface9 *backbuffer = NULL;
677     IDirect3DSurface9 *rt_surface = NULL;
678     IDirect3DSurface9 *offscreen_surface = NULL;
679     DWORD fill_color, color;
680
681     /* Test ColorFill on a the backbuffer (should pass) */
682     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
683     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
684     if(backbuffer)
685     {
686         fill_color = 0x112233;
687         hr = IDirect3DDevice9_ColorFill(device, backbuffer, NULL, fill_color);
688         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
689
690         color = getPixelColor(device, 0, 0);
691         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
692
693         IDirect3DSurface9_Release(backbuffer);
694     }
695
696     /* Test ColorFill on a render target surface (should pass) */
697     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt_surface, NULL );
698     ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
699     if(rt_surface)
700     {
701         fill_color = 0x445566;
702         hr = IDirect3DDevice9_ColorFill(device, rt_surface, NULL, fill_color);
703         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
704
705         color = getPixelColorFromSurface(rt_surface, 0, 0);
706         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
707
708         IDirect3DSurface9_Release(rt_surface);
709     }
710
711     /* Test ColorFill on a offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
712     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
713             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen_surface, NULL);
714     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
715     if(offscreen_surface)
716     {
717         fill_color = 0x778899;
718         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, fill_color);
719         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
720
721         color = getPixelColorFromSurface(offscreen_surface, 0, 0);
722         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
723
724         IDirect3DSurface9_Release(offscreen_surface);
725     }
726
727     /* Try ColorFill on a offscreen surface in sysmem (should fail) */
728     offscreen_surface = NULL;
729     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
730             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &offscreen_surface, NULL);
731     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
732     if(offscreen_surface)
733     {
734         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, 0);
735         ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
736
737         IDirect3DSurface9_Release(offscreen_surface);
738     }
739 }
740
741 typedef struct {
742     float in[4];
743     DWORD out;
744 } test_data_t;
745
746 /*
747  *  c7      mova    ARGB            mov     ARGB
748  * -2.4     -2      0x00ffff00      -3      0x00ff0000
749  * -1.6     -2      0x00ffff00      -2      0x00ffff00
750  * -0.4      0      0x0000ffff      -1      0x0000ff00
751  *  0.4      0      0x0000ffff       0      0x0000ffff
752  *  1.6      2      0x00ff00ff       1      0x000000ff
753  *  2.4      2      0x00ff00ff       2      0x00ff00ff
754  */
755 static void test_mova(IDirect3DDevice9 *device)
756 {
757     static const DWORD mova_test[] = {
758         0xfffe0200,                                                             /* vs_2_0                       */
759         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
760         0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
761         0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
762         0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
763         0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
764         0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
765         0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
766         0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
767         0x0200002e, 0xb0010000, 0xa0000007,                                     /* mova a0.x, c7.x              */
768         0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000,                         /* mov oD0, c[a0.x + 3]         */
769         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
770         0x0000ffff                                                              /* END                          */
771     };
772     static const DWORD mov_test[] = {
773         0xfffe0101,                                                             /* vs_1_1                       */
774         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
775         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
776         0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
777         0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
778         0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
779         0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
780         0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
781         0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
782         0x00000001, 0xb0010000, 0xa0000007,                                     /* mov a0.x, c7.x               */
783         0x00000001, 0xd00f0000, 0xa0e42003,                                     /* mov oD0, c[a0.x + 3]         */
784         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
785         0x0000ffff                                                              /* END                          */
786     };
787
788     static const test_data_t test_data[2][6] = {
789         {
790             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
791             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
792             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
793             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
794             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
795             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
796         },
797         {
798             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
799             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
800             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
801             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
802             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
803             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
804         }
805     };
806
807     static const float quad[][3] = {
808         {-1.0f, -1.0f, 0.0f},
809         {-1.0f,  1.0f, 0.0f},
810         { 1.0f, -1.0f, 0.0f},
811         { 1.0f,  1.0f, 0.0f},
812     };
813
814     static const D3DVERTEXELEMENT9 decl_elements[] = {
815         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
816         D3DDECL_END()
817     };
818
819     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
820     IDirect3DVertexShader9 *mova_shader = NULL;
821     IDirect3DVertexShader9 *mov_shader = NULL;
822     HRESULT hr;
823     UINT i, j;
824
825     hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
826     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
827     hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
828     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
829     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
830     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
831     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
832     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
833
834     hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
835     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
836     for(j = 0; j < 2; ++j)
837     {
838         for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
839         {
840             DWORD color;
841
842             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
843             ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
844
845             hr = IDirect3DDevice9_BeginScene(device);
846             ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
847
848             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
849             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
850
851             hr = IDirect3DDevice9_EndScene(device);
852             ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
853
854             color = getPixelColor(device, 320, 240);
855             ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
856                test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
857
858             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
859             ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
860
861             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
862             ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
863         }
864         hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
865         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
866     }
867
868     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
869     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
870
871     IDirect3DVertexDeclaration9_Release(vertex_declaration);
872     IDirect3DVertexShader9_Release(mova_shader);
873     IDirect3DVertexShader9_Release(mov_shader);
874 }
875
876 struct sVertex {
877     float x, y, z;
878     DWORD diffuse;
879     DWORD specular;
880 };
881
882 struct sVertexT {
883     float x, y, z, rhw;
884     DWORD diffuse;
885     DWORD specular;
886 };
887
888 static void fog_test(IDirect3DDevice9 *device)
889 {
890     HRESULT hr;
891     D3DCOLOR color;
892     float start = 0.0f, end = 1.0f;
893     D3DCAPS9 caps;
894     int i;
895
896     /* Gets full z based fog with linear fog, no fog with specular color */
897     struct sVertex untransformed_1[] = {
898         {-1,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
899         {-1,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
900         { 0,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
901         { 0,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
902     };
903     /* Ok, I am too lazy to deal with transform matrices */
904     struct sVertex untransformed_2[] = {
905         {-1,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
906         {-1,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
907         { 0,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
908         { 0,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
909     };
910     /* Untransformed ones. Give them a different diffuse color to make the test look
911      * nicer. It also makes making sure that they are drawn correctly easier.
912      */
913     struct sVertexT transformed_1[] = {
914         {320,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
915         {640,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
916         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
917         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
918     };
919     struct sVertexT transformed_2[] = {
920         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
921         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
922         {640,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
923         {320,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
924     };
925     struct vertex rev_fog_quads[] = {
926        {-1.0,   -1.0,   0.1,    0x000000ff},
927        {-1.0,    0.0,   0.1,    0x000000ff},
928        { 0.0,    0.0,   0.1,    0x000000ff},
929        { 0.0,   -1.0,   0.1,    0x000000ff},
930
931        { 0.0,   -1.0,   0.9,    0x000000ff},
932        { 0.0,    0.0,   0.9,    0x000000ff},
933        { 1.0,    0.0,   0.9,    0x000000ff},
934        { 1.0,   -1.0,   0.9,    0x000000ff},
935
936        { 0.0,    0.0,   0.4,    0x000000ff},
937        { 0.0,    1.0,   0.4,    0x000000ff},
938        { 1.0,    1.0,   0.4,    0x000000ff},
939        { 1.0,    0.0,   0.4,    0x000000ff},
940
941        {-1.0,    0.0,   0.7,    0x000000ff},
942        {-1.0,    1.0,   0.7,    0x000000ff},
943        { 0.0,    1.0,   0.7,    0x000000ff},
944        { 0.0,    0.0,   0.7,    0x000000ff},
945     };
946     WORD Indices[] = {0, 1, 2, 2, 3, 0};
947
948     const float ident_mat[16] =
949     {
950         1.0f, 0.0f, 0.0f, 0.0f,
951         0.0f, 1.0f, 0.0f, 0.0f,
952         0.0f, 0.0f, 1.0f, 0.0f,
953         0.0f, 0.0f, 0.0f, 1.0f
954     };
955     const float world_mat1[16] =
956     {
957         1.0f, 0.0f,  0.0f, 0.0f,
958         0.0f, 1.0f,  0.0f, 0.0f,
959         0.0f, 0.0f,  1.0f, 0.0f,
960         0.0f, 0.0f, -0.5f, 1.0f
961     };
962     const float world_mat2[16] =
963     {
964         1.0f, 0.0f, 0.0f, 0.0f,
965         0.0f, 1.0f, 0.0f, 0.0f,
966         0.0f, 0.0f, 1.0f, 0.0f,
967         0.0f, 0.0f, 1.0f, 1.0f
968     };
969     const float proj_mat[16] =
970     {
971         1.0f, 0.0f,  0.0f, 0.0f,
972         0.0f, 1.0f,  0.0f, 0.0f,
973         0.0f, 0.0f,  1.0f, 0.0f,
974         0.0f, 0.0f, -1.0f, 1.0f
975     };
976
977     const struct sVertex far_quad1[] =
978     {
979         {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
980         {-1.0f,  0.0f, 0.5f, 0xffff0000, 0xff000000},
981         { 0.0f,  0.0f, 0.5f, 0xffff0000, 0xff000000},
982         { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
983     };
984     const struct sVertex far_quad2[] =
985     {
986         {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
987         {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
988         { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
989         { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
990     };
991
992     memset(&caps, 0, sizeof(caps));
993     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
994     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
995     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
996     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
997
998     /* Setup initial states: No lighting, fog on, fog color */
999     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1000     ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
1001     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1002     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
1003     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1004     ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
1005
1006     /* First test: Both table fog and vertex fog off */
1007     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1008     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
1009     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1010     ok(hr == D3D_OK, "Turning off vertex fog returned %08x\n", hr);
1011
1012     /* Start = 0, end = 1. Should be default, but set them */
1013     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1014     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1015     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1016     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1017
1018     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1019     {
1020         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1021         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1022         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
1023         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1024                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1,
1025                                                      sizeof(untransformed_1[0]));
1026         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1027
1028         /* That makes it use the Z value */
1029         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1030         ok(hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %#08x\n", hr);
1031         /* Untransformed, vertex fog != none (or table fog != none):
1032          * Use the Z value as input into the equation
1033          */
1034         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1035                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2,
1036                                                      sizeof(untransformed_2[0]));
1037         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1038
1039         /* transformed verts */
1040         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1041         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1042         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1043         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1044                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1045                                                      sizeof(transformed_1[0]));
1046         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1047
1048         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1049         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1050         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
1051          * equation
1052          */
1053         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1054                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
1055                                                      sizeof(transformed_2[0]));
1056         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1057
1058         hr = IDirect3DDevice9_EndScene(device);
1059         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1060     }
1061     else
1062     {
1063         ok(FALSE, "BeginScene failed\n");
1064     }
1065
1066     color = getPixelColor(device, 160, 360);
1067     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1068     color = getPixelColor(device, 160, 120);
1069     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
1070     color = getPixelColor(device, 480, 120);
1071     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1072     if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1073     {
1074         color = getPixelColor(device, 480, 360);
1075         ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
1076     }
1077     else
1078     {
1079         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1080          * The settings above result in no fogging with vertex fog
1081          */
1082         color = getPixelColor(device, 480, 120);
1083         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1084         trace("Info: Table fog not supported by this device\n");
1085     }
1086     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1087
1088     /* Now test the special case fogstart == fogend */
1089     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1090     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1091
1092     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1093     {
1094         start = 512;
1095         end = 512;
1096         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1097         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1098         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1099         ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1100
1101         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1102         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1103         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1104         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %08x\n", hr);
1105         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1106         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1107
1108         /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
1109          * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
1110          * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
1111          * The third transformed quad remains unfogged because the fogcoords are read from the specular
1112          * color and has fixed fogstart and fogend.
1113          */
1114         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1115                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1,
1116                 sizeof(untransformed_1[0]));
1117         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1118         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1119                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2,
1120                 sizeof(untransformed_2[0]));
1121         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1122
1123         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1124         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1125         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1126         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1127                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1128                 sizeof(transformed_1[0]));
1129         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1130
1131         hr = IDirect3DDevice9_EndScene(device);
1132         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1133     }
1134     else
1135     {
1136         ok(FALSE, "BeginScene failed\n");
1137     }
1138     color = getPixelColor(device, 160, 360);
1139     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1140     color = getPixelColor(device, 160, 120);
1141     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1142     color = getPixelColor(device, 480, 120);
1143     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1144     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1145
1146     /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1147      * but without shaders it seems to work everywhere
1148      */
1149     end = 0.2;
1150     start = 0.8;
1151     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1152     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1153     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1154     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1155     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1156     ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1157
1158     /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1159      * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1160      * so skip this for now
1161      */
1162     for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1163         const char *mode = (i ? "table" : "vertex");
1164         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1165         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1166         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1167         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1168         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1169         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1170         hr = IDirect3DDevice9_BeginScene(device);
1171         ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1172         if(SUCCEEDED(hr)) {
1173             WORD Indices2[] = { 0,  1,  2,  2,  3, 0,
1174                                 4,  5,  6,  6,  7, 4,
1175                                 8,  9, 10, 10, 11, 8,
1176                             12, 13, 14, 14, 15, 12};
1177
1178             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1179                     16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1180                     sizeof(rev_fog_quads[0]));
1181             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1182
1183             hr = IDirect3DDevice9_EndScene(device);
1184             ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1185         }
1186         color = getPixelColor(device, 160, 360);
1187         ok(color_match(color, 0x0000ff00, 1),
1188                 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1189
1190         color = getPixelColor(device, 160, 120);
1191         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1192                 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1193
1194         color = getPixelColor(device, 480, 120);
1195         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1196                 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1197
1198         color = getPixelColor(device, 480, 360);
1199         ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1200
1201         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1202
1203         if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1204             skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1205             break;
1206         }
1207     }
1208
1209     if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1210     {
1211         /* A simple fog + non-identity world matrix test */
1212         hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)world_mat1);
1213         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %#08x\n", hr);
1214
1215         start = 0.0;
1216         end = 1.0;
1217         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
1218         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1219         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
1220         ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1221         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1222         ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
1223         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1224         ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
1225
1226         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1227         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %#08x\n", hr);
1228
1229         if (IDirect3DDevice9_BeginScene(device) == D3D_OK)
1230         {
1231             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1232             ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
1233
1234             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1235                     2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
1236             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1237
1238             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1239                     2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
1240             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1241
1242             hr = IDirect3DDevice9_EndScene(device);
1243             ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
1244         }
1245         else
1246         {
1247             ok(FALSE, "BeginScene failed\n");
1248         }
1249
1250         color = getPixelColor(device, 160, 360);
1251         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 4),
1252                 "Unfogged quad has color %08x\n", color);
1253         color = getPixelColor(device, 160, 120);
1254         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1255                 "Fogged out quad has color %08x\n", color);
1256
1257         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1258
1259         /* Test fog behavior with an orthogonal (but non-identity) projection matrix */
1260         hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)world_mat2);
1261         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1262         hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (const D3DMATRIX *)proj_mat);
1263         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1264
1265         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1266         ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
1267
1268         if (IDirect3DDevice9_BeginScene(device) == D3D_OK)
1269         {
1270             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1271             ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
1272
1273             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1274                     2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1275             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1276
1277             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1278                     2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1279             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1280
1281             hr = IDirect3DDevice9_EndScene(device);
1282             ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
1283         }
1284         else
1285         {
1286             ok(FALSE, "BeginScene failed\n");
1287         }
1288
1289         color = getPixelColor(device, 160, 360);
1290         todo_wine ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
1291         color = getPixelColor(device, 160, 120);
1292         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1293                 "Fogged out quad has color %08x\n", color);
1294
1295         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1296
1297         hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)ident_mat);
1298         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1299         hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (const D3DMATRIX *)ident_mat);
1300         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1301     }
1302     else
1303     {
1304         skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
1305     }
1306
1307     /* Test RANGEFOG vs FOGTABLEMODE */
1308     if ((caps.RasterCaps & (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE)) ==
1309             (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE))
1310     {
1311         struct sVertex untransformed_3[] =
1312         {
1313             {-1.0,-1.0,   0.4999f,      0xFFFF0000,     0xFF000000  },
1314             {-1.0, 1.0,   0.4999f,      0xFFFF0000,     0xFF000000  },
1315             { 1.0,-1.0,   0.4999f,      0xFFFF0000,     0xFF000000  },
1316             { 1.0, 1.0,   0.4999f,      0xFFFF0000,     0xFF000000  },
1317         };
1318
1319         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1320         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
1321         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1322         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
1323
1324         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, TRUE);
1325         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1326
1327         /* z=0.4999, set the fogstart to 0.5 and fogend slightly higher. If range fog
1328          * is not used, the fog coordinate will be equal to fogstart and the quad not
1329          * fogged. If range fog is used the fog coordinate will be slightly higher and
1330          * the fog coordinate will be > fogend, so we get a fully fogged quad. The fog
1331          * is calculated per vertex and interpolated, so even the center of the screen
1332          * where the difference doesn't matter will be fogged, but check the corners in
1333          * case a d3d/gl implementation decides to calculate the fog factor per fragment */
1334         start = 0.5f;
1335         end = 0.50001f;
1336         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1337         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1338         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1339         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1340
1341         /* Table fog: Range fog is not used */
1342         hr = IDirect3DDevice9_BeginScene(device);
1343         ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
1344         if (SUCCEEDED(hr))
1345         {
1346             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1347             ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1348             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, untransformed_3, sizeof(*untransformed_3));
1349             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
1350             hr = IDirect3DDevice9_EndScene(device);
1351             ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
1352         }
1353         color = getPixelColor(device, 10, 10);
1354         ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1355         color = getPixelColor(device, 630, 10);
1356         ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1357         color = getPixelColor(device, 10, 470);
1358         ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1359         color = getPixelColor(device, 630, 470);
1360         ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1361
1362         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1363         ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
1364
1365         /* Vertex fog: Rangefog is used */
1366         hr = IDirect3DDevice9_BeginScene(device);
1367         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP returned %#08x\n", hr);
1368         if (SUCCEEDED(hr))
1369         {
1370             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1371             ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1372             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1373             ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1374             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, untransformed_3, sizeof(*untransformed_3));
1375             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
1376             hr = IDirect3DDevice9_EndScene(device);
1377             ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
1378         }
1379         color = getPixelColor(device, 10, 10);
1380         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1381                 "Rangefog with vertex fog returned color 0x%08x\n", color);
1382         color = getPixelColor(device, 630, 10);
1383         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1384                 "Rangefog with vertex fog returned color 0x%08x\n", color);
1385         color = getPixelColor(device, 10, 470);
1386         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1387                 "Rangefog with vertex fog returned color 0x%08x\n", color);
1388         color = getPixelColor(device, 630, 470);
1389         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1390                 "Rangefog with vertex fog returned color 0x%08x\n", color);
1391
1392         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1393         ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
1394
1395         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, FALSE);
1396         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1397     }
1398     else
1399     {
1400         skip("Range fog or table fog not supported, skipping range fog tests\n");
1401     }
1402
1403     /* Turn off the fog master switch to avoid confusing other tests */
1404     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1405     ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1406     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1407     ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %08x\n", hr);
1408     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1409     ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1410 }
1411
1412 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1413  * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1414  * regardless of the actual addressing mode set. The way this test works is
1415  * that we sample in one of the corners of the cubemap with filtering enabled,
1416  * and check the interpolated color. There are essentially two reasonable
1417  * things an implementation can do: Either pick one of the faces and
1418  * interpolate the edge texel with itself (i.e., clamp within the face), or
1419  * interpolate between the edge texels of the three involved faces. It should
1420  * never involve the border color or the other side (texcoord wrapping) of a
1421  * face in the interpolation. */
1422 static void test_cube_wrap(IDirect3DDevice9 *device)
1423 {
1424     static const float quad[][6] = {
1425         {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1426         {-1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1427         { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1428         { 1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1429     };
1430
1431     static const D3DVERTEXELEMENT9 decl_elements[] = {
1432         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1433         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1434         D3DDECL_END()
1435     };
1436
1437     static const struct {
1438         D3DTEXTUREADDRESS mode;
1439         const char *name;
1440     } address_modes[] = {
1441         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1442         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1443         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1444         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1445         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1446     };
1447
1448     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1449     IDirect3DCubeTexture9 *texture = NULL;
1450     IDirect3DSurface9 *surface = NULL;
1451     IDirect3DSurface9 *face_surface;
1452     D3DLOCKED_RECT locked_rect;
1453     HRESULT hr;
1454     UINT x;
1455     INT y, face;
1456
1457     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1458     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1459     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1460     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1461
1462     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1463             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1464     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1465
1466     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1467             D3DPOOL_DEFAULT, &texture, NULL);
1468     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1469
1470     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1471     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1472
1473     for (y = 0; y < 128; ++y)
1474     {
1475         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1476         for (x = 0; x < 64; ++x)
1477         {
1478             *ptr++ = 0xff0000ff;
1479         }
1480         for (x = 64; x < 128; ++x)
1481         {
1482             *ptr++ = 0xffff0000;
1483         }
1484     }
1485
1486     hr = IDirect3DSurface9_UnlockRect(surface);
1487     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1488
1489     hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
1490     ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1491
1492     hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1493     ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1494
1495     IDirect3DSurface9_Release(face_surface);
1496
1497     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1498     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1499
1500     for (y = 0; y < 128; ++y)
1501     {
1502         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1503         for (x = 0; x < 64; ++x)
1504         {
1505             *ptr++ = 0xffff0000;
1506         }
1507         for (x = 64; x < 128; ++x)
1508         {
1509             *ptr++ = 0xff0000ff;
1510         }
1511     }
1512
1513     hr = IDirect3DSurface9_UnlockRect(surface);
1514     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1515
1516     /* Create cube faces */
1517     for (face = 1; face < 6; ++face)
1518     {
1519         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1520         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1521
1522         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1523         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1524
1525         IDirect3DSurface9_Release(face_surface);
1526     }
1527
1528     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1529     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1530
1531     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1532     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1533     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1534     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1535     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1536     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1537
1538     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1539     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1540
1541     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1542     {
1543         DWORD color;
1544
1545         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1546         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1547         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1548         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1549
1550         hr = IDirect3DDevice9_BeginScene(device);
1551         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1552
1553         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1554         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1555
1556         hr = IDirect3DDevice9_EndScene(device);
1557         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1558
1559         color = getPixelColor(device, 320, 240);
1560         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1561                 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
1562                 color, address_modes[x].name);
1563
1564         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1565         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1566
1567         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1568         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1569     }
1570
1571     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1572     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1573
1574     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1575     IDirect3DCubeTexture9_Release(texture);
1576     IDirect3DSurface9_Release(surface);
1577 }
1578
1579 static void offscreen_test(IDirect3DDevice9 *device)
1580 {
1581     HRESULT hr;
1582     IDirect3DTexture9 *offscreenTexture = NULL;
1583     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1584     DWORD color;
1585
1586     static const float quad[][5] = {
1587         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1588         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1589         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1590         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1591     };
1592
1593     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1594     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1595
1596     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1597     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1598     if(!offscreenTexture) {
1599         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1600         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1601         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1602         if(!offscreenTexture) {
1603             skip("Cannot create an offscreen render target\n");
1604             goto out;
1605         }
1606     }
1607
1608     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1609     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1610     if(!backbuffer) {
1611         goto out;
1612     }
1613
1614     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1615     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1616     if(!offscreen) {
1617         goto out;
1618     }
1619
1620     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1621     ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1622
1623     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1624     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1625     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1626     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1627     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1628     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1629     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1630     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1631     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1632     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1633
1634     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1635         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1636         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1637         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1638         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1639
1640         /* Draw without textures - Should result in a white quad */
1641         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1642         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1643
1644         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1645         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1646         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1647         ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1648
1649         /* This time with the texture */
1650         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1651         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1652
1653         IDirect3DDevice9_EndScene(device);
1654     }
1655
1656     /* Center quad - should be white */
1657     color = getPixelColor(device, 320, 240);
1658     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1659     /* Some quad in the cleared part of the texture */
1660     color = getPixelColor(device, 170, 240);
1661     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1662     /* Part of the originally cleared back buffer */
1663     color = getPixelColor(device, 10, 10);
1664     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1665     if(0) {
1666         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1667          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1668          * the offscreen rendering mode this test would succeed or fail
1669          */
1670         color = getPixelColor(device, 10, 470);
1671         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1672     }
1673
1674     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1675
1676 out:
1677     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1678     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1679
1680     /* restore things */
1681     if(backbuffer) {
1682         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1683         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1684         IDirect3DSurface9_Release(backbuffer);
1685     }
1686     if(offscreenTexture) {
1687         IDirect3DTexture9_Release(offscreenTexture);
1688     }
1689     if(offscreen) {
1690         IDirect3DSurface9_Release(offscreen);
1691     }
1692 }
1693
1694 /* This test tests fog in combination with shaders.
1695  * What's tested: linear fog (vertex and table) with pixel shader
1696  *                linear table fog with non foggy vertex shader
1697  *                vertex fog with foggy vertex shader, non-linear
1698  *                fog with shader, non-linear fog with foggy shader,
1699  *                linear table fog with foggy shader
1700  */
1701 static void fog_with_shader_test(IDirect3DDevice9 *device)
1702 {
1703     HRESULT hr;
1704     DWORD color;
1705     union {
1706         float f;
1707         DWORD i;
1708     } start, end;
1709     unsigned int i, j;
1710
1711     /* basic vertex shader without fog computation ("non foggy") */
1712     static const DWORD vertex_shader_code1[] = {
1713         0xfffe0101,                                                             /* vs_1_1                       */
1714         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1715         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1716         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1717         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1718         0x0000ffff
1719     };
1720     /* basic vertex shader with reversed fog computation ("foggy") */
1721     static const DWORD vertex_shader_code2[] = {
1722         0xfffe0101,                                                             /* vs_1_1                        */
1723         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1724         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1725         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1726         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1727         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1728         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1729         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1730         0x0000ffff
1731     };
1732     /* basic pixel shader */
1733     static const DWORD pixel_shader_code[] = {
1734         0xffff0101,                                                             /* ps_1_1     */
1735         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, vo */
1736         0x0000ffff
1737     };
1738
1739     static struct vertex quad[] = {
1740         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1741         {-1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1742         { 1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1743         { 1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1744     };
1745
1746     static const D3DVERTEXELEMENT9 decl_elements[] = {
1747         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1748         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1749         D3DDECL_END()
1750     };
1751
1752     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1753     IDirect3DVertexShader9      *vertex_shader[3]   = {NULL, NULL, NULL};
1754     IDirect3DPixelShader9       *pixel_shader[2]    = {NULL, NULL};
1755
1756     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1757     static const struct test_data_t {
1758         int vshader;
1759         int pshader;
1760         D3DFOGMODE vfog;
1761         D3DFOGMODE tfog;
1762         unsigned int color[11];
1763     } test_data[] = {
1764         /* only pixel shader: */
1765         {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1766         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1767         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1768         {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1769         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1770         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1771         {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1772         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1773         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1774         {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1775         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1776         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1777         {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1778         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1779         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1780
1781         /* vertex shader */
1782         {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1783         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1784          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1785         {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1786         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1787         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1788         {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1789         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1790         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1791
1792         {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1793         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1794         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1795         {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1796         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1797         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1798
1799         /* vertex shader and pixel shader */
1800         /* The next 4 tests would read the fog coord output, but it isn't available.
1801          * The result is a fully fogged quad, no matter what the Z coord is. This is on
1802          * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1803          * These tests should be disabled if some other hardware behaves differently
1804          */
1805         {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1806         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1807         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1808         {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1809         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1810         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1811         {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1812         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1813         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1814         {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1815         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1816         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1817
1818         /* These use the Z coordinate with linear table fog */
1819         {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1820         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1821         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1822         {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1823         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1824         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1825         {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1826         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1827         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1828         {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1829         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1830         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1831
1832         /* Non-linear table fog without fog coord */
1833         {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1834         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1835         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1836         {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1837         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1838         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1839
1840 #if 0  /* FIXME: these fail on GeForce 8500 */
1841         /* foggy vertex shader */
1842         {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1843         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1844          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1845         {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1846         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1847          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1848         {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1849         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1850          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1851         {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1852         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1853          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1854 #endif
1855
1856         /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1857          * all using the fixed fog-coord linear fog
1858          */
1859         {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1860         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1861          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1862         {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1863         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1864          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1865         {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1866         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1867          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1868         {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1869         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1870          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1871
1872         /* These use table fog. Here the shader-provided fog coordinate is
1873          * ignored and the z coordinate used instead
1874          */
1875         {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1876         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1877         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1878         {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1879         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1880         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1881         {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1882         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1883         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1884     };
1885
1886     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1887     start.f=0.1f;
1888     end.f=0.9f;
1889
1890     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1891     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1892     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1893     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1894     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1895     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1896     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1897     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1898
1899     /* Setup initial states: No lighting, fog on, fog color */
1900     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1901     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1902     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1903     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1904     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1905     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1906     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1907     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1908
1909     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1910     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1911     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1912     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1913
1914     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1915     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1916     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1917     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1918     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1919
1920     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1921     {
1922         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1923         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1924         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1925         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1926         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1927         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1928         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1929         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1930
1931         for(j=0; j < 11; j++)
1932         {
1933             /* Don't use the whole zrange to prevent rounding errors */
1934             quad[0].z = 0.001f + (float)j / 10.02f;
1935             quad[1].z = 0.001f + (float)j / 10.02f;
1936             quad[2].z = 0.001f + (float)j / 10.02f;
1937             quad[3].z = 0.001f + (float)j / 10.02f;
1938
1939             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1940             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1941
1942             hr = IDirect3DDevice9_BeginScene(device);
1943             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1944
1945             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1946             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1947
1948             hr = IDirect3DDevice9_EndScene(device);
1949             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1950
1951             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1952             color = getPixelColor(device, 128, 240);
1953             ok(color_match(color, test_data[i].color[j], 13),
1954                 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1955                 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1956
1957             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1958         }
1959     }
1960
1961     /* reset states */
1962     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1963     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1964     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1965     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1966     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1967     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1968     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1969     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1970
1971     IDirect3DVertexShader9_Release(vertex_shader[1]);
1972     IDirect3DVertexShader9_Release(vertex_shader[2]);
1973     IDirect3DPixelShader9_Release(pixel_shader[1]);
1974     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1975 }
1976
1977 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1978     unsigned int i, x, y;
1979     HRESULT hr;
1980     IDirect3DTexture9 *texture[2] = {NULL, NULL};
1981     D3DLOCKED_RECT locked_rect;
1982
1983     /* Generate the textures */
1984     for(i=0; i<2; i++)
1985     {
1986         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1987                                             D3DPOOL_MANAGED, &texture[i], NULL);
1988         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1989
1990         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1991         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1992         for (y = 0; y < 128; ++y)
1993         {
1994             if(i)
1995             { /* Set up black texture with 2x2 texel white spot in the middle */
1996                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1997                 for (x = 0; x < 128; ++x)
1998                 {
1999                     if(y>62 && y<66 && x>62 && x<66)
2000                         *ptr++ = 0xffffffff;
2001                     else
2002                         *ptr++ = 0xff000000;
2003                 }
2004             }
2005             else
2006             { /* Set up a displacement map which points away from the center parallel to the closest axis.
2007                * (if multiplied with bumpenvmat)
2008               */
2009                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2010                 for (x = 0; x < 128; ++x)
2011                 {
2012                     if(abs(x-64)>abs(y-64))
2013                     {
2014                         if(x < 64)
2015                             *ptr++ = 0xc000;
2016                         else
2017                             *ptr++ = 0x4000;
2018                     }
2019                     else
2020                     {
2021                         if(y < 64)
2022                             *ptr++ = 0x0040;
2023                         else
2024                             *ptr++ = 0x00c0;
2025                     }
2026                 }
2027             }
2028         }
2029         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
2030         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2031
2032         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
2033         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2034
2035         /* Disable texture filtering */
2036         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2037         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2038         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2039         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2040
2041         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2042         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
2043         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2044         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
2045     }
2046 }
2047
2048 /* test the behavior of the texbem instruction
2049  * with normal 2D and projective 2D textures
2050  */
2051 static void texbem_test(IDirect3DDevice9 *device)
2052 {
2053     HRESULT hr;
2054     DWORD color;
2055     int i;
2056
2057     static const DWORD pixel_shader_code[] = {
2058         0xffff0101,                         /* ps_1_1*/
2059         0x00000042, 0xb00f0000,             /* tex t0*/
2060         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
2061         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
2062         0x0000ffff
2063     };
2064     static const DWORD double_texbem_code[] =  {
2065         0xffff0103,                                         /* ps_1_3           */
2066         0x00000042, 0xb00f0000,                             /* tex t0           */
2067         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
2068         0x00000042, 0xb00f0002,                             /* tex t2           */
2069         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
2070         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
2071         0x0000ffff                                          /* end              */
2072     };
2073
2074
2075     static const float quad[][7] = {
2076         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
2077         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
2078         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
2079         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
2080     };
2081     static const float quad_proj[][9] = {
2082         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
2083         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
2084         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
2085         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
2086     };
2087
2088     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
2089         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2090         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2091         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
2092         D3DDECL_END()
2093     },{
2094         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2095         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2096         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
2097         D3DDECL_END()
2098     } };
2099
2100     /* use asymmetric matrix to test loading */
2101     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
2102
2103     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
2104     IDirect3DPixelShader9       *pixel_shader       = NULL;
2105     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
2106     D3DLOCKED_RECT locked_rect;
2107
2108     generate_bumpmap_textures(device);
2109
2110     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2111     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2112     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2113     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2114     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
2115
2116     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
2117     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2118
2119     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2120     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2121
2122     for(i=0; i<2; i++)
2123     {
2124         if(i)
2125         {
2126             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
2127             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2128         }
2129
2130         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
2131         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
2132         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2133         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
2134
2135         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
2136         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2137         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2138         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2139
2140         hr = IDirect3DDevice9_BeginScene(device);
2141         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2142
2143         if(!i)
2144             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2145         else
2146             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
2147         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2148
2149         hr = IDirect3DDevice9_EndScene(device);
2150         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2151
2152         color = getPixelColor(device, 320-32, 240);
2153         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2154         color = getPixelColor(device, 320+32, 240);
2155         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2156         color = getPixelColor(device, 320, 240-32);
2157         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2158         color = getPixelColor(device, 320, 240+32);
2159         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2160
2161         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2162         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2163
2164         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2165         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2166         IDirect3DPixelShader9_Release(pixel_shader);
2167
2168         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2169         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2170         IDirect3DVertexDeclaration9_Release(vertex_declaration);
2171     }
2172
2173     /* clean up */
2174     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
2175     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
2176
2177     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2178     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2179
2180     for(i=0; i<2; i++)
2181     {
2182         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
2183         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
2184         IDirect3DTexture9_Release(texture); /* For the GetTexture */
2185         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
2186         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2187         IDirect3DTexture9_Release(texture);
2188     }
2189
2190     /* Test double texbem */
2191     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
2192     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2193     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
2194     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2195     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
2196     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2197     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
2198     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2199
2200     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
2201     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2202     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
2203     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
2204
2205     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2206     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2207
2208     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
2209     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2210     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
2211     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
2212     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
2213     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2214
2215     {
2216         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
2217 #define tex  0x00ff0000
2218 #define tex1 0x0000ff00
2219 #define origin 0x000000ff
2220         static const DWORD pixel_data[] = {
2221             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2222             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2223             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2224             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2225             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
2226             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2227             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2228             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2229         };
2230 #undef tex1
2231 #undef tex2
2232 #undef origin
2233
2234         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
2235         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2236         for(i = 0; i < 8; i++) {
2237             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
2238         }
2239         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
2240         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2241     }
2242
2243     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2244     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2245     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
2246     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2247     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
2248     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2249     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
2250     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2251     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2252     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2253     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
2254     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2255
2256     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
2257     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
2258     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2259     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2260     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2261     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2262     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2263     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2264     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2265     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2266
2267     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
2268     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
2269     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2270     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2271     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2272     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2273     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2274     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2275     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2276     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2277
2278     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2279     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2280     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2281     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2282     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2283     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2284     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2285     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2286     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2287     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2288     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2289     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2290     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2291     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2292     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2293     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2294
2295     hr = IDirect3DDevice9_BeginScene(device);
2296     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2297     if(SUCCEEDED(hr)) {
2298         static const float double_quad[] = {
2299             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2300              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2301             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2302              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2303         };
2304
2305         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
2306         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2307         hr = IDirect3DDevice9_EndScene(device);
2308         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2309     }
2310     color = getPixelColor(device, 320, 240);
2311     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2312
2313     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2314     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2315     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
2316     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2317     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
2318     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2319     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
2320     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2321     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2322     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2323
2324     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2325     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2326
2327     IDirect3DPixelShader9_Release(pixel_shader);
2328     IDirect3DTexture9_Release(texture);
2329     IDirect3DTexture9_Release(texture1);
2330     IDirect3DTexture9_Release(texture2);
2331 }
2332
2333 static void z_range_test(IDirect3DDevice9 *device)
2334 {
2335     const struct vertex quad[] =
2336     {
2337         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
2338         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
2339         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
2340         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
2341     };
2342     const struct vertex quad2[] =
2343     {
2344         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
2345         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
2346         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
2347         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
2348     };
2349
2350     const struct tvertex quad3[] =
2351     {
2352         {    0,   240,   1.1f,  1.0,                    0xffffff00},
2353         {    0,   480,   1.1f,  1.0,                    0xffffff00},
2354         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
2355         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
2356     };
2357     const struct tvertex quad4[] =
2358     {
2359         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
2360         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
2361         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
2362         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
2363     };
2364     HRESULT hr;
2365     DWORD color;
2366     IDirect3DVertexShader9 *shader;
2367     IDirect3DVertexDeclaration9 *decl;
2368     D3DCAPS9 caps;
2369     const DWORD shader_code[] = {
2370         0xfffe0101,                                     /* vs_1_1           */
2371         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
2372         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
2373         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
2374         0x0000ffff                                      /* end              */
2375     };
2376     static const D3DVERTEXELEMENT9 decl_elements[] = {
2377         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2378         D3DDECL_END()
2379     };
2380
2381     IDirect3DDevice9_GetDeviceCaps(device, &caps);
2382
2383     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2384      * then call Present. Then clear the color buffer to make sure it has some defined content
2385      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2386      * by the depth value.
2387      */
2388     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2389     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2390     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2391     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2392     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2393     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2394
2395     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2396     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2397     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2398     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2399     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2400     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2401     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2402     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2403     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2404     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2405
2406     hr = IDirect3DDevice9_BeginScene(device);
2407     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2408     if(hr == D3D_OK)
2409     {
2410         /* Test the untransformed vertex path */
2411         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2412         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2413         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2414         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2415         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2416         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2417
2418         /* Test the transformed vertex path */
2419         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2420         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2421
2422         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2423         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2424         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2425         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2426         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2427         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2428
2429         hr = IDirect3DDevice9_EndScene(device);
2430         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2431     }
2432
2433     /* Do not test the exact corner pixels, but go pretty close to them */
2434
2435     /* Clipped because z > 1.0 */
2436     color = getPixelColor(device, 28, 238);
2437     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2438     color = getPixelColor(device, 28, 241);
2439     if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2440     {
2441         ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2442     }
2443     else
2444     {
2445         ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2446     }
2447
2448     /* Not clipped, > z buffer clear value(0.75) */
2449     color = getPixelColor(device, 31, 238);
2450     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2451     color = getPixelColor(device, 31, 241);
2452     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2453     color = getPixelColor(device, 100, 238);
2454     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2455     color = getPixelColor(device, 100, 241);
2456     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2457
2458     /* Not clipped, < z buffer clear value */
2459     color = getPixelColor(device, 104, 238);
2460     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2461     color = getPixelColor(device, 104, 241);
2462     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2463     color = getPixelColor(device, 318, 238);
2464     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2465     color = getPixelColor(device, 318, 241);
2466     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2467
2468     /* Clipped because z < 0.0 */
2469     color = getPixelColor(device, 321, 238);
2470     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2471     color = getPixelColor(device, 321, 241);
2472     if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2473     {
2474         ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2475     }
2476     else
2477     {
2478         ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2479     }
2480
2481     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2482     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2483
2484     /* Test the shader path */
2485     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2486         skip("Vertex shaders not supported\n");
2487         goto out;
2488     }
2489     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2490     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2491     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2492     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2493
2494     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2495
2496     IDirect3DDevice9_SetVertexDeclaration(device, decl);
2497     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2498     IDirect3DDevice9_SetVertexShader(device, shader);
2499     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2500
2501     hr = IDirect3DDevice9_BeginScene(device);
2502     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2503     if(hr == D3D_OK)
2504     {
2505         float colorf[] = {1.0, 0.0, 0.0, 1.0};
2506         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2507         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2508         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2509         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2510         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2511         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2512         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2513         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2514         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2515
2516         hr = IDirect3DDevice9_EndScene(device);
2517         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2518     }
2519
2520     IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2521     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2522     IDirect3DDevice9_SetVertexShader(device, NULL);
2523     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2524
2525     IDirect3DVertexDeclaration9_Release(decl);
2526     IDirect3DVertexShader9_Release(shader);
2527
2528     /* Z < 1.0 */
2529     color = getPixelColor(device, 28, 238);
2530     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2531
2532     /* 1.0 < z < 0.75 */
2533     color = getPixelColor(device, 31, 238);
2534     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2535     color = getPixelColor(device, 100, 238);
2536     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2537
2538     /* 0.75 < z < 0.0 */
2539     color = getPixelColor(device, 104, 238);
2540     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2541     color = getPixelColor(device, 318, 238);
2542     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2543
2544     /* 0.0 < z */
2545     color = getPixelColor(device, 321, 238);
2546     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2547
2548     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2549     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2550
2551     out:
2552     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2553     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2554     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2555     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2556     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2557     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2558 }
2559
2560 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2561 {
2562     D3DSURFACE_DESC desc;
2563     D3DLOCKED_RECT l;
2564     HRESULT hr;
2565     unsigned int x, y;
2566     DWORD *mem;
2567
2568     memset(&desc, 0, sizeof(desc));
2569     memset(&l, 0, sizeof(l));
2570     hr = IDirect3DSurface9_GetDesc(surface, &desc);
2571     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2572     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2573     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2574     if(FAILED(hr)) return;
2575
2576     for(y = 0; y < desc.Height; y++)
2577     {
2578         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2579         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2580         {
2581             mem[x] = color;
2582         }
2583     }
2584     hr = IDirect3DSurface9_UnlockRect(surface);
2585     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2586 }
2587
2588 /* This tests a variety of possible StretchRect() situations */
2589 static void stretchrect_test(IDirect3DDevice9 *device)
2590 {
2591     HRESULT hr;
2592     IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL, *tex_rt_dest640_480 = NULL;
2593     IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL, *surf_tex_rt_dest640_480 = NULL;
2594     IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2595     IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2596     IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2597     IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2598     IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2599     IDirect3DSurface9 *orig_rt = NULL;
2600     IDirect3DSurface9 *backbuffer = NULL;
2601     DWORD color;
2602
2603     RECT src_rect64 = {0, 0, 64, 64};
2604     RECT src_rect64_flipy = {0, 64, 64, 0};
2605     RECT dst_rect64 = {0, 0, 64, 64};
2606     RECT dst_rect64_flipy = {0, 64, 64, 0};
2607
2608     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2609     ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2610     if(!orig_rt) {
2611         goto out;
2612     }
2613
2614     /* Create our temporary surfaces in system memory */
2615     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2616     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2617     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2618     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2619
2620     /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2621     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2622     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2623     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2624     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2625     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2626     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2627
2628     /* Create render target surfaces */
2629     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2630     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2631     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2632     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2633     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2634     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2635     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2636     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2637
2638     /* Create render target textures */
2639     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2640     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2641     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2642     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2643     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2644     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2645     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
2646     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2647     if (tex_rt32) {
2648         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2649         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2650     }
2651     if (tex_rt64) {
2652         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2653         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2654     }
2655     if (tex_rt_dest64) {
2656         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2657         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2658     }
2659     if (tex_rt_dest64) {
2660         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
2661         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2662     }
2663
2664     /* Create regular textures in D3DPOOL_DEFAULT */
2665     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2666     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2667     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2668     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2669     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2670     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2671     if (tex32) {
2672         hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2673         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2674     }
2675     if (tex64) {
2676         hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2677         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2678     }
2679     if (tex_dest64) {
2680         hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2681         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2682     }
2683
2684     /*********************************************************************
2685      * Tests for when the source parameter is an offscreen plain surface *
2686      *********************************************************************/
2687
2688     /* Fill the offscreen 64x64 surface with green */
2689     if (surf_offscreen64)
2690         fill_surface(surf_offscreen64, 0xff00ff00);
2691
2692     /* offscreenplain ==> offscreenplain, same size */
2693     if(surf_offscreen64 && surf_offscreen_dest64) {
2694         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2695         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2696
2697         if (hr == D3D_OK) {
2698             color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2699             ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2700         }
2701
2702         /* Blit without scaling */
2703         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64, 0);
2704         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2705
2706         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2707         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_offscreen_dest64, &dst_rect64, 0);
2708         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2709
2710         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2711         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64_flipy, 0);
2712         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2713     }
2714
2715     /* offscreenplain ==> rendertarget texture, same size */
2716     if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2717         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2718         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2719
2720         /* We can't lock rendertarget textures, so copy to our temp surface first */
2721         if (hr == D3D_OK) {
2722             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2723             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2724         }
2725
2726         if (hr == D3D_OK) {
2727             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2728             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2729         }
2730
2731         /* Blit without scaling */
2732         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2733         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2734
2735         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2736         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2737         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2738
2739         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2740         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2741         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2742     }
2743
2744     /* offscreenplain ==> rendertarget surface, same size */
2745     if(surf_offscreen64 && surf_rt_dest64) {
2746         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2747         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2748
2749         if (hr == D3D_OK) {
2750             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2751             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2752         }
2753
2754         /* Blit without scaling */
2755         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2756         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2757
2758         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2759         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2760         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2761
2762         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2763         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2764         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2765     }
2766
2767     /* offscreenplain ==> texture, same size (should fail) */
2768     if(surf_offscreen64 && surf_tex_dest64) {
2769         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2770         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2771     }
2772
2773     /* Fill the smaller offscreen surface with red */
2774     fill_surface(surf_offscreen32, 0xffff0000);
2775
2776     /* offscreenplain ==> offscreenplain, scaling (should fail) */
2777     if(surf_offscreen32 && surf_offscreen64) {
2778         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2779         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2780     }
2781
2782     /* offscreenplain ==> rendertarget texture, scaling */
2783     if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2784         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2785         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2786
2787         /* We can't lock rendertarget textures, so copy to our temp surface first */
2788         if (hr == D3D_OK) {
2789             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2790             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2791         }
2792
2793         if (hr == D3D_OK) {
2794             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2795             ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2796         }
2797     }
2798
2799     /* offscreenplain ==> rendertarget surface, scaling */
2800     if(surf_offscreen32 && surf_rt_dest64) {
2801         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2802         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2803
2804         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2805         ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2806     }
2807
2808     /* offscreenplain ==> texture, scaling (should fail) */
2809     if(surf_offscreen32 && surf_tex_dest64) {
2810         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2811         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2812     }
2813
2814     /************************************************************
2815      * Tests for when the source parameter is a regular texture *
2816      ************************************************************/
2817
2818     /* Fill the surface of the regular texture with blue */
2819     if (surf_tex64 && surf_temp64) {
2820         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2821         fill_surface(surf_temp64, 0xff0000ff);
2822         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2823         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2824     }
2825
2826     /* texture ==> offscreenplain, same size */
2827     if(surf_tex64 && surf_offscreen64) {
2828         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2829         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2830     }
2831
2832     /* texture ==> rendertarget texture, same size */
2833     if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2834         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2835         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2836
2837         /* We can't lock rendertarget textures, so copy to our temp surface first */
2838         if (hr == D3D_OK) {
2839             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2840             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2841         }
2842
2843         if (hr == D3D_OK) {
2844             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2845             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2846         }
2847
2848         /* Blit without scaling */
2849         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2850         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2851
2852         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2853         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2854         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2855
2856         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2857         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2858         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2859     }
2860
2861     /* texture ==> rendertarget surface, same size */
2862     if(surf_tex64 && surf_rt_dest64) {
2863         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2864         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2865
2866         if (hr == D3D_OK) {
2867             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2868             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2869         }
2870
2871         /* Blit without scaling */
2872         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2873         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2874
2875         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2876         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2877         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2878
2879         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2880         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2881         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2882     }
2883
2884     /* texture ==> texture, same size (should fail) */
2885     if(surf_tex64 && surf_tex_dest64) {
2886         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2887         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2888     }
2889
2890     /* Fill the surface of the smaller regular texture with red */
2891     if (surf_tex32 && surf_temp32) {
2892         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2893         fill_surface(surf_temp32, 0xffff0000);
2894         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2895         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2896     }
2897
2898     /* texture ==> offscreenplain, scaling (should fail) */
2899     if(surf_tex32 && surf_offscreen64) {
2900         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2901         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2902     }
2903
2904     /* texture ==> rendertarget texture, scaling */
2905     if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2906         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2907         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2908
2909         /* We can't lock rendertarget textures, so copy to our temp surface first */
2910         if (hr == D3D_OK) {
2911             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2912             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2913         }
2914
2915         if (hr == D3D_OK) {
2916             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2917             ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2918         }
2919     }
2920
2921     /* texture ==> rendertarget surface, scaling */
2922     if(surf_tex32 && surf_rt_dest64) {
2923         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2924         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2925
2926         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2927         ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2928     }
2929
2930     /* texture ==> texture, scaling (should fail) */
2931     if(surf_tex32 && surf_tex_dest64) {
2932         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2933         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2934     }
2935
2936     /*****************************************************************
2937      * Tests for when the source parameter is a rendertarget texture *
2938      *****************************************************************/
2939
2940     /* Fill the surface of the rendertarget texture with white */
2941     if (surf_tex_rt64 && surf_temp64) {
2942         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2943         fill_surface(surf_temp64, 0xffffffff);
2944         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2945         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2946     }
2947
2948     /* rendertarget texture ==> offscreenplain, same size */
2949     if(surf_tex_rt64 && surf_offscreen64) {
2950         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2951         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2952     }
2953
2954     /* rendertarget texture ==> rendertarget texture, same size */
2955     if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2956         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2957         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2958
2959         /* We can't lock rendertarget textures, so copy to our temp surface first */
2960         if (hr == D3D_OK) {
2961             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2962             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2963         }
2964
2965         if (hr == D3D_OK) {
2966             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2967             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2968         }
2969
2970         /* Blit without scaling */
2971         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2972         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2973
2974         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2975         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2976         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2977
2978         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2979         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2980         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2981     }
2982
2983     /* rendertarget texture ==> rendertarget surface, same size */
2984     if(surf_tex_rt64 && surf_rt_dest64) {
2985         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2986         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2987
2988         if (hr == D3D_OK) {
2989             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2990             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2991         }
2992
2993         /* Blit without scaling */
2994         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2995         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2996
2997         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2998         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2999         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3000
3001         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3002         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
3003         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3004     }
3005
3006     /* rendertarget texture ==> texture, same size (should fail) */
3007     if(surf_tex_rt64 && surf_tex_dest64) {
3008         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
3009         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3010     }
3011
3012     /* Fill the surface of the smaller rendertarget texture with red */
3013     if (surf_tex_rt32 && surf_temp32) {
3014         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
3015         fill_surface(surf_temp32, 0xffff0000);
3016         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
3017         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
3018     }
3019
3020     /* rendertarget texture ==> offscreenplain, scaling (should fail) */
3021     if(surf_tex_rt32 && surf_offscreen64) {
3022         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
3023         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3024     }
3025
3026     /* rendertarget texture ==> rendertarget texture, scaling */
3027     if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
3028         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
3029         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3030
3031         /* We can't lock rendertarget textures, so copy to our temp surface first */
3032         if (hr == D3D_OK) {
3033             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3034             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3035         }
3036
3037         if (hr == D3D_OK) {
3038             color = getPixelColorFromSurface(surf_temp64, 48, 48);
3039             ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3040         }
3041     }
3042
3043     /* rendertarget texture ==> rendertarget surface, scaling */
3044     if(surf_tex_rt32 && surf_rt_dest64) {
3045         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
3046         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3047
3048         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3049         ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3050     }
3051
3052     /* rendertarget texture ==> texture, scaling (should fail) */
3053     if(surf_tex_rt32 && surf_tex_dest64) {
3054         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
3055         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3056     }
3057
3058     /*****************************************************************
3059      * Tests for when the source parameter is a rendertarget surface *
3060      *****************************************************************/
3061
3062     /* Fill the surface of the rendertarget surface with black */
3063     if (surf_rt64)
3064         fill_surface(surf_rt64, 0xff000000);
3065
3066     /* rendertarget texture ==> offscreenplain, same size */
3067     if(surf_rt64 && surf_offscreen64) {
3068         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
3069         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3070     }
3071
3072     /* rendertarget surface ==> rendertarget texture, same size */
3073     if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
3074         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
3075         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3076
3077         /* We can't lock rendertarget textures, so copy to our temp surface first */
3078         if (hr == D3D_OK) {
3079             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3080             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3081         }
3082
3083         if (hr == D3D_OK) {
3084             color = getPixelColorFromSurface(surf_temp64, 32, 32);
3085             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
3086         }
3087
3088         /* Blit without scaling */
3089         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
3090         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3091
3092         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3093         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
3094         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3095
3096         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3097         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
3098         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3099     }
3100
3101     /* rendertarget surface ==> rendertarget surface, same size */
3102     if(surf_rt64 && surf_rt_dest64) {
3103         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
3104         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3105
3106         if (hr == D3D_OK) {
3107             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3108             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
3109         }
3110
3111         /* Blit without scaling */
3112         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
3113         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3114
3115         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3116         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64_flipy, 0);
3117         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3118
3119         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3120         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
3121         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3122     }
3123
3124     /* rendertarget surface ==> texture, same size (should fail) */
3125     if(surf_rt64 && surf_tex_dest64) {
3126         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
3127         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3128     }
3129
3130     /* Fill the surface of the smaller rendertarget texture with red */
3131     if (surf_rt32)
3132         fill_surface(surf_rt32, 0xffff0000);
3133
3134     /* rendertarget surface ==> offscreenplain, scaling (should fail) */
3135     if(surf_rt32 && surf_offscreen64) {
3136         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
3137         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3138     }
3139
3140     /* rendertarget surface ==> rendertarget texture, scaling */
3141     if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
3142         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
3143         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3144
3145         /* We can't lock rendertarget textures, so copy to our temp surface first */
3146         if (hr == D3D_OK) {
3147             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3148             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3149         }
3150
3151         if (hr == D3D_OK) {
3152             color = getPixelColorFromSurface(surf_temp64, 48, 48);
3153             ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3154         }
3155     }
3156
3157     /* rendertarget surface ==> rendertarget surface, scaling */
3158     if(surf_rt32 && surf_rt_dest64) {
3159         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
3160         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3161
3162         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3163         ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3164     }
3165
3166     /* rendertarget surface ==> texture, scaling (should fail) */
3167     if(surf_rt32 && surf_tex_dest64) {
3168         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
3169         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3170     }
3171
3172     /* backbuffer ==> surface tests (no scaling) */
3173     if(backbuffer && surf_tex_rt_dest640_480)
3174     {
3175         RECT src_rect = {0, 0, 640, 480};
3176         RECT src_rect_flipy = {0, 480, 640, 0};
3177         RECT dst_rect = {0, 0, 640, 480};
3178         RECT dst_rect_flipy = {0, 480, 640, 0};
3179
3180         /* Blit with NULL rectangles */
3181         hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, 0);
3182         ok( hr == D3D_OK, "StretchRect backbuffer ==> texture same size failed:\n");
3183
3184         /* Blit without scaling */
3185         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect, 0);
3186         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3187
3188         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3189         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy, surf_tex_rt_dest640_480, &dst_rect, 0);
3190         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3191
3192         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3193         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect_flipy, 0);
3194         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3195     }
3196
3197     /* TODO: Test format conversions */
3198
3199
3200 out:
3201     /* Clean up */
3202     if (backbuffer)
3203         IDirect3DSurface9_Release(backbuffer);
3204     if (surf_rt32)
3205         IDirect3DSurface9_Release(surf_rt32);
3206     if (surf_rt64)
3207         IDirect3DSurface9_Release(surf_rt64);
3208     if (surf_rt_dest64)
3209         IDirect3DSurface9_Release(surf_rt_dest64);
3210     if (surf_temp32)
3211         IDirect3DSurface9_Release(surf_temp32);
3212     if (surf_temp64)
3213         IDirect3DSurface9_Release(surf_temp64);
3214     if (surf_offscreen32)
3215         IDirect3DSurface9_Release(surf_offscreen32);
3216     if (surf_offscreen64)
3217         IDirect3DSurface9_Release(surf_offscreen64);
3218     if (surf_offscreen_dest64)
3219         IDirect3DSurface9_Release(surf_offscreen_dest64);
3220
3221     if (tex_rt32) {
3222         if (surf_tex_rt32)
3223             IDirect3DSurface9_Release(surf_tex_rt32);
3224         IDirect3DTexture9_Release(tex_rt32);
3225     }
3226     if (tex_rt64) {
3227         if (surf_tex_rt64)
3228             IDirect3DSurface9_Release(surf_tex_rt64);
3229         IDirect3DTexture9_Release(tex_rt64);
3230     }
3231     if (tex_rt_dest64) {
3232         if (surf_tex_rt_dest64)
3233             IDirect3DSurface9_Release(surf_tex_rt_dest64);
3234         IDirect3DTexture9_Release(tex_rt_dest64);
3235     }
3236     if (tex_rt_dest640_480) {
3237         if (surf_tex_rt_dest640_480)
3238             IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
3239         IDirect3DTexture9_Release(tex_rt_dest640_480);
3240     }
3241     if (tex32) {
3242         if (surf_tex32)
3243             IDirect3DSurface9_Release(surf_tex32);
3244         IDirect3DTexture9_Release(tex32);
3245     }
3246     if (tex64) {
3247         if (surf_tex64)
3248             IDirect3DSurface9_Release(surf_tex64);
3249         IDirect3DTexture9_Release(tex64);
3250     }
3251     if (tex_dest64) {
3252         if (surf_tex_dest64)
3253             IDirect3DSurface9_Release(surf_tex_dest64);
3254         IDirect3DTexture9_Release(tex_dest64);
3255     }
3256
3257     if (orig_rt) {
3258         hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
3259         ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
3260         IDirect3DSurface9_Release(orig_rt);
3261     }
3262 }
3263
3264 static void maxmip_test(IDirect3DDevice9 *device)
3265 {
3266     IDirect3DTexture9 *texture = NULL;
3267     IDirect3DSurface9 *surface = NULL;
3268     HRESULT hr;
3269     DWORD color;
3270     static const struct
3271     {
3272         struct
3273         {
3274             float x, y, z;
3275             float s, t;
3276         }
3277         v[4];
3278     }
3279     quads[] =
3280     {
3281         {{
3282             {-1.0, -1.0,  0.0,  0.0,  0.0},
3283             {-1.0,  0.0,  0.0,  0.0,  1.0},
3284             { 0.0, -1.0,  0.0,  1.0,  0.0},
3285             { 0.0,  0.0,  0.0,  1.0,  1.0},
3286         }},
3287         {{
3288             { 0.0, -1.0,  0.0,  0.0,  0.0},
3289             { 0.0,  0.0,  0.0,  0.0,  1.0},
3290             { 1.0, -1.0,  0.0,  1.0,  0.0},
3291             { 1.0,  0.0,  0.0,  1.0,  1.0},
3292         }},
3293         {{
3294             { 0.0,  0.0,  0.0,  0.0,  0.0},
3295             { 0.0,  1.0,  0.0,  0.0,  1.0},
3296             { 1.0,  0.0,  0.0,  1.0,  0.0},
3297             { 1.0,  1.0,  0.0,  1.0,  1.0},
3298         }},
3299         {{
3300             {-1.0,  0.0,  0.0,  0.0,  0.0},
3301             {-1.0,  1.0,  0.0,  0.0,  1.0},
3302             { 0.0,  0.0,  0.0,  1.0,  0.0},
3303             { 0.0,  1.0,  0.0,  1.0,  1.0},
3304         }},
3305     };
3306
3307     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
3308                                         &texture, NULL);
3309     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3310     if(!texture)
3311     {
3312         skip("Failed to create test texture\n");
3313         return;
3314     }
3315
3316     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3317     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3318     fill_surface(surface, 0xffff0000);
3319     IDirect3DSurface9_Release(surface);
3320     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
3321     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3322     fill_surface(surface, 0xff00ff00);
3323     IDirect3DSurface9_Release(surface);
3324     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3325     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3326     fill_surface(surface, 0xff0000ff);
3327     IDirect3DSurface9_Release(surface);
3328
3329     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3330     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3331     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3332     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3333
3334     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3335     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3336
3337     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3338     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3339
3340     hr = IDirect3DDevice9_BeginScene(device);
3341     if(SUCCEEDED(hr))
3342     {
3343         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3344         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3345         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3346         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3347
3348         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3349         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3350         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3351         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3352
3353         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3354         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3355         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3356         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3357
3358         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3359         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3360         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3361         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3362         hr = IDirect3DDevice9_EndScene(device);
3363         ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
3364     }
3365
3366     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
3367     color = getPixelColor(device, 160, 360);
3368     ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
3369     color = getPixelColor(device, 480, 360);
3370     ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
3371     color = getPixelColor(device, 480, 120);
3372     ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
3373     color = getPixelColor(device, 160, 120);
3374     ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
3375     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3376     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3377
3378     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3379     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3380
3381     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3382     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3383
3384     hr = IDirect3DDevice9_BeginScene(device);
3385     if(SUCCEEDED(hr))
3386     {
3387         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3388         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3389         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3390         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3391
3392         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3393         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3394         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3395         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3396
3397         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3398         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3399         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3400         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3401
3402         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3403         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3404         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3405         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3406         hr = IDirect3DDevice9_EndScene(device);
3407         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
3408     }
3409
3410     /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3411      * level 3 (> levels in texture) samples from the highest level in the
3412      * texture (level 2). */
3413     color = getPixelColor(device, 160, 360);
3414     ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
3415     color = getPixelColor(device, 480, 360);
3416     ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
3417     color = getPixelColor(device, 480, 120);
3418     ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
3419     color = getPixelColor(device, 160, 120);
3420     ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
3421     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3422     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3423
3424     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3425     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3426
3427     hr = IDirect3DDevice9_BeginScene(device);
3428     if(SUCCEEDED(hr))
3429     {
3430         DWORD ret;
3431
3432         /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
3433         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3434         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3435         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3436         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3437         ret = IDirect3DTexture9_SetLOD(texture, 1);
3438         ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
3439         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3440         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3441
3442         /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
3443         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3444         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3445         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3446         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3447         ret = IDirect3DTexture9_SetLOD(texture, 2);
3448         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3449         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3450         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3451
3452         /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
3453         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3454         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3455         ret = IDirect3DTexture9_SetLOD(texture, 1);
3456         ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
3457         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3458         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3459
3460         /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
3461         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3462         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3463         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3464         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3465         ret = IDirect3DTexture9_SetLOD(texture, 1);
3466         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3467         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3468         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3469         hr = IDirect3DDevice9_EndScene(device);
3470         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3471     }
3472
3473     /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3474      * level 3 (> levels in texture) samples from the highest level in the
3475      * texture (level 2). */
3476     color = getPixelColor(device, 160, 360);
3477     ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
3478     color = getPixelColor(device, 480, 360);
3479     ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
3480     color = getPixelColor(device, 480, 120);
3481     ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
3482     color = getPixelColor(device, 160, 120);
3483     ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
3484
3485     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3486     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3487
3488     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3489     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3490     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3491     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3492     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3493     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3494     IDirect3DTexture9_Release(texture);
3495 }
3496
3497 static void release_buffer_test(IDirect3DDevice9 *device)
3498 {
3499     IDirect3DVertexBuffer9 *vb = NULL;
3500     IDirect3DIndexBuffer9 *ib = NULL;
3501     HRESULT hr;
3502     BYTE *data;
3503     LONG ref;
3504
3505     static const struct vertex quad[] = {
3506         {-1.0,      -1.0,       0.1,        0xffff0000},
3507         {-1.0,       1.0,       0.1,        0xffff0000},
3508         { 1.0,       1.0,       0.1,        0xffff0000},
3509
3510         {-1.0,      -1.0,       0.1,        0xff00ff00},
3511         {-1.0,       1.0,       0.1,        0xff00ff00},
3512         { 1.0,       1.0,       0.1,        0xff00ff00}
3513     };
3514     short indices[] = {3, 4, 5};
3515
3516     /* Index and vertex buffers should always be creatable */
3517     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
3518                                               D3DPOOL_MANAGED, &vb, NULL);
3519     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
3520     if(!vb) {
3521         skip("Failed to create a vertex buffer\n");
3522         return;
3523     }
3524     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3525     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
3526     if(!ib) {
3527         skip("Failed to create an index buffer\n");
3528         return;
3529     }
3530
3531     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3532     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3533     memcpy(data, quad, sizeof(quad));
3534     hr = IDirect3DVertexBuffer9_Unlock(vb);
3535     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3536
3537     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3538     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3539     memcpy(data, indices, sizeof(indices));
3540     hr = IDirect3DIndexBuffer9_Unlock(ib);
3541     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3542
3543     hr = IDirect3DDevice9_SetIndices(device, ib);
3544     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3545     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3546     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3547     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3548     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3549
3550     /* Now destroy the bound index buffer and draw again */
3551     ref = IDirect3DIndexBuffer9_Release(ib);
3552     ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3553
3554     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3555     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3556
3557     hr = IDirect3DDevice9_BeginScene(device);
3558     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3559     if(SUCCEEDED(hr))
3560     {
3561         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3562          * making assumptions about the indices or vertices
3563          */
3564         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3565         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3566         hr = IDirect3DDevice9_EndScene(device);
3567         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3568     }
3569
3570     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3571     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3572
3573     hr = IDirect3DDevice9_SetIndices(device, NULL);
3574     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3575     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3576     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3577
3578     /* Index buffer was already destroyed as part of the test */
3579     IDirect3DVertexBuffer9_Release(vb);
3580 }
3581
3582 static void float_texture_test(IDirect3DDevice9 *device)
3583 {
3584     IDirect3D9 *d3d = NULL;
3585     HRESULT hr;
3586     IDirect3DTexture9 *texture = NULL;
3587     D3DLOCKED_RECT lr;
3588     float *data;
3589     DWORD color;
3590     float quad[] = {
3591         -1.0,      -1.0,       0.1,     0.0,    0.0,
3592         -1.0,       1.0,       0.1,     0.0,    1.0,
3593          1.0,      -1.0,       0.1,     1.0,    0.0,
3594          1.0,       1.0,       0.1,     1.0,    1.0,
3595     };
3596
3597     memset(&lr, 0, sizeof(lr));
3598     IDirect3DDevice9_GetDirect3D(device, &d3d);
3599     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3600                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3601         skip("D3DFMT_R32F textures not supported\n");
3602         goto out;
3603     }
3604
3605     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3606                                         D3DPOOL_MANAGED, &texture, NULL);
3607     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3608     if(!texture) {
3609         skip("Failed to create R32F texture\n");
3610         goto out;
3611     }
3612
3613     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3614     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3615     data = lr.pBits;
3616     *data = 0.0;
3617     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3618     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3619
3620     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3621     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3622
3623     hr = IDirect3DDevice9_BeginScene(device);
3624     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3625     if(SUCCEEDED(hr))
3626     {
3627         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3628         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3629
3630         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3631         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3632
3633         hr = IDirect3DDevice9_EndScene(device);
3634         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3635     }
3636     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3637     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3638
3639     color = getPixelColor(device, 240, 320);
3640     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3641
3642     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3643     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3644
3645 out:
3646     if(texture) IDirect3DTexture9_Release(texture);
3647     IDirect3D9_Release(d3d);
3648 }
3649
3650 static void g16r16_texture_test(IDirect3DDevice9 *device)
3651 {
3652     IDirect3D9 *d3d = NULL;
3653     HRESULT hr;
3654     IDirect3DTexture9 *texture = NULL;
3655     D3DLOCKED_RECT lr;
3656     DWORD *data;
3657     DWORD color;
3658     float quad[] = {
3659        -1.0,      -1.0,       0.1,     0.0,    0.0,
3660        -1.0,       1.0,       0.1,     0.0,    1.0,
3661         1.0,      -1.0,       0.1,     1.0,    0.0,
3662         1.0,       1.0,       0.1,     1.0,    1.0,
3663     };
3664
3665     memset(&lr, 0, sizeof(lr));
3666     IDirect3DDevice9_GetDirect3D(device, &d3d);
3667     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3668        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3669            skip("D3DFMT_G16R16 textures not supported\n");
3670            goto out;
3671     }
3672
3673     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3674                                         D3DPOOL_MANAGED, &texture, NULL);
3675     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3676     if(!texture) {
3677         skip("Failed to create D3DFMT_G16R16 texture\n");
3678         goto out;
3679     }
3680
3681     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3682     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3683     data = lr.pBits;
3684     *data = 0x0f00f000;
3685     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3686     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3687
3688     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3689     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3690
3691     hr = IDirect3DDevice9_BeginScene(device);
3692     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3693     if(SUCCEEDED(hr))
3694     {
3695         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3696         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3697
3698         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3699         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3700
3701         hr = IDirect3DDevice9_EndScene(device);
3702         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3703     }
3704     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3705     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3706
3707     color = getPixelColor(device, 240, 320);
3708     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3709        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3710
3711     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3712     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3713
3714 out:
3715     if(texture) IDirect3DTexture9_Release(texture);
3716     IDirect3D9_Release(d3d);
3717 }
3718
3719 static void check_rect(IDirect3DDevice9 *device, RECT r, const char *message)
3720 {
3721     LONG x_coords[2][2] =
3722     {
3723         {r.left - 1, r.left + 1},
3724         {r.right + 1, r.right - 1},
3725     };
3726     LONG y_coords[2][2] =
3727     {
3728         {r.top - 1, r.top + 1},
3729         {r.bottom + 1, r.bottom - 1}
3730     };
3731     unsigned int i, j, x_side, y_side;
3732
3733     for (i = 0; i < 2; ++i)
3734     {
3735         for (j = 0; j < 2; ++j)
3736         {
3737             for (x_side = 0; x_side < 2; ++x_side)
3738             {
3739                 for (y_side = 0; y_side < 2; ++y_side)
3740                 {
3741                     unsigned int x = x_coords[i][x_side], y = y_coords[j][y_side];
3742                     DWORD color;
3743                     DWORD expected = (x_side == 1 && y_side == 1) ? 0x00ffffff : 0;
3744
3745                     color = getPixelColor(device, x, y);
3746                     ok(color == expected, "%s: Pixel (%d, %d) has color %08x, expected %08x\n",
3747                             message, x, y, color, expected);
3748                 }
3749             }
3750         }
3751     }
3752 }
3753
3754 struct projected_textures_test_run
3755 {
3756     const char *message;
3757     DWORD flags;
3758     IDirect3DVertexDeclaration9 *decl;
3759     BOOL vs, ps;
3760     RECT rect;
3761 };
3762
3763 static void projected_textures_test(IDirect3DDevice9 *device,
3764         struct projected_textures_test_run tests[4])
3765 {
3766     unsigned int i;
3767
3768     static const DWORD vertex_shader[] =
3769     {
3770         0xfffe0101,                                     /* vs_1_1           */
3771         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
3772         0x0000001f, 0x80000005, 0x900f0001,             /* dcl_texcoord0 v1 */
3773         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
3774         0x00000001, 0xe00f0000, 0x90e40001,             /* mov oT0, v1      */
3775         0x0000ffff                                      /* end              */
3776     };
3777     static const DWORD pixel_shader[] =
3778     {
3779         0xffff0103,                                     /* ps_1_3           */
3780         0x00000042, 0xb00f0000,                         /* tex t0           */
3781         0x00000001, 0x800f0000, 0xb0e40000,             /* mov r0, t0       */
3782         0x0000ffff                                      /* end              */
3783     };
3784     IDirect3DVertexShader9 *vs = NULL;
3785     IDirect3DPixelShader9 *ps = NULL;
3786     HRESULT hr;
3787
3788     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader, &vs);
3789     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
3790     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader, &ps);
3791     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
3792
3793     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0f, 0);
3794     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3795
3796     hr = IDirect3DDevice9_BeginScene(device);
3797     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3798     if (FAILED(hr))
3799         return;
3800
3801     for (i = 0; i < 4; ++i)
3802     {
3803         DWORD value = 0xdeadbeef;
3804         static const float proj_quads[] =
3805         {
3806             -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3807              0.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3808             -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3809              0.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3810
3811              0.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3812              1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3813              0.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3814              1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3815
3816             -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3817              0.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3818             -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3819              0.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3820
3821              0.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3822              1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3823              0.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3824              1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3825         };
3826
3827         if (tests[i].vs)
3828             hr = IDirect3DDevice9_SetVertexShader(device, vs);
3829         else
3830             hr = IDirect3DDevice9_SetVertexShader(device, NULL);
3831         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
3832         if (tests[i].ps)
3833             hr = IDirect3DDevice9_SetPixelShader(device, ps);
3834         else
3835             hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3836         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3837
3838         hr = IDirect3DDevice9_SetVertexDeclaration(device, tests[i].decl);
3839         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3840
3841         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, tests[i].flags);
3842         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3843         hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, &value);
3844         ok(SUCCEEDED(hr) && value == tests[i].flags,
3845                 "GetTextureStageState returned: hr %08x, value %08x.\n", hr, value);
3846
3847         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
3848                 &proj_quads[i * 4 * 7], 7 * sizeof(float));
3849         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3850     }
3851
3852     hr = IDirect3DDevice9_EndScene(device);
3853     ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3854
3855     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
3856     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3857     IDirect3DVertexShader9_Release(vs);
3858     IDirect3DPixelShader9_Release(ps);
3859
3860     for (i = 0; i < 4; ++i)
3861         check_rect(device, tests[i].rect, tests[i].message);
3862
3863     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3864     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3865 }
3866
3867 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3868 {
3869     HRESULT hr;
3870     IDirect3D9 *d3d;
3871     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3872     D3DCAPS9 caps;
3873     IDirect3DTexture9 *texture = NULL;
3874     IDirect3DVolumeTexture9 *volume = NULL;
3875     unsigned int x, y, z;
3876     D3DLOCKED_RECT lr;
3877     D3DLOCKED_BOX lb;
3878     DWORD color;
3879     UINT w, h;
3880     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3, *decl4;
3881     float identity[16] = {1.0, 0.0, 0.0, 0.0,
3882                            0.0, 1.0, 0.0, 0.0,
3883                            0.0, 0.0, 1.0, 0.0,
3884                            0.0, 0.0, 0.0, 1.0};
3885     static const D3DVERTEXELEMENT9 decl_elements[] = {
3886         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3887         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3888         D3DDECL_END()
3889     };
3890     static const D3DVERTEXELEMENT9 decl_elements2[] = {
3891         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3892         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3893         D3DDECL_END()
3894     };
3895     static const D3DVERTEXELEMENT9 decl_elements3[] = {
3896         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3897         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3898         D3DDECL_END()
3899     };
3900     static const D3DVERTEXELEMENT9 decl_elements4[] = {
3901         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3902         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3903         D3DDECL_END()
3904     };
3905     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3906                                                  0x00, 0xff, 0x00, 0x00,
3907                                                  0x00, 0x00, 0x00, 0x00,
3908                                                  0x00, 0x00, 0x00, 0x00};
3909
3910     memset(&lr, 0, sizeof(lr));
3911     memset(&lb, 0, sizeof(lb));
3912     IDirect3DDevice9_GetDirect3D(device, &d3d);
3913     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3914                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3915         fmt = D3DFMT_A16B16G16R16;
3916     }
3917     IDirect3D9_Release(d3d);
3918
3919     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3920     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3921     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3922     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3923     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3924     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3925     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements4, &decl4);
3926     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3927     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3928     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3929     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3930     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3931     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3932     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3933     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3934     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3935     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3936     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3937     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3938     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3939     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3940     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3941     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3942     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3943     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3944     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3945
3946     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3947     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3948     w = min(1024, caps.MaxTextureWidth);
3949     h = min(1024, caps.MaxTextureHeight);
3950     hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3951                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3952     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3953     if(!texture) {
3954         skip("Failed to create the test texture\n");
3955         return;
3956     }
3957
3958     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3959      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3960      * 1.0 in red and green for the x and y coords
3961      */
3962     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3963     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3964     for(y = 0; y < h; y++) {
3965         for(x = 0; x < w; x++) {
3966             double r_f = (double) y / (double) h;
3967             double g_f = (double) x / (double) w;
3968             if(fmt == D3DFMT_A16B16G16R16) {
3969                 unsigned short r, g;
3970                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3971                 r = (unsigned short) (r_f * 65536.0);
3972                 g = (unsigned short) (g_f * 65536.0);
3973                 dst[0] = r;
3974                 dst[1] = g;
3975                 dst[2] = 0;
3976                 dst[3] = 65535;
3977             } else {
3978                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3979                 unsigned char r = (unsigned char) (r_f * 255.0);
3980                 unsigned char g = (unsigned char) (g_f * 255.0);
3981                 dst[0] = 0;
3982                 dst[1] = g;
3983                 dst[2] = r;
3984                 dst[3] = 255;
3985             }
3986         }
3987     }
3988     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3989     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3990     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3991     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3992
3993     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3994     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3995     hr = IDirect3DDevice9_BeginScene(device);
3996     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3997     if(SUCCEEDED(hr))
3998     {
3999         float quad1[] = {
4000             -1.0,      -1.0,       0.1,     1.0,    1.0,
4001             -1.0,       0.0,       0.1,     1.0,    1.0,
4002              0.0,      -1.0,       0.1,     1.0,    1.0,
4003              0.0,       0.0,       0.1,     1.0,    1.0,
4004         };
4005         float quad2[] = {
4006             -1.0,       0.0,       0.1,     1.0,    1.0,
4007             -1.0,       1.0,       0.1,     1.0,    1.0,
4008              0.0,       0.0,       0.1,     1.0,    1.0,
4009              0.0,       1.0,       0.1,     1.0,    1.0,
4010         };
4011         float quad3[] = {
4012              0.0,       0.0,       0.1,     0.5,    0.5,
4013              0.0,       1.0,       0.1,     0.5,    0.5,
4014              1.0,       0.0,       0.1,     0.5,    0.5,
4015              1.0,       1.0,       0.1,     0.5,    0.5,
4016         };
4017         float quad4[] = {
4018              320,       480,       0.1,     1.0,    0.0,    1.0,
4019              320,       240,       0.1,     1.0,    0.0,    1.0,
4020              640,       480,       0.1,     1.0,    0.0,    1.0,
4021              640,       240,       0.1,     1.0,    0.0,    1.0,
4022         };
4023         float mat[16] = {0.0, 0.0, 0.0, 0.0,
4024                           0.0, 0.0, 0.0, 0.0,
4025                           0.0, 0.0, 0.0, 0.0,
4026                           0.0, 0.0, 0.0, 0.0};
4027
4028         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
4029         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4030         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4031         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4032         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4033
4034         /* What happens with transforms enabled? */
4035         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4036         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4037         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4038         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4039
4040         /* What happens if 4 coords are used, but only 2 given ?*/
4041         mat[8] = 1.0;
4042         mat[13] = 1.0;
4043         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4044         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4045         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
4046         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4047         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4048         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4049
4050         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
4051          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
4052          * due to the coords in the vertices. (turns out red, indeed)
4053          */
4054         memset(mat, 0, sizeof(mat));
4055         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4056         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4057         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
4058         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4059         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4060         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4061         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4062         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4063
4064         hr = IDirect3DDevice9_EndScene(device);
4065         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4066     }
4067     color = getPixelColor(device, 160, 360);
4068     ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
4069     color = getPixelColor(device, 160, 120);
4070     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4071     color = getPixelColor(device, 480, 120);
4072     ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
4073     color = getPixelColor(device, 480, 360);
4074     ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
4075     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4076     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4077
4078     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
4079     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4080
4081     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4082     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4083     hr = IDirect3DDevice9_BeginScene(device);
4084     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4085     if(SUCCEEDED(hr))
4086     {
4087         float quad1[] = {
4088             -1.0,      -1.0,       0.1,     0.8,    0.2,
4089             -1.0,       0.0,       0.1,     0.8,    0.2,
4090              0.0,      -1.0,       0.1,     0.8,    0.2,
4091              0.0,       0.0,       0.1,     0.8,    0.2,
4092         };
4093         float quad2[] = {
4094             -1.0,       0.0,       0.1,     0.5,    1.0,
4095             -1.0,       1.0,       0.1,     0.5,    1.0,
4096              0.0,       0.0,       0.1,     0.5,    1.0,
4097              0.0,       1.0,       0.1,     0.5,    1.0,
4098         };
4099         float quad3[] = {
4100              0.0,       0.0,       0.1,     0.5,    1.0,
4101              0.0,       1.0,       0.1,     0.5,    1.0,
4102              1.0,       0.0,       0.1,     0.5,    1.0,
4103              1.0,       1.0,       0.1,     0.5,    1.0,
4104         };
4105         float quad4[] = {
4106              0.0,      -1.0,       0.1,     0.8,    0.2,
4107              0.0,       0.0,       0.1,     0.8,    0.2,
4108              1.0,      -1.0,       0.1,     0.8,    0.2,
4109              1.0,       0.0,       0.1,     0.8,    0.2,
4110         };
4111         float mat[16] = {0.0, 0.0, 0.0, 0.0,
4112                           0.0, 0.0, 0.0, 0.0,
4113                           0.0, 1.0, 0.0, 0.0,
4114                           0.0, 0.0, 0.0, 0.0};
4115
4116         /* What happens to the default 1 in the 3rd coordinate if it is disabled?
4117          */
4118         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4119         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4120         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4121         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4122
4123         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4124         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4125
4126         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
4127          * it behaves like COUNT2 because normal textures require 2 coords
4128          */
4129         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4130         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4131         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
4132         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4133
4134         /* Just to be sure, the same as quad2 above */
4135         memset(mat, 0, sizeof(mat));
4136         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4137         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4138         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4139         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4140         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4141         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4142
4143         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
4144          * used? And what happens to the first?
4145          */
4146         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4147         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4148         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4149         ok(SUCCEEDED(hr), "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     color = getPixelColor(device, 160, 360);
4155     ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
4156     color = getPixelColor(device, 160, 120);
4157     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4158     color = getPixelColor(device, 480, 120);
4159     ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
4160        "quad 3 has color %08x, expected 0x00ff8000\n", color);
4161     color = getPixelColor(device, 480, 360);
4162     ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
4163        "quad 4 has color %08x, expected 0x0033cc00\n", color);
4164     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4165     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4166
4167     IDirect3DTexture9_Release(texture);
4168
4169     /* Test projected textures, without any fancy matrices */
4170     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
4171     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4172     if (SUCCEEDED(hr))
4173     {
4174         struct projected_textures_test_run projected_tests_1[4] =
4175         {
4176             {
4177                 "D3DTTFF_COUNT4 | D3DTTFF_PROJECTED - bottom left",
4178                 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED,
4179                 decl3,
4180                 FALSE, TRUE,
4181                 {120, 300, 240, 390},
4182             },
4183             {
4184                 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED - bottom right",
4185                 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4186                 decl3,
4187                 FALSE, TRUE,
4188                 {400, 360, 480, 420},
4189             },
4190             /* Try with some invalid values */
4191             {
4192                 "0xffffffff (draws like COUNT4 | PROJECTED) - top left",
4193                 0xffffffff,
4194                 decl3,
4195                 FALSE, TRUE,
4196                 {120, 60, 240, 150}
4197             },
4198             {
4199                 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (draws non-projected) - top right",
4200                 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4201                 decl4,
4202                 FALSE, TRUE,
4203                 {340, 210, 360, 225},
4204             }
4205         };
4206         struct projected_textures_test_run projected_tests_2[4] =
4207         {
4208             {
4209                 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED, texcoord has 4 components) - bottom left",
4210                 D3DTTFF_PROJECTED,
4211                 decl3,
4212                 FALSE, TRUE,
4213                 {120, 300, 240, 390},
4214             },
4215             {
4216                 "D3DTTFF_PROJECTED (like COUNT3 | PROJECTED, texcoord has only 3 components) - bottom right",
4217                 D3DTTFF_PROJECTED,
4218                 decl,
4219                 FALSE, TRUE,
4220                 {400, 360, 480, 420},
4221             },
4222             {
4223                 "0xffffffff (like COUNT3 | PROJECTED, texcoord has only 3 components) - top left",
4224                 0xffffffff,
4225                 decl,
4226                 FALSE, TRUE,
4227                 {80, 120, 160, 180},
4228             },
4229             {
4230                 "D3DTTFF_COUNT1 (draws non-projected) - top right",
4231                 D3DTTFF_COUNT1,
4232                 decl4,
4233                 FALSE, TRUE,
4234                 {340, 210, 360, 225},
4235             }
4236         };
4237         struct projected_textures_test_run projected_tests_3[4] =
4238         {
4239             {
4240                 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom left",
4241                 D3DTTFF_PROJECTED,
4242                 decl3,
4243                 TRUE, FALSE,
4244                 {120, 300, 240, 390},
4245             },
4246             {
4247                 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom right",
4248                 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4249                 decl3,
4250                 TRUE, TRUE,
4251                 {440, 300, 560, 390},
4252             },
4253             {
4254                 "0xffffffff (like COUNT4 | PROJECTED) - top left",
4255                 0xffffffff,
4256                 decl3,
4257                 TRUE, TRUE,
4258                 {120, 60, 240, 150},
4259             },
4260             {
4261                 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - top right",
4262                 D3DTTFF_PROJECTED,
4263                 decl3,
4264                 FALSE, FALSE,
4265                 {440, 60, 560, 150},
4266             },
4267         };
4268
4269         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4270         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4271
4272         hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4273         ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
4274         for(x = 0; x < 4; x++) {
4275             memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
4276         }
4277         hr = IDirect3DTexture9_UnlockRect(texture, 0);
4278         ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
4279         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4280         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4281
4282         projected_textures_test(device, projected_tests_1);
4283         projected_textures_test(device, projected_tests_2);
4284         projected_textures_test(device, projected_tests_3);
4285
4286         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4287         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4288         IDirect3DTexture9_Release(texture);
4289     }
4290
4291     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
4292     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4293     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
4294      * Thus watch out if sampling from texels between 0 and 1.
4295      */
4296     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
4297     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
4298        "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
4299     if(!volume) {
4300         skip("Failed to create a volume texture\n");
4301         goto out;
4302     }
4303
4304     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
4305     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
4306     for(z = 0; z < 32; z++) {
4307         for(y = 0; y < 32; y++) {
4308             for(x = 0; x < 32; x++) {
4309                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
4310                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
4311                 float r_f = (float) x / 31.0;
4312                 float g_f = (float) y / 31.0;
4313                 float b_f = (float) z / 31.0;
4314
4315                 if(fmt == D3DFMT_A16B16G16R16) {
4316                     unsigned short *mem_s = mem;
4317                     mem_s[0]  = r_f * 65535.0;
4318                     mem_s[1]  = g_f * 65535.0;
4319                     mem_s[2]  = b_f * 65535.0;
4320                     mem_s[3]  = 65535;
4321                 } else {
4322                     unsigned char *mem_c = mem;
4323                     mem_c[0]  = b_f * 255.0;
4324                     mem_c[1]  = g_f * 255.0;
4325                     mem_c[2]  = r_f * 255.0;
4326                     mem_c[3]  = 255;
4327                 }
4328             }
4329         }
4330     }
4331     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
4332     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4333
4334     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
4335     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4336
4337     hr = IDirect3DDevice9_BeginScene(device);
4338     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4339     if(SUCCEEDED(hr))
4340     {
4341         float quad1[] = {
4342             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4343             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4344              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4345              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
4346         };
4347         float quad2[] = {
4348             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4349             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
4350              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4351              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
4352         };
4353         float quad3[] = {
4354              0.0,       0.0,       0.1,     0.0,    0.0,
4355              0.0,       1.0,       0.1,     0.0,    0.0,
4356              1.0,       0.0,       0.1,     0.0,    0.0,
4357              1.0,       1.0,       0.1,     0.0,    0.0
4358         };
4359         float quad4[] = {
4360              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4361              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4362              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4363              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
4364         };
4365         float mat[16] = {1.0, 0.0, 0.0, 0.0,
4366                          0.0, 0.0, 1.0, 0.0,
4367                          0.0, 1.0, 0.0, 0.0,
4368                          0.0, 0.0, 0.0, 1.0};
4369         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4370         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4371
4372         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
4373          * values
4374          */
4375         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4376         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4377         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4378         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4379         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4380         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4381
4382         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
4383          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
4384          * otherwise the w will be missing(blue).
4385          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
4386          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
4387          */
4388         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4389         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4390         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4391         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4392
4393         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
4394         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4395         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4396         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4397         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4398         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4399         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4400         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4401         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4402
4403         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
4404          * disable. ATI extends it up to the amount of values needed for the volume texture
4405          */
4406         memset(mat, 0, sizeof(mat));
4407         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4408         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4409         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4410         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4411         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4412         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4413         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4414         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4415
4416         hr = IDirect3DDevice9_EndScene(device);
4417         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4418     }
4419
4420     color = getPixelColor(device, 160, 360);
4421     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
4422     color = getPixelColor(device, 160, 120);
4423     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
4424        "quad 2 has color %08x, expected 0x00ffff00\n", color);
4425     color = getPixelColor(device, 480, 120);
4426     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
4427     color = getPixelColor(device, 480, 360);
4428     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
4429
4430     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4431     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4432
4433     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
4434     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4435     hr = IDirect3DDevice9_BeginScene(device);
4436     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4437     if(SUCCEEDED(hr))
4438     {
4439         float quad1[] = {
4440             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4441             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4442              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4443              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
4444         };
4445         float quad2[] = {
4446             -1.0,       0.0,       0.1,
4447             -1.0,       1.0,       0.1,
4448              0.0,       0.0,       0.1,
4449              0.0,       1.0,       0.1,
4450         };
4451         float quad3[] = {
4452              0.0,       0.0,       0.1,     1.0,
4453              0.0,       1.0,       0.1,     1.0,
4454              1.0,       0.0,       0.1,     1.0,
4455              1.0,       1.0,       0.1,     1.0
4456         };
4457         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
4458                            0.0, 0.0, 0.0, 0.0,
4459                            0.0, 0.0, 0.0, 0.0,
4460                            0.0, 1.0, 0.0, 0.0};
4461         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
4462                            1.0, 0.0, 0.0, 0.0,
4463                            0.0, 1.0, 0.0, 0.0,
4464                            0.0, 0.0, 1.0, 0.0};
4465         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4466         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4467
4468         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
4469          * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
4470          * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
4471          * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
4472          * 4th *input* coordinate.
4473          */
4474         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4475         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4476         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4477         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4478         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4479         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4480
4481         /* None passed */
4482         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4483         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4484         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4485         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4486         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4487         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4488
4489         /* 4 used, 1 passed */
4490         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4491         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4492         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
4493         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4494         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4495         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4496
4497         hr = IDirect3DDevice9_EndScene(device);
4498         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4499     }
4500     color = getPixelColor(device, 160, 360);
4501     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4502     color = getPixelColor(device, 160, 120);
4503     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4504     color = getPixelColor(device, 480, 120);
4505     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4506     /* Quad4: unused */
4507
4508     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4509     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4510
4511     IDirect3DVolumeTexture9_Release(volume);
4512
4513     out:
4514     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4515     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4516     IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
4517     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4518     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4519     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4520     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4521     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4522     IDirect3DVertexDeclaration9_Release(decl);
4523     IDirect3DVertexDeclaration9_Release(decl2);
4524     IDirect3DVertexDeclaration9_Release(decl3);
4525     IDirect3DVertexDeclaration9_Release(decl4);
4526 }
4527
4528 static void texdepth_test(IDirect3DDevice9 *device)
4529 {
4530     IDirect3DPixelShader9 *shader;
4531     HRESULT hr;
4532     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
4533     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
4534     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
4535     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
4536     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
4537     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
4538     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
4539     DWORD shader_code[] = {
4540         0xffff0104,                                                                 /* ps_1_4               */
4541         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
4542         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
4543         0x0000fffd,                                                                 /* phase                */
4544         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
4545         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
4546         0x0000ffff                                                                  /* end                  */
4547     };
4548     DWORD color;
4549     float vertex[] = {
4550        -1.0,   -1.0,    0.0,
4551         1.0,   -1.0,    1.0,
4552        -1.0,    1.0,    0.0,
4553         1.0,    1.0,    1.0
4554     };
4555
4556     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4557     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4558
4559     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4560     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4561     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4562     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4563     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4564     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4565     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4566     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4567     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4568     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4569
4570     /* Fill the depth buffer with a gradient */
4571     hr = IDirect3DDevice9_BeginScene(device);
4572     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4573     if(SUCCEEDED(hr))
4574     {
4575         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4576         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4577         hr = IDirect3DDevice9_EndScene(device);
4578         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4579     }
4580
4581     /* Now perform the actual tests. Same geometry, but with the shader */
4582     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4583     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4584     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4585     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4586     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4587     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4588
4589     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4590     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF 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, 3 * sizeof(float));
4596         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4597
4598         hr = IDirect3DDevice9_EndScene(device);
4599         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4600     }
4601
4602     color = getPixelColor(device, 158, 240);
4603     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4604     color = getPixelColor(device, 162, 240);
4605     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
4606
4607     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4608     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4609
4610     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4611     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4612
4613     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
4614     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4615     hr = IDirect3DDevice9_BeginScene(device);
4616     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4617     if(SUCCEEDED(hr))
4618     {
4619         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4620         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4621
4622         hr = IDirect3DDevice9_EndScene(device);
4623         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4624     }
4625
4626     color = getPixelColor(device, 318, 240);
4627     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4628     color = getPixelColor(device, 322, 240);
4629     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4630
4631     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4632     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4633
4634     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4635     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4636
4637     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4638     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4639     hr = IDirect3DDevice9_BeginScene(device);
4640     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4641     if(SUCCEEDED(hr))
4642     {
4643         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4644         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4645
4646         hr = IDirect3DDevice9_EndScene(device);
4647         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4648     }
4649
4650     color = getPixelColor(device, 1, 240);
4651     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4652
4653     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4654     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4655
4656     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4657     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4658
4659     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4660     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4661     hr = IDirect3DDevice9_BeginScene(device);
4662     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4663     if(SUCCEEDED(hr))
4664     {
4665         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4666         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4667
4668         hr = IDirect3DDevice9_EndScene(device);
4669         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4670     }
4671     color = getPixelColor(device, 318, 240);
4672     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4673     color = getPixelColor(device, 322, 240);
4674     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
4675
4676     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4677     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4678
4679     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4680     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4681
4682     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
4683     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4684     hr = IDirect3DDevice9_BeginScene(device);
4685     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4686     if(SUCCEEDED(hr))
4687     {
4688         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4689         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4690
4691         hr = IDirect3DDevice9_EndScene(device);
4692         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4693     }
4694
4695     color = getPixelColor(device, 1, 240);
4696     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4697
4698     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4699     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4700
4701     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4702     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4703
4704     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4705     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4706     hr = IDirect3DDevice9_BeginScene(device);
4707     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4708     if(SUCCEEDED(hr))
4709     {
4710         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4711         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4712
4713         hr = IDirect3DDevice9_EndScene(device);
4714         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4715     }
4716
4717     color = getPixelColor(device, 638, 240);
4718     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4719
4720     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4721     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4722
4723     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4724     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4725
4726     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4727     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4728     hr = IDirect3DDevice9_BeginScene(device);
4729     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4730     if(SUCCEEDED(hr))
4731     {
4732         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4733         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4734
4735         hr = IDirect3DDevice9_EndScene(device);
4736         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4737     }
4738
4739     color = getPixelColor(device, 638, 240);
4740     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4741
4742     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4743     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4744
4745     /* Cleanup */
4746     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4747     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4748     IDirect3DPixelShader9_Release(shader);
4749
4750     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4751     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4752     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4753     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4754 }
4755
4756 static void texkill_test(IDirect3DDevice9 *device)
4757 {
4758     IDirect3DPixelShader9 *shader;
4759     HRESULT hr;
4760     DWORD color;
4761
4762     const float vertex[] = {
4763     /*                          bottom  top    right    left */
4764         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
4765          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
4766         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
4767          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
4768     };
4769
4770     DWORD shader_code_11[] = {
4771     0xffff0101,                                                             /* ps_1_1                     */
4772     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4773     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
4774     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
4775     0x0000ffff                                                              /* end                        */
4776     };
4777     DWORD shader_code_20[] = {
4778     0xffff0200,                                                             /* ps_2_0                     */
4779     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
4780     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4781     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
4782     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
4783     0x0000ffff                                                              /* end                        */
4784     };
4785
4786     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4787     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4788     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4789     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4790
4791     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4792     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4793     hr = IDirect3DDevice9_BeginScene(device);
4794     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4795     if(SUCCEEDED(hr))
4796     {
4797         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4798         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4799         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4800         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4801         hr = IDirect3DDevice9_EndScene(device);
4802         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4803     }
4804     color = getPixelColor(device, 63, 46);
4805     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4806     color = getPixelColor(device, 66, 46);
4807     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4808     color = getPixelColor(device, 63, 49);
4809     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4810     color = getPixelColor(device, 66, 49);
4811     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4812
4813     color = getPixelColor(device, 578, 46);
4814     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4815     color = getPixelColor(device, 575, 46);
4816     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4817     color = getPixelColor(device, 578, 49);
4818     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4819     color = getPixelColor(device, 575, 49);
4820     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4821
4822     color = getPixelColor(device, 63, 430);
4823     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4824     color = getPixelColor(device, 63, 433);
4825     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4826     color = getPixelColor(device, 66, 433);
4827     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4828     color = getPixelColor(device, 66, 430);
4829     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4830
4831     color = getPixelColor(device, 578, 430);
4832     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4833     color = getPixelColor(device, 578, 433);
4834     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4835     color = getPixelColor(device, 575, 433);
4836     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4837     color = getPixelColor(device, 575, 430);
4838     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4839
4840     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4841     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4842
4843     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4844     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4845     IDirect3DPixelShader9_Release(shader);
4846
4847     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4848     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4849     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4850     if(FAILED(hr)) {
4851         skip("Failed to create 2.0 test shader, most likely not supported\n");
4852         return;
4853     }
4854
4855     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4856     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4857     hr = IDirect3DDevice9_BeginScene(device);
4858     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4859     if(SUCCEEDED(hr))
4860     {
4861         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4862         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4863         hr = IDirect3DDevice9_EndScene(device);
4864         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4865     }
4866
4867     color = getPixelColor(device, 63, 46);
4868     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4869     color = getPixelColor(device, 66, 46);
4870     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4871     color = getPixelColor(device, 63, 49);
4872     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4873     color = getPixelColor(device, 66, 49);
4874     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4875
4876     color = getPixelColor(device, 578, 46);
4877     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4878     color = getPixelColor(device, 575, 46);
4879     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4880     color = getPixelColor(device, 578, 49);
4881     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4882     color = getPixelColor(device, 575, 49);
4883     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4884
4885     color = getPixelColor(device, 63, 430);
4886     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4887     color = getPixelColor(device, 63, 433);
4888     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4889     color = getPixelColor(device, 66, 433);
4890     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4891     color = getPixelColor(device, 66, 430);
4892     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4893
4894     color = getPixelColor(device, 578, 430);
4895     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4896     color = getPixelColor(device, 578, 433);
4897     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4898     color = getPixelColor(device, 575, 433);
4899     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4900     color = getPixelColor(device, 575, 430);
4901     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4902
4903     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4904     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4905
4906     /* Cleanup */
4907     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4908     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4909     IDirect3DPixelShader9_Release(shader);
4910 }
4911
4912 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4913 {
4914     IDirect3D9 *d3d9;
4915     HRESULT hr;
4916     IDirect3DTexture9 *texture;
4917     IDirect3DPixelShader9 *shader;
4918     IDirect3DPixelShader9 *shader2;
4919     D3DLOCKED_RECT lr;
4920     DWORD color;
4921     DWORD shader_code[] = {
4922         0xffff0101,                             /* ps_1_1       */
4923         0x00000042, 0xb00f0000,                 /* tex t0       */
4924         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
4925         0x0000ffff                              /* end          */
4926     };
4927     DWORD shader_code2[] = {
4928         0xffff0101,                             /* ps_1_1       */
4929         0x00000042, 0xb00f0000,                 /* tex t0       */
4930         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
4931         0x0000ffff                              /* end          */
4932     };
4933
4934     float quad[] = {
4935        -1.0,   -1.0,   0.1,     0.5,    0.5,
4936         1.0,   -1.0,   0.1,     0.5,    0.5,
4937        -1.0,    1.0,   0.1,     0.5,    0.5,
4938         1.0,    1.0,   0.1,     0.5,    0.5,
4939     };
4940
4941     memset(&lr, 0, sizeof(lr));
4942     IDirect3DDevice9_GetDirect3D(device, &d3d9);
4943     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4944                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4945     IDirect3D9_Release(d3d9);
4946     if(FAILED(hr)) {
4947         skip("No D3DFMT_X8L8V8U8 support\n");
4948         return;
4949     };
4950
4951     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4952     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4953
4954     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4955     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4956     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4957     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4958     *((DWORD *) lr.pBits) = 0x11ca3141;
4959     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4960     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4961
4962     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4963     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4964     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4965     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4966
4967     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4968     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4969     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4970     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4971     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4972     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4973
4974     hr = IDirect3DDevice9_BeginScene(device);
4975     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4976     if(SUCCEEDED(hr))
4977     {
4978         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4979         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4980
4981         hr = IDirect3DDevice9_EndScene(device);
4982         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4983     }
4984     color = getPixelColor(device, 578, 430);
4985     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4986        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4987     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4988     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4989
4990     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4991     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4992     hr = IDirect3DDevice9_BeginScene(device);
4993     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4994     if(SUCCEEDED(hr))
4995     {
4996         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4997         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4998
4999         hr = IDirect3DDevice9_EndScene(device);
5000         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5001     }
5002     color = getPixelColor(device, 578, 430);
5003     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
5004     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5005     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5006
5007     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5008     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5009     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5010     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
5011     IDirect3DPixelShader9_Release(shader);
5012     IDirect3DPixelShader9_Release(shader2);
5013     IDirect3DTexture9_Release(texture);
5014 }
5015
5016 static void autogen_mipmap_test(IDirect3DDevice9 *device)
5017 {
5018     HRESULT hr;
5019     IDirect3D9 *d3d;
5020     IDirect3DTexture9 *texture = NULL;
5021     IDirect3DSurface9 *surface;
5022     DWORD color;
5023     const RECT r1 = {256, 256, 512, 512};
5024     const RECT r2 = {512, 256, 768, 512};
5025     const RECT r3 = {256, 512, 512, 768};
5026     const RECT r4 = {512, 512, 768, 768};
5027     unsigned int x, y;
5028     D3DLOCKED_RECT lr;
5029     memset(&lr, 0, sizeof(lr));
5030
5031     IDirect3DDevice9_GetDirect3D(device, &d3d);
5032     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5033        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
5034         skip("No autogenmipmap support\n");
5035         IDirect3D9_Release(d3d);
5036         return;
5037     }
5038     IDirect3D9_Release(d3d);
5039
5040     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5041     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5042
5043     /* Make the mipmap big, so that a smaller mipmap is used
5044      */
5045     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
5046                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
5047     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5048
5049     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5050     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
5051     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5052     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
5053     for(y = 0; y < 1024; y++) {
5054         for(x = 0; x < 1024; x++) {
5055             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
5056             POINT pt;
5057
5058             pt.x = x;
5059             pt.y = y;
5060             if(PtInRect(&r1, pt)) {
5061                 *dst = 0xffff0000;
5062             } else if(PtInRect(&r2, pt)) {
5063                 *dst = 0xff00ff00;
5064             } else if(PtInRect(&r3, pt)) {
5065                 *dst = 0xff0000ff;
5066             } else if(PtInRect(&r4, pt)) {
5067                 *dst = 0xff000000;
5068             } else {
5069                 *dst = 0xffffffff;
5070             }
5071         }
5072     }
5073     hr = IDirect3DSurface9_UnlockRect(surface);
5074     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
5075     IDirect3DSurface9_Release(surface);
5076
5077     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5078     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5079     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
5080     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
5081
5082     hr = IDirect3DDevice9_BeginScene(device);
5083     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5084     if(SUCCEEDED(hr)) {
5085         const float quad[] =  {
5086            -0.5,   -0.5,    0.1,    0.0,    0.0,
5087            -0.5,    0.5,    0.1,    0.0,    1.0,
5088             0.5,   -0.5,    0.1,    1.0,    0.0,
5089             0.5,    0.5,    0.1,    1.0,    1.0
5090         };
5091
5092         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5093         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5094         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5095         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5096         hr = IDirect3DDevice9_EndScene(device);
5097         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5098     }
5099     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5100     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5101     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
5102     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
5103     IDirect3DTexture9_Release(texture);
5104
5105     color = getPixelColor(device, 200, 200);
5106     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
5107     color = getPixelColor(device, 280, 200);
5108     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
5109     color = getPixelColor(device, 360, 200);
5110     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
5111     color = getPixelColor(device, 440, 200);
5112     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5113     color = getPixelColor(device, 200, 270);
5114     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
5115     color = getPixelColor(device, 280, 270);
5116     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
5117     color = getPixelColor(device, 360, 270);
5118     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
5119     color = getPixelColor(device, 440, 270);
5120     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5121     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5122     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5123 }
5124
5125 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
5126 {
5127     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
5128     IDirect3DVertexDeclaration9 *decl;
5129     HRESULT hr;
5130     DWORD color;
5131     DWORD shader_code_11[] =  {
5132         0xfffe0101,                                         /* vs_1_1           */
5133         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
5134         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5135         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
5136         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
5137         0x0000ffff                                          /* end              */
5138     };
5139     DWORD shader_code_11_2[] =  {
5140         0xfffe0101,                                         /* vs_1_1           */
5141         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
5142         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
5143         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
5144         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5145         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
5146         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
5147         0x0000ffff                                          /* end              */
5148     };
5149     DWORD shader_code_20[] =  {
5150         0xfffe0200,                                         /* vs_2_0           */
5151         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
5152         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5153         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
5154         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
5155         0x0000ffff                                          /* end              */
5156     };
5157     DWORD shader_code_20_2[] =  {
5158         0xfffe0200,                                         /* vs_2_0           */
5159         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
5160         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
5161         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
5162         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5163         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
5164         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
5165         0x0000ffff                                          /* end              */
5166     };
5167     static const D3DVERTEXELEMENT9 decl_elements[] = {
5168         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5169         D3DDECL_END()
5170     };
5171     float quad1[] = {
5172         -1.0,   -1.0,   0.1,
5173          0.0,   -1.0,   0.1,
5174         -1.0,    0.0,   0.1,
5175          0.0,    0.0,   0.1
5176     };
5177     float quad2[] = {
5178          0.0,   -1.0,   0.1,
5179          1.0,   -1.0,   0.1,
5180          0.0,    0.0,   0.1,
5181          1.0,    0.0,   0.1
5182     };
5183     float quad3[] = {
5184          0.0,    0.0,   0.1,
5185          1.0,    0.0,   0.1,
5186          0.0,    1.0,   0.1,
5187          1.0,    1.0,   0.1
5188     };
5189     float quad4[] = {
5190         -1.0,    0.0,   0.1,
5191          0.0,    0.0,   0.1,
5192         -1.0,    1.0,   0.1,
5193          0.0,    1.0,   0.1
5194     };
5195     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
5196     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
5197
5198     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5199     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5200
5201     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
5202     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5203     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
5204     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5205     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
5206     if(FAILED(hr)) shader_20 = NULL;
5207     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
5208     if(FAILED(hr)) shader_20_2 = NULL;
5209     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5210     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5211
5212     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
5213     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5214     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
5215     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5216     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5217     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5218
5219     hr = IDirect3DDevice9_BeginScene(device);
5220     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5221     if(SUCCEEDED(hr))
5222     {
5223         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
5224         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5225         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5226         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5227
5228         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
5229         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5230         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5231         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5232
5233         if(shader_20) {
5234             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
5235             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5236             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5237             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5238         }
5239
5240         if(shader_20_2) {
5241             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
5242             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5243             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
5244             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5245         }
5246
5247         hr = IDirect3DDevice9_EndScene(device);
5248         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5249     }
5250
5251     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5252     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5253     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
5254     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5255
5256     color = getPixelColor(device, 160, 360);
5257     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5258        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
5259     color = getPixelColor(device, 480, 360);
5260     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5261        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
5262     if(shader_20) {
5263         color = getPixelColor(device, 480, 120);
5264         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5265            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
5266     }
5267     if(shader_20_2) {
5268         color = getPixelColor(device, 160, 120);
5269         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5270            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5271     }
5272     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5273     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5274
5275     IDirect3DVertexDeclaration9_Release(decl);
5276     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
5277     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
5278     IDirect3DVertexShader9_Release(shader_11_2);
5279     IDirect3DVertexShader9_Release(shader_11);
5280 }
5281
5282 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
5283 {
5284     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
5285     HRESULT hr;
5286     DWORD color;
5287     DWORD shader_code_11[] =  {
5288         0xffff0101,                                         /* ps_1_1           */
5289         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5290         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5291         0x0000ffff                                          /* end              */
5292     };
5293     DWORD shader_code_12[] =  {
5294         0xffff0102,                                         /* ps_1_2           */
5295         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5296         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5297         0x0000ffff                                          /* end              */
5298     };
5299     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
5300      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
5301      * During development of this test, 1.3 shaders were verified too
5302      */
5303     DWORD shader_code_14[] =  {
5304         0xffff0104,                                         /* ps_1_4           */
5305         /* Try to make one constant local. It gets clamped too, although the binary contains
5306          * the bigger numbers
5307          */
5308         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
5309         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5310         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5311         0x0000ffff                                          /* end              */
5312     };
5313     DWORD shader_code_20[] =  {
5314         0xffff0200,                                         /* ps_2_0           */
5315         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5316         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5317         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
5318         0x0000ffff                                          /* end              */
5319     };
5320     float quad1[] = {
5321         -1.0,   -1.0,   0.1,
5322          0.0,   -1.0,   0.1,
5323         -1.0,    0.0,   0.1,
5324          0.0,    0.0,   0.1
5325     };
5326     float quad2[] = {
5327          0.0,   -1.0,   0.1,
5328          1.0,   -1.0,   0.1,
5329          0.0,    0.0,   0.1,
5330          1.0,    0.0,   0.1
5331     };
5332     float quad3[] = {
5333          0.0,    0.0,   0.1,
5334          1.0,    0.0,   0.1,
5335          0.0,    1.0,   0.1,
5336          1.0,    1.0,   0.1
5337     };
5338     float quad4[] = {
5339         -1.0,    0.0,   0.1,
5340          0.0,    0.0,   0.1,
5341         -1.0,    1.0,   0.1,
5342          0.0,    1.0,   0.1
5343     };
5344     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
5345     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
5346
5347     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5348     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5349
5350     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5351     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5352     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5353     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5354     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5355     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5356     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
5357     if(FAILED(hr)) shader_20 = NULL;
5358
5359     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5360     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5361     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5362     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5363     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5364     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5365
5366     hr = IDirect3DDevice9_BeginScene(device);
5367     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5368     if(SUCCEEDED(hr))
5369     {
5370         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5371         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5372         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5373         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5374
5375         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5376         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5377         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5378         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5379
5380         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5381         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5382         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5383         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5384
5385         if(shader_20) {
5386             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
5387             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5388             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
5389             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5390         }
5391
5392         hr = IDirect3DDevice9_EndScene(device);
5393         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5394     }
5395     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5396     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5397
5398     color = getPixelColor(device, 160, 360);
5399     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5400        "quad 1 has color %08x, expected 0x00808000\n", color);
5401     color = getPixelColor(device, 480, 360);
5402     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5403        "quad 2 has color %08x, expected 0x00808000\n", color);
5404     color = getPixelColor(device, 480, 120);
5405     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5406        "quad 3 has color %08x, expected 0x00808000\n", color);
5407     if(shader_20) {
5408         color = getPixelColor(device, 160, 120);
5409         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5410            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5411     }
5412     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5413     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5414
5415     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
5416     IDirect3DPixelShader9_Release(shader_14);
5417     IDirect3DPixelShader9_Release(shader_12);
5418     IDirect3DPixelShader9_Release(shader_11);
5419 }
5420
5421 static void dp2add_ps_test(IDirect3DDevice9 *device)
5422 {
5423     IDirect3DPixelShader9 *shader_dp2add = NULL;
5424     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
5425     HRESULT hr;
5426     DWORD color;
5427
5428     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
5429      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
5430      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
5431      * r0 first.
5432      * The result here for the r,g,b components should be roughly 0.5:
5433      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
5434     static const DWORD shader_code_dp2add[] =  {
5435         0xffff0200,                                                             /* ps_2_0                       */
5436         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
5437
5438         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5439         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
5440
5441         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
5442         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5443         0x0000ffff                                                              /* end                          */
5444     };
5445
5446     /* Test the _sat modifier, too.  Result here should be:
5447      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
5448      *      _SAT: ==> 1.0
5449      *   ADD: (1.0 + -0.5) = 0.5
5450      */
5451     static const DWORD shader_code_dp2add_sat[] =  {
5452         0xffff0200,                                                             /* ps_2_0                           */
5453         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
5454
5455         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
5456         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
5457         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
5458
5459         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
5460         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
5461         0x0000ffff                                                              /* end                              */
5462     };
5463
5464     const float quad[] = {
5465         -1.0,   -1.0,   0.1,
5466          1.0,   -1.0,   0.1,
5467         -1.0,    1.0,   0.1,
5468          1.0,    1.0,   0.1
5469     };
5470
5471
5472     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
5473     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5474
5475     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
5476     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5477
5478     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
5479     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5480
5481     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5482     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5483
5484     if (shader_dp2add) {
5485
5486         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5487         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5488
5489         hr = IDirect3DDevice9_BeginScene(device);
5490         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5491         if(SUCCEEDED(hr))
5492         {
5493             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5494             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5495
5496             hr = IDirect3DDevice9_EndScene(device);
5497             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5498         }
5499
5500         color = getPixelColor(device, 360, 240);
5501         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5502                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5503
5504         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5505         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5506
5507         IDirect3DPixelShader9_Release(shader_dp2add);
5508     } else {
5509         skip("dp2add shader creation failed\n");
5510     }
5511
5512     if (shader_dp2add_sat) {
5513
5514         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5515         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5516
5517         hr = IDirect3DDevice9_BeginScene(device);
5518         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5519         if(SUCCEEDED(hr))
5520         {
5521             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5522             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5523
5524             hr = IDirect3DDevice9_EndScene(device);
5525             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5526         }
5527
5528         color = getPixelColor(device, 360, 240);
5529         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5530                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5531
5532         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5533         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5534
5535         IDirect3DPixelShader9_Release(shader_dp2add_sat);
5536     } else {
5537         skip("dp2add shader creation failed\n");
5538     }
5539
5540     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5541     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5542 }
5543
5544 static void cnd_test(IDirect3DDevice9 *device)
5545 {
5546     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
5547     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
5548     HRESULT hr;
5549     DWORD color;
5550     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
5551      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
5552      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
5553      */
5554     DWORD shader_code_11[] =  {
5555         0xffff0101,                                                                 /* ps_1_1               */
5556         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5557         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5558         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
5559         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5560         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5561         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5562         0x0000ffff                                                                  /* end                  */
5563     };
5564     DWORD shader_code_12[] =  {
5565         0xffff0102,                                                                 /* ps_1_2               */
5566         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5567         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5568         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5569         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5570         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5571         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5572         0x0000ffff                                                                  /* end                  */
5573     };
5574     DWORD shader_code_13[] =  {
5575         0xffff0103,                                                                 /* ps_1_3               */
5576         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5577         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5578         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5579         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
5580         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5581         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5582         0x0000ffff                                                                  /* end                  */
5583     };
5584     DWORD shader_code_14[] =  {
5585         0xffff0104,                                                                 /* ps_1_3               */
5586         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
5587         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
5588         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
5589         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
5590         0x0000ffff                                                                  /* end                  */
5591     };
5592
5593     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
5594      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
5595      * set by the compiler, it was added manually after compilation. Note that the COISSUE
5596      * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
5597      * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
5598      * well enough.
5599      *
5600      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
5601      * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
5602      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
5603      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
5604      */
5605     DWORD shader_code_11_coissue[] =  {
5606         0xffff0101,                                                             /* ps_1_1                   */
5607         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5608         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5609         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5610         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5611         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5612         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5613         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5614         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5615         /* 0x40000000 = D3DSI_COISSUE */
5616         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5617         0x0000ffff                                                              /* end                      */
5618     };
5619     DWORD shader_code_12_coissue[] =  {
5620         0xffff0102,                                                             /* ps_1_2                   */
5621         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5622         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5623         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5624         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5625         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5626         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5627         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5628         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5629         /* 0x40000000 = D3DSI_COISSUE */
5630         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5631         0x0000ffff                                                              /* end                      */
5632     };
5633     DWORD shader_code_13_coissue[] =  {
5634         0xffff0103,                                                             /* ps_1_3                   */
5635         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5636         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5637         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5638         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5639         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5640         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5641         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5642         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5643         /* 0x40000000 = D3DSI_COISSUE */
5644         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5645         0x0000ffff                                                              /* end                      */
5646     };
5647     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
5648      * compare against 0.5
5649      */
5650     DWORD shader_code_14_coissue[] =  {
5651         0xffff0104,                                                             /* ps_1_4                   */
5652         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
5653         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
5654         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
5655         /* 0x40000000 = D3DSI_COISSUE */
5656         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
5657         0x0000ffff                                                              /* end                      */
5658     };
5659     float quad1[] = {
5660         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5661          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5662         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5663          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
5664     };
5665     float quad2[] = {
5666          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5667          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5668          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5669          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
5670     };
5671     float quad3[] = {
5672          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5673          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5674          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5675          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
5676     };
5677     float quad4[] = {
5678         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5679          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5680         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5681          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
5682     };
5683     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
5684     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
5685     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
5686     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
5687
5688     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5689     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5690
5691     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5692     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5693     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5694     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5695     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
5696     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5697     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5698     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5699     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
5700     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5701     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5702     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5703     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5704     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5705     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5706     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5707
5708     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5709     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5710     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5711     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5712     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5713     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5714
5715     hr = IDirect3DDevice9_BeginScene(device);
5716     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5717     if(SUCCEEDED(hr))
5718     {
5719         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5720         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5721         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5722         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5723
5724         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5725         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5726         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5727         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5728
5729         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5730         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5731         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5732         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5733
5734         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5735         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5736         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5737         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5738
5739         hr = IDirect3DDevice9_EndScene(device);
5740         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5741     }
5742
5743     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5744     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5745
5746     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5747     color = getPixelColor(device, 158, 118);
5748     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5749     color = getPixelColor(device, 162, 118);
5750     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5751     color = getPixelColor(device, 158, 122);
5752     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5753     color = getPixelColor(device, 162, 122);
5754     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5755
5756     /* 1.1 shader. All 3 components get set, based on the .w comparison */
5757     color = getPixelColor(device, 158, 358);
5758     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5759     color = getPixelColor(device, 162, 358);
5760     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5761         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5762     color = getPixelColor(device, 158, 362);
5763     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5764     color = getPixelColor(device, 162, 362);
5765     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5766         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5767
5768     /* 1.2 shader */
5769     color = getPixelColor(device, 478, 358);
5770     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5771     color = getPixelColor(device, 482, 358);
5772     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5773         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5774     color = getPixelColor(device, 478, 362);
5775     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5776     color = getPixelColor(device, 482, 362);
5777     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5778         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5779
5780     /* 1.3 shader */
5781     color = getPixelColor(device, 478, 118);
5782     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5783     color = getPixelColor(device, 482, 118);
5784     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5785         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5786     color = getPixelColor(device, 478, 122);
5787     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5788     color = getPixelColor(device, 482, 122);
5789     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5790         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5791
5792     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5793     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5794
5795     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5796     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5797     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5798     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5799     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5800     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5801
5802     hr = IDirect3DDevice9_BeginScene(device);
5803     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5804     if(SUCCEEDED(hr))
5805     {
5806         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5807         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5808         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5809         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5810
5811         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5812         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5813         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5814         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5815
5816         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5817         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5818         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5819         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5820
5821         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5822         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5823         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5824         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5825
5826         hr = IDirect3DDevice9_EndScene(device);
5827         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5828     }
5829
5830     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5831     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5832
5833     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5834      * that we swapped the values in c1 and c2 to make the other tests return some color
5835      */
5836     color = getPixelColor(device, 158, 118);
5837     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5838     color = getPixelColor(device, 162, 118);
5839     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5840     color = getPixelColor(device, 158, 122);
5841     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5842     color = getPixelColor(device, 162, 122);
5843     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5844
5845     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
5846      * (The Win7 nvidia driver always selects c2)
5847      */
5848     color = getPixelColor(device, 158, 358);
5849     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5850         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5851     color = getPixelColor(device, 162, 358);
5852     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5853         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5854     color = getPixelColor(device, 158, 362);
5855     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5856         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5857     color = getPixelColor(device, 162, 362);
5858     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5859         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5860
5861     /* 1.2 shader */
5862     color = getPixelColor(device, 478, 358);
5863     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5864         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5865     color = getPixelColor(device, 482, 358);
5866     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5867         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5868     color = getPixelColor(device, 478, 362);
5869     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5870         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5871     color = getPixelColor(device, 482, 362);
5872     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5873         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5874
5875     /* 1.3 shader */
5876     color = getPixelColor(device, 478, 118);
5877     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5878         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5879     color = getPixelColor(device, 482, 118);
5880     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5881         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5882     color = getPixelColor(device, 478, 122);
5883     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5884         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5885     color = getPixelColor(device, 482, 122);
5886     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5887         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5888
5889     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5890     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5891
5892     IDirect3DPixelShader9_Release(shader_14_coissue);
5893     IDirect3DPixelShader9_Release(shader_13_coissue);
5894     IDirect3DPixelShader9_Release(shader_12_coissue);
5895     IDirect3DPixelShader9_Release(shader_11_coissue);
5896     IDirect3DPixelShader9_Release(shader_14);
5897     IDirect3DPixelShader9_Release(shader_13);
5898     IDirect3DPixelShader9_Release(shader_12);
5899     IDirect3DPixelShader9_Release(shader_11);
5900 }
5901
5902 static void nested_loop_test(IDirect3DDevice9 *device) {
5903     const DWORD shader_code[] = {
5904         0xffff0300,                                                             /* ps_3_0               */
5905         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
5906         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5907         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
5908         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
5909         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5910         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5911         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
5912         0x0000001d,                                                             /* endloop              */
5913         0x0000001d,                                                             /* endloop              */
5914         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
5915         0x0000ffff                                                              /* end                  */
5916     };
5917     const DWORD vshader_code[] = {
5918         0xfffe0300,                                                             /* vs_3_0               */
5919         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
5920         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
5921         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
5922         0x0000ffff                                                              /* end                  */
5923     };
5924     IDirect3DPixelShader9 *shader;
5925     IDirect3DVertexShader9 *vshader;
5926     HRESULT hr;
5927     DWORD color;
5928     const float quad[] = {
5929         -1.0,   -1.0,   0.1,
5930          1.0,   -1.0,   0.1,
5931         -1.0,    1.0,   0.1,
5932          1.0,    1.0,   0.1
5933     };
5934
5935     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5936     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5937     hr = IDirect3DDevice9_SetPixelShader(device, shader);
5938     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5939     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
5940     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
5941     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
5942     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5943     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5944     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5945     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5946     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5947
5948     hr = IDirect3DDevice9_BeginScene(device);
5949     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5950     if(SUCCEEDED(hr))
5951     {
5952         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5953         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5954         hr = IDirect3DDevice9_EndScene(device);
5955         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5956     }
5957
5958     color = getPixelColor(device, 360, 240);
5959     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5960        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5961
5962     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5963     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5964
5965     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5966     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5967     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5968     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5969     IDirect3DPixelShader9_Release(shader);
5970     IDirect3DVertexShader9_Release(vshader);
5971 }
5972
5973 struct varying_test_struct
5974 {
5975     const DWORD             *shader_code;
5976     IDirect3DPixelShader9   *shader;
5977     DWORD                   color, color_rhw;
5978     const char              *name;
5979     BOOL                    todo, todo_rhw;
5980 };
5981
5982 struct hugeVertex
5983 {
5984     float pos_x,        pos_y,      pos_z,      rhw;
5985     float weight_1,     weight_2,   weight_3,   weight_4;
5986     float index_1,      index_2,    index_3,    index_4;
5987     float normal_1,     normal_2,   normal_3,   normal_4;
5988     float fog_1,        fog_2,      fog_3,      fog_4;
5989     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
5990     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
5991     float binormal_1,   binormal_2, binormal_3, binormal_4;
5992     float depth_1,      depth_2,    depth_3,    depth_4;
5993     DWORD diffuse, specular;
5994 };
5995
5996 static void pretransformed_varying_test(IDirect3DDevice9 *device) {
5997     /* dcl_position: fails to compile */
5998     const DWORD blendweight_code[] = {
5999         0xffff0300,                             /* ps_3_0                   */
6000         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
6001         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6002         0x0000ffff                              /* end                      */
6003     };
6004     const DWORD blendindices_code[] = {
6005         0xffff0300,                             /* ps_3_0                   */
6006         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
6007         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6008         0x0000ffff                              /* end                      */
6009     };
6010     const DWORD normal_code[] = {
6011         0xffff0300,                             /* ps_3_0                   */
6012         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
6013         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6014         0x0000ffff                              /* end                      */
6015     };
6016     /* psize: fails? */
6017     const DWORD texcoord0_code[] = {
6018         0xffff0300,                             /* ps_3_0                   */
6019         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
6020         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6021         0x0000ffff                              /* end                      */
6022     };
6023     const DWORD tangent_code[] = {
6024         0xffff0300,                             /* ps_3_0                   */
6025         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
6026         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6027         0x0000ffff                              /* end                      */
6028     };
6029     const DWORD binormal_code[] = {
6030         0xffff0300,                             /* ps_3_0                   */
6031         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
6032         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6033         0x0000ffff                              /* end                      */
6034     };
6035     /* tessfactor: fails */
6036     /* positiont: fails */
6037     const DWORD color_code[] = {
6038         0xffff0300,                             /* ps_3_0                   */
6039         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
6040         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6041         0x0000ffff                              /* end                      */
6042     };
6043     const DWORD fog_code[] = {
6044         0xffff0300,                             /* ps_3_0                   */
6045         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
6046         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6047         0x0000ffff                              /* end                      */
6048     };
6049     const DWORD depth_code[] = {
6050         0xffff0300,                             /* ps_3_0                   */
6051         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
6052         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6053         0x0000ffff                              /* end                      */
6054     };
6055     const DWORD specular_code[] = {
6056         0xffff0300,                             /* ps_3_0                   */
6057         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
6058         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6059         0x0000ffff                              /* end                      */
6060     };
6061     /* sample: fails */
6062
6063     struct varying_test_struct tests[] = {
6064        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
6065        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
6066        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
6067        /* Why does dx not forward the texcoord? */
6068        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
6069        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
6070        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
6071        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
6072        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
6073        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
6074        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
6075     };
6076     /* Declare a monster vertex type :-) */
6077     static const D3DVERTEXELEMENT9 decl_elements[] = {
6078         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
6079         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
6080         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
6081         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
6082         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
6083         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6084         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
6085         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
6086         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
6087         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6088         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
6089         D3DDECL_END()
6090     };
6091     struct hugeVertex data[4] = {
6092         {
6093             -1.0,   -1.0,   0.1,    1.0,
6094              0.1,    0.1,   0.1,    0.1,
6095              0.2,    0.2,   0.2,    0.2,
6096              0.3,    0.3,   0.3,    0.3,
6097              0.4,    0.4,   0.4,    0.4,
6098              0.50,   0.55,  0.55,   0.55,
6099              0.6,    0.6,   0.6,    0.7,
6100              0.7,    0.7,   0.7,    0.6,
6101              0.8,    0.8,   0.8,    0.8,
6102              0xe6e6e6e6, /* 0.9 * 256 */
6103              0x224488ff  /* Nothing special */
6104         },
6105         {
6106              1.0,   -1.0,   0.1,    1.0,
6107              0.1,    0.1,   0.1,    0.1,
6108              0.2,    0.2,   0.2,    0.2,
6109              0.3,    0.3,   0.3,    0.3,
6110              0.4,    0.4,   0.4,    0.4,
6111              0.50,   0.55,  0.55,   0.55,
6112              0.6,    0.6,   0.6,    0.7,
6113              0.7,    0.7,   0.7,    0.6,
6114              0.8,    0.8,   0.8,    0.8,
6115              0xe6e6e6e6, /* 0.9 * 256 */
6116              0x224488ff /* Nothing special */
6117         },
6118         {
6119             -1.0,    1.0,   0.1,    1.0,
6120              0.1,    0.1,   0.1,    0.1,
6121              0.2,    0.2,   0.2,    0.2,
6122              0.3,    0.3,   0.3,    0.3,
6123              0.4,    0.4,   0.4,    0.4,
6124              0.50,   0.55,  0.55,   0.55,
6125              0.6,    0.6,   0.6,    0.7,
6126              0.7,    0.7,   0.7,    0.6,
6127              0.8,    0.8,   0.8,    0.8,
6128              0xe6e6e6e6, /* 0.9 * 256 */
6129              0x224488ff /* Nothing special */
6130         },
6131         {
6132              1.0,    1.0,   0.1,    1.0,
6133              0.1,    0.1,   0.1,    0.1,
6134              0.2,    0.2,   0.2,    0.2,
6135              0.3,    0.3,   0.3,    0.3,
6136              0.4,    0.4,   0.4,    0.4,
6137              0.50,   0.55,  0.55,   0.55,
6138              0.6,    0.6,   0.6,    0.7,
6139              0.7,    0.7,   0.7,    0.6,
6140              0.8,    0.8,   0.8,    0.8,
6141              0xe6e6e6e6, /* 0.9 * 256 */
6142              0x224488ff /* Nothing special */
6143         },
6144     };
6145     struct hugeVertex data2[4];
6146     IDirect3DVertexDeclaration9 *decl;
6147     HRESULT hr;
6148     unsigned int i;
6149     DWORD color, r, g, b, r_e, g_e, b_e;
6150
6151     memcpy(data2, data, sizeof(data2));
6152     data2[0].pos_x = 0;     data2[0].pos_y = 0;
6153     data2[1].pos_x = 640;   data2[1].pos_y = 0;
6154     data2[2].pos_x = 0;     data2[2].pos_y = 480;
6155     data2[3].pos_x = 640;   data2[3].pos_y = 480;
6156
6157     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
6158     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6159     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6160     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6161
6162     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6163     {
6164         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
6165         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
6166            tests[i].name, hr);
6167     }
6168
6169     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6170     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6171     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6172     {
6173         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6174         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6175
6176         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
6177         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6178
6179         hr = IDirect3DDevice9_BeginScene(device);
6180         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6181         if(SUCCEEDED(hr))
6182         {
6183             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
6184             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6185             hr = IDirect3DDevice9_EndScene(device);
6186             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6187         }
6188
6189         color = getPixelColor(device, 360, 240);
6190         r = color & 0x00ff0000 >> 16;
6191         g = color & 0x0000ff00 >>  8;
6192         b = color & 0x000000ff;
6193         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
6194         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
6195         b_e = tests[i].color_rhw & 0x000000ff;
6196
6197         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6198         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6199
6200         if(tests[i].todo_rhw) {
6201             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
6202              * pipeline
6203              */
6204             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
6205                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
6206                          tests[i].name, color, tests[i].color_rhw);
6207         } else {
6208             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
6209                "Test %s returned color 0x%08x, expected 0x%08x\n",
6210                tests[i].name, color, tests[i].color_rhw);
6211         }
6212     }
6213
6214     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6215     {
6216         IDirect3DPixelShader9_Release(tests[i].shader);
6217     }
6218
6219     IDirect3DVertexDeclaration9_Release(decl);
6220 }
6221
6222 static void test_compare_instructions(IDirect3DDevice9 *device)
6223 {
6224     DWORD shader_sge_vec_code[] = {
6225         0xfffe0101,                                         /* vs_1_1                   */
6226         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6227         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6228         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6229         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
6230         0x0000ffff                                          /* end                      */
6231     };
6232     DWORD shader_slt_vec_code[] = {
6233         0xfffe0101,                                         /* vs_1_1                   */
6234         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6235         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6236         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6237         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
6238         0x0000ffff                                          /* end                      */
6239     };
6240     DWORD shader_sge_scalar_code[] = {
6241         0xfffe0101,                                         /* vs_1_1                   */
6242         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6243         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6244         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6245         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
6246         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
6247         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
6248         0x0000ffff                                          /* end                      */
6249     };
6250     DWORD shader_slt_scalar_code[] = {
6251         0xfffe0101,                                         /* vs_1_1                   */
6252         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6253         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6254         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6255         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
6256         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
6257         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
6258         0x0000ffff                                          /* end                      */
6259     };
6260     IDirect3DVertexShader9 *shader_sge_vec;
6261     IDirect3DVertexShader9 *shader_slt_vec;
6262     IDirect3DVertexShader9 *shader_sge_scalar;
6263     IDirect3DVertexShader9 *shader_slt_scalar;
6264     HRESULT hr, color;
6265     float quad1[] =  {
6266         -1.0,   -1.0,   0.1,
6267          0.0,   -1.0,   0.1,
6268         -1.0,    0.0,   0.1,
6269          0.0,    0.0,   0.1
6270     };
6271     float quad2[] =  {
6272          0.0,   -1.0,   0.1,
6273          1.0,   -1.0,   0.1,
6274          0.0,    0.0,   0.1,
6275          1.0,    0.0,   0.1
6276     };
6277     float quad3[] =  {
6278         -1.0,    0.0,   0.1,
6279          0.0,    0.0,   0.1,
6280         -1.0,    1.0,   0.1,
6281          0.0,    1.0,   0.1
6282     };
6283     float quad4[] =  {
6284          0.0,    0.0,   0.1,
6285          1.0,    0.0,   0.1,
6286          0.0,    1.0,   0.1,
6287          1.0,    1.0,   0.1
6288     };
6289     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
6290     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
6291
6292     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6293     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6294
6295     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
6296     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6297     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
6298     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6299     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
6300     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6301     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
6302     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6303     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6304     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6305     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
6306     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6307     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6308     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
6309
6310     hr = IDirect3DDevice9_BeginScene(device);
6311     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6312     if(SUCCEEDED(hr))
6313     {
6314         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
6315         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6316         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6317         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6318
6319         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
6320         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6321         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
6322         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6323
6324         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
6325         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6326         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6327         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6328
6329         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6330         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6331
6332         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
6333         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6334         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6335         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6336
6337         hr = IDirect3DDevice9_EndScene(device);
6338         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6339     }
6340
6341     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6342     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6343
6344     color = getPixelColor(device, 160, 360);
6345     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
6346     color = getPixelColor(device, 480, 360);
6347     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
6348     color = getPixelColor(device, 160, 120);
6349     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
6350     color = getPixelColor(device, 480, 160);
6351     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
6352
6353     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6354     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6355
6356     IDirect3DVertexShader9_Release(shader_sge_vec);
6357     IDirect3DVertexShader9_Release(shader_slt_vec);
6358     IDirect3DVertexShader9_Release(shader_sge_scalar);
6359     IDirect3DVertexShader9_Release(shader_slt_scalar);
6360 }
6361
6362 static void test_vshader_input(IDirect3DDevice9 *device)
6363 {
6364     static const DWORD swapped_shader_code_3[] =
6365     {
6366         0xfffe0300,                                         /* vs_3_0               */
6367         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6368         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6369         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6370         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6371         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6372         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6373         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6374         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6375         0x0000ffff                                          /* end                  */
6376     };
6377     static const DWORD swapped_shader_code_1[] =
6378     {
6379         0xfffe0101,                                         /* vs_1_1               */
6380         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6381         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6382         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6383         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6384         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6385         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6386         0x0000ffff                                          /* end                  */
6387     };
6388     static const DWORD swapped_shader_code_2[] =
6389     {
6390         0xfffe0200,                                         /* vs_2_0               */
6391         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6392         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6393         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6394         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6395         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6396         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6397         0x0000ffff                                          /* end                  */
6398     };
6399     static const DWORD texcoord_color_shader_code_3[] =
6400     {
6401         0xfffe0300,                                         /* vs_3_0               */
6402         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6403         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6404         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6405         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6406         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6407         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
6408         0x0000ffff                                          /* end                  */
6409     };
6410     static const DWORD texcoord_color_shader_code_2[] =
6411     {
6412         0xfffe0200,                                         /* vs_2_0               */
6413         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6414         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6415         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6416         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6417         0x0000ffff                                          /* end                  */
6418     };
6419     static const DWORD texcoord_color_shader_code_1[] =
6420     {
6421         0xfffe0101,                                         /* vs_1_1               */
6422         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6423         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6424         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6425         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6426         0x0000ffff                                          /* end                  */
6427     };
6428     static const DWORD color_color_shader_code_3[] =
6429     {
6430         0xfffe0300,                                         /* vs_3_0               */
6431         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6432         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6433         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6434         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6435         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6436         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
6437         0x0000ffff                                          /* end                  */
6438     };
6439     static const DWORD color_color_shader_code_2[] =
6440     {
6441         0xfffe0200,                                         /* vs_2_0               */
6442         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6443         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6444         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6445         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1      */
6446         0x0000ffff                                          /* end                  */
6447     };
6448     static const DWORD color_color_shader_code_1[] =
6449     {
6450         0xfffe0101,                                         /* vs_1_1               */
6451         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6452         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6453         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6454         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1      */
6455         0x0000ffff                                          /* end                  */
6456     };
6457     static const DWORD ps3_code[] =
6458     {
6459         0xffff0300,                                         /* ps_3_0               */
6460         0x0200001f, 0x8000000a, 0x900f0000,                 /* dcl_color0 v0        */
6461         0x02000001, 0x800f0800, 0x90e40000,                 /* mov oC0, v0          */
6462         0x0000ffff                                          /* end                  */
6463     };
6464     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6465     IDirect3DPixelShader9 *ps;
6466     HRESULT hr;
6467     DWORD color;
6468     float quad1[] =  {
6469         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6470          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6471         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6472          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6473     };
6474     float quad2[] =  {
6475          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6476          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6477          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6478          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6479     };
6480     float quad3[] =  {
6481         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
6482          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
6483         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
6484          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6485     };
6486     float quad4[] =  {
6487          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6488          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6489          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6490          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6491     };
6492     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6493         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6494         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6495         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6496         D3DDECL_END()
6497     };
6498     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6499         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6500         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6501         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6502         D3DDECL_END()
6503     };
6504     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6505         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6506         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6507         D3DDECL_END()
6508     };
6509     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6510         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6511         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6512         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
6513         D3DDECL_END()
6514     };
6515     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6516         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6517         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6518         D3DDECL_END()
6519     };
6520     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6521         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6522         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6523         D3DDECL_END()
6524     };
6525     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6526         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6527         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6528         D3DDECL_END()
6529     };
6530     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6531         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6532         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6533         D3DDECL_END()
6534     };
6535     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6536     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6537     unsigned int i;
6538     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6539     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6540
6541     struct vertex quad1_color[] =  {
6542        {-1.0,   -1.0,   0.1,    0x00ff8040},
6543        { 0.0,   -1.0,   0.1,    0x00ff8040},
6544        {-1.0,    0.0,   0.1,    0x00ff8040},
6545        { 0.0,    0.0,   0.1,    0x00ff8040}
6546     };
6547     struct vertex quad2_color[] =  {
6548        { 0.0,   -1.0,   0.1,    0x00ff8040},
6549        { 1.0,   -1.0,   0.1,    0x00ff8040},
6550        { 0.0,    0.0,   0.1,    0x00ff8040},
6551        { 1.0,    0.0,   0.1,    0x00ff8040}
6552     };
6553     struct vertex quad3_color[] =  {
6554        {-1.0,    0.0,   0.1,    0x00ff8040},
6555        { 0.0,    0.0,   0.1,    0x00ff8040},
6556        {-1.0,    1.0,   0.1,    0x00ff8040},
6557        { 0.0,    1.0,   0.1,    0x00ff8040}
6558     };
6559     float quad4_color[] =  {
6560          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6561          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6562          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6563          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6564     };
6565
6566     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6567     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6568     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6569     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6570     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6571     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6572     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6573     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6574
6575     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6576     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6577     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6578     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6579     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6580     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6581     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6582     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6583
6584     hr = IDirect3DDevice9_CreatePixelShader(device, ps3_code, &ps);
6585     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6586
6587     for(i = 1; i <= 3; i++) {
6588         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6589         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6590         if(i == 3) {
6591             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6592             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6593             hr = IDirect3DDevice9_SetPixelShader(device, ps);
6594             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6595         } else if(i == 2){
6596             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6597             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6598         } else if(i == 1) {
6599             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6600             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6601         }
6602
6603         hr = IDirect3DDevice9_BeginScene(device);
6604         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6605         if(SUCCEEDED(hr))
6606         {
6607             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6608             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6609
6610             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6611             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6612             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6613             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6614
6615             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6616             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6617             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6618             if(i == 3 || i == 2) {
6619                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6620             } else if(i == 1) {
6621                 /* Succeeds or fails, depending on SW or HW vertex processing */
6622                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6623             }
6624
6625             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6626             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6627             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6628             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6629
6630             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6631             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6632             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6633             if(i == 3 || i == 2) {
6634                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6635             } else if(i == 1) {
6636                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6637             }
6638
6639             hr = IDirect3DDevice9_EndScene(device);
6640             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6641         }
6642
6643         if(i == 3 || i == 2) {
6644             color = getPixelColor(device, 160, 360);
6645             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6646                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6647
6648             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6649             color = getPixelColor(device, 480, 360);
6650             ok(color == 0x00FFFF00 || color ==0x00FF0000,
6651                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6652             color = getPixelColor(device, 160, 120);
6653             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6654             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6655                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6656
6657             color = getPixelColor(device, 480, 160);
6658             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6659         } else if(i == 1) {
6660             color = getPixelColor(device, 160, 360);
6661             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6662                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6663             color = getPixelColor(device, 480, 360);
6664             /* Accept the clear color as well in this case, since SW VP returns an error */
6665             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6666             color = getPixelColor(device, 160, 120);
6667             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6668                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6669             color = getPixelColor(device, 480, 160);
6670             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6671         }
6672
6673         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6674         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6675
6676         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6677         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6678
6679         /* Now find out if the whole streams are re-read, or just the last active value for the
6680          * vertices is used.
6681          */
6682         hr = IDirect3DDevice9_BeginScene(device);
6683         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6684         if(SUCCEEDED(hr))
6685         {
6686             float quad1_modified[] =  {
6687                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6688                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6689                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6690                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6691             };
6692             float quad2_modified[] =  {
6693                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6694                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6695                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6696                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6697             };
6698
6699             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6700             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6701
6702             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6703             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6704             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6705             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6706
6707             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6708             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6709             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6710             if(i == 3 || i == 2) {
6711                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6712             } else if(i == 1) {
6713                 /* Succeeds or fails, depending on SW or HW vertex processing */
6714                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6715             }
6716
6717             hr = IDirect3DDevice9_EndScene(device);
6718             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6719         }
6720
6721         color = getPixelColor(device, 480, 350);
6722         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6723          * as well.
6724          *
6725          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6726          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6727          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6728          * refrast's result.
6729          *
6730          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6731          */
6732         ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6733            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6734
6735         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6736         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6737
6738         IDirect3DDevice9_SetVertexShader(device, NULL);
6739         IDirect3DDevice9_SetPixelShader(device, NULL);
6740         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6741
6742         IDirect3DVertexShader9_Release(swapped_shader);
6743     }
6744
6745     for(i = 1; i <= 3; i++) {
6746         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6747         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6748         if(i == 3) {
6749             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6750             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6751             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6752             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6753             hr = IDirect3DDevice9_SetPixelShader(device, ps);
6754             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6755         } else if(i == 2){
6756             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6757             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6758             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6759             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6760         } else if(i == 1) {
6761             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6762             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6763             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6764             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6765         }
6766
6767         hr = IDirect3DDevice9_BeginScene(device);
6768         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6769         if(SUCCEEDED(hr))
6770         {
6771             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6772             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6773             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6774             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6775             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6776             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6777
6778             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6779             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6780
6781             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6782             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6783             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6784             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6785             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6786             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6787
6788             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6789             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6790             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6791             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6792             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6793             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6794
6795             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6796             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6797             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6798             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6799
6800             hr = IDirect3DDevice9_EndScene(device);
6801             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6802         }
6803         IDirect3DDevice9_SetVertexShader(device, NULL);
6804         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6805         IDirect3DDevice9_SetPixelShader(device, NULL);
6806
6807         color = getPixelColor(device, 160, 360);
6808         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6809            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6810         color = getPixelColor(device, 480, 360);
6811         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6812            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6813         color = getPixelColor(device, 160, 120);
6814         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6815            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6816         color = getPixelColor(device, 480, 160);
6817         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6818            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6819
6820         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6821         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6822
6823         IDirect3DVertexShader9_Release(texcoord_color_shader);
6824         IDirect3DVertexShader9_Release(color_color_shader);
6825     }
6826
6827     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6828     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6829     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6830     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6831
6832     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6833     IDirect3DVertexDeclaration9_Release(decl_color_color);
6834     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6835     IDirect3DVertexDeclaration9_Release(decl_color_float);
6836
6837     IDirect3DPixelShader9_Release(ps);
6838 }
6839
6840 static void srgbtexture_test(IDirect3DDevice9 *device)
6841 {
6842     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6843      * texture stage state to render a quad using that texture.  The resulting
6844      * color components should be 0x36 (~ 0.21), per this formula:
6845      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6846      * This is true where srgb_color > 0.04045.
6847      */
6848     IDirect3D9 *d3d = NULL;
6849     HRESULT hr;
6850     LPDIRECT3DTEXTURE9 texture = NULL;
6851     LPDIRECT3DSURFACE9 surface = NULL;
6852     D3DLOCKED_RECT lr;
6853     DWORD color;
6854     float quad[] = {
6855         -1.0,       1.0,       0.0,     0.0,    0.0,
6856          1.0,       1.0,       0.0,     1.0,    0.0,
6857         -1.0,      -1.0,       0.0,     0.0,    1.0,
6858          1.0,      -1.0,       0.0,     1.0,    1.0,
6859     };
6860
6861
6862     memset(&lr, 0, sizeof(lr));
6863     IDirect3DDevice9_GetDirect3D(device, &d3d);
6864     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6865                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6866                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6867         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6868         goto out;
6869     }
6870
6871     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6872                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6873                                         &texture, NULL);
6874     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6875     if(!texture) {
6876         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6877         goto out;
6878     }
6879     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6880     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6881
6882     fill_surface(surface, 0xff7f7f7f);
6883     IDirect3DSurface9_Release(surface);
6884
6885     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6886     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6887     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6888     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6889
6890     hr = IDirect3DDevice9_BeginScene(device);
6891     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6892     if(SUCCEEDED(hr))
6893     {
6894         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6895         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6896
6897         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6898         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6899
6900
6901         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6902         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6903
6904         hr = IDirect3DDevice9_EndScene(device);
6905         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6906     }
6907
6908     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6909     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6910     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6911     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6912
6913     color = getPixelColor(device, 320, 240);
6914     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6915
6916     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6917     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6918
6919 out:
6920     if(texture) IDirect3DTexture9_Release(texture);
6921     IDirect3D9_Release(d3d);
6922 }
6923
6924 static void shademode_test(IDirect3DDevice9 *device)
6925 {
6926     /* Render a quad and try all of the different fixed function shading models. */
6927     HRESULT hr;
6928     DWORD color0, color1;
6929     DWORD color0_gouraud = 0, color1_gouraud = 0;
6930     DWORD shademode = D3DSHADE_FLAT;
6931     DWORD primtype = D3DPT_TRIANGLESTRIP;
6932     LPVOID data = NULL;
6933     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6934     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6935     UINT i, j;
6936     struct vertex quad_strip[] =
6937     {
6938         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6939         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6940         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6941         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6942     };
6943     struct vertex quad_list[] =
6944     {
6945         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6946         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6947         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6948
6949         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6950         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6951         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6952     };
6953
6954     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6955                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6956     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6957     if (FAILED(hr)) goto bail;
6958
6959     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6960                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6961     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6962     if (FAILED(hr)) goto bail;
6963
6964     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6965     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6966
6967     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6968     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6969
6970     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6971     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6972     memcpy(data, quad_strip, sizeof(quad_strip));
6973     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6974     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6975
6976     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6977     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6978     memcpy(data, quad_list, sizeof(quad_list));
6979     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6980     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6981
6982     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
6983      * the color fixups we have to do for FLAT shading will be dependent on that. */
6984     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6985     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6986
6987     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6988     for (j=0; j<2; j++) {
6989
6990         /* Inner loop just changes the D3DRS_SHADEMODE */
6991         for (i=0; i<3; i++) {
6992             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6993             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6994
6995             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6996             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6997
6998             hr = IDirect3DDevice9_BeginScene(device);
6999             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7000             if(SUCCEEDED(hr))
7001             {
7002                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
7003                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
7004
7005                 hr = IDirect3DDevice9_EndScene(device);
7006                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7007             }
7008
7009             /* Sample two spots from the output */
7010             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
7011             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
7012             switch(shademode) {
7013                 case D3DSHADE_FLAT:
7014                     /* Should take the color of the first vertex of each triangle */
7015                     if (0)
7016                     {
7017                         /* This test depends on EXT_provoking_vertex being
7018                          * available. This extension is currently (20090810)
7019                          * not common enough to let the test fail if it isn't
7020                          * present. */
7021                         ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
7022                         ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
7023                     }
7024                     shademode = D3DSHADE_GOURAUD;
7025                     break;
7026                 case D3DSHADE_GOURAUD:
7027                     /* Should be an interpolated blend */
7028
7029                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
7030                        "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
7031                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
7032                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
7033
7034                     color0_gouraud = color0;
7035                     color1_gouraud = color1;
7036
7037                     shademode = D3DSHADE_PHONG;
7038                     break;
7039                 case D3DSHADE_PHONG:
7040                     /* Should be the same as GOURAUD, since no hardware implements this */
7041                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
7042                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
7043                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
7044                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
7045
7046                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7047                             color0_gouraud, color0);
7048                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7049                             color1_gouraud, color1);
7050                     break;
7051             }
7052         }
7053
7054         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7055         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7056
7057         /* Now, do it all over again with a TRIANGLELIST */
7058         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
7059         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7060         primtype = D3DPT_TRIANGLELIST;
7061         shademode = D3DSHADE_FLAT;
7062     }
7063
7064 bail:
7065     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7066     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7067     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
7068     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7069
7070     if (vb_strip)
7071         IDirect3DVertexBuffer9_Release(vb_strip);
7072     if (vb_list)
7073         IDirect3DVertexBuffer9_Release(vb_list);
7074 }
7075
7076 static void alpha_test(IDirect3DDevice9 *device)
7077 {
7078     HRESULT hr;
7079     IDirect3DTexture9 *offscreenTexture;
7080     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
7081     DWORD color;
7082
7083     struct vertex quad1[] =
7084     {
7085         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
7086         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
7087         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
7088         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
7089     };
7090     struct vertex quad2[] =
7091     {
7092         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
7093         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
7094         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
7095         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
7096     };
7097     static const float composite_quad[][5] = {
7098         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
7099         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
7100         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
7101         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
7102     };
7103
7104     /* Clear the render target with alpha = 0.5 */
7105     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7106     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7107
7108     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
7109     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
7110
7111     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7112     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7113     if(!backbuffer) {
7114         goto out;
7115     }
7116
7117     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
7118     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
7119     if(!offscreen) {
7120         goto out;
7121     }
7122
7123     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7124     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7125
7126     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7127     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7128     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7129     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7130     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
7131     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
7132     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
7133     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
7134     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7135     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7136
7137     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
7138     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7139     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
7140
7141         /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
7142         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7143         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7144         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7145         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7146         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7147         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7148
7149         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7150         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7151         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7152         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7153         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7154         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7155
7156         /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
7157          * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
7158          * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
7159         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
7160         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7161         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7162         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7163
7164         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7165         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7166         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7167         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7168         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7169         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7170
7171         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7172         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7173         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7174         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7175         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7176         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7177
7178         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7179         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7180
7181         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
7182          * Disable alpha blending for the final composition
7183          */
7184         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
7185         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7186         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7187         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7188
7189         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
7190         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7191         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
7192         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7193         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7194         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7195
7196         hr = IDirect3DDevice9_EndScene(device);
7197         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
7198     }
7199
7200     color = getPixelColor(device, 160, 360);
7201     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7202        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
7203
7204     color = getPixelColor(device, 160, 120);
7205     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
7206        "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
7207
7208     color = getPixelColor(device, 480, 360);
7209     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7210        "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
7211
7212     color = getPixelColor(device, 480, 120);
7213     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
7214        "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
7215
7216     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7217
7218     out:
7219     /* restore things */
7220     if(backbuffer) {
7221         IDirect3DSurface9_Release(backbuffer);
7222     }
7223     if(offscreenTexture) {
7224         IDirect3DTexture9_Release(offscreenTexture);
7225     }
7226     if(offscreen) {
7227         IDirect3DSurface9_Release(offscreen);
7228     }
7229 }
7230
7231 struct vertex_shortcolor {
7232     float x, y, z;
7233     unsigned short r, g, b, a;
7234 };
7235 struct vertex_floatcolor {
7236     float x, y, z;
7237     float r, g, b, a;
7238 };
7239
7240 static void fixed_function_decl_test(IDirect3DDevice9 *device)
7241 {
7242     HRESULT hr;
7243     BOOL s_ok, ub_ok, f_ok;
7244     DWORD color, size, i;
7245     void *data;
7246     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
7247         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7248         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7249         D3DDECL_END()
7250     };
7251     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
7252         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7253         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7254         D3DDECL_END()
7255     };
7256     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
7257         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7258         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7259         D3DDECL_END()
7260     };
7261     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
7262         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7263         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7264         D3DDECL_END()
7265     };
7266     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
7267         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7268         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7269         D3DDECL_END()
7270     };
7271     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
7272         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7273         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7274         D3DDECL_END()
7275     };
7276     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
7277         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
7278         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7279         D3DDECL_END()
7280     };
7281     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
7282     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
7283     IDirect3DVertexBuffer9 *vb, *vb2;
7284     struct vertex quad1[] =                             /* D3DCOLOR */
7285     {
7286         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
7287         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7288         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
7289         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7290     };
7291     struct vertex quad2[] =                             /* UBYTE4N */
7292     {
7293         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7294         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
7295         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7296         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
7297     };
7298     struct vertex_shortcolor quad3[] =                  /* short */
7299     {
7300         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7301         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7302         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7303         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7304     };
7305     struct vertex_floatcolor quad4[] =
7306     {
7307         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7308         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7309         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7310         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7311     };
7312     DWORD colors[] = {
7313         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7314         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7315         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7316         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7317         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7318         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7319         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7320         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7321         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7322         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7323         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7324         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7325         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7326         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7327         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7328         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7329     };
7330     float quads[] = {
7331         -1.0,   -1.0,     0.1,
7332         -1.0,    0.0,     0.1,
7333          0.0,   -1.0,     0.1,
7334          0.0,    0.0,     0.1,
7335
7336          0.0,   -1.0,     0.1,
7337          0.0,    0.0,     0.1,
7338          1.0,   -1.0,     0.1,
7339          1.0,    0.0,     0.1,
7340
7341          0.0,    0.0,     0.1,
7342          0.0,    1.0,     0.1,
7343          1.0,    0.0,     0.1,
7344          1.0,    1.0,     0.1,
7345
7346         -1.0,    0.0,     0.1,
7347         -1.0,    1.0,     0.1,
7348          0.0,    0.0,     0.1,
7349          0.0,    1.0,     0.1
7350     };
7351     struct tvertex quad_transformed[] = {
7352        {  90,    110,     0.1,      2.0,        0x00ffff00},
7353        { 570,    110,     0.1,      2.0,        0x00ffff00},
7354        {  90,    300,     0.1,      2.0,        0x00ffff00},
7355        { 570,    300,     0.1,      2.0,        0x00ffff00}
7356     };
7357     D3DCAPS9 caps;
7358
7359     memset(&caps, 0, sizeof(caps));
7360     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7361     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7362
7363     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7364     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7365
7366     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7367     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7368     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7369     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7370     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7371     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7372     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7373         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7374         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7375         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7376         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7377     } else {
7378         trace("D3DDTCAPS_UBYTE4N not supported\n");
7379         dcl_ubyte_2 = NULL;
7380         dcl_ubyte = NULL;
7381     }
7382     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7383     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7384     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7385     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7386
7387     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7388     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7389                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
7390     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7391
7392     hr = IDirect3DDevice9_BeginScene(device);
7393     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7394     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7395     if(SUCCEEDED(hr)) {
7396         if(dcl_color) {
7397             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7398             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7399             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7400             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7401         }
7402
7403         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7404          * accepts them, the nvidia driver accepts them all. All those differences even though we're
7405          * using software vertex processing. Doh!
7406          */
7407         if(dcl_ubyte) {
7408             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7409             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7410             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7411             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7412             ub_ok = SUCCEEDED(hr);
7413         }
7414
7415         if(dcl_short) {
7416             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7417             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7418             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7419             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7420             s_ok = SUCCEEDED(hr);
7421         }
7422
7423         if(dcl_float) {
7424             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7425             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7426             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7427             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7428             f_ok = SUCCEEDED(hr);
7429         }
7430
7431         hr = IDirect3DDevice9_EndScene(device);
7432         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7433     }
7434
7435     if(dcl_short) {
7436         color = getPixelColor(device, 480, 360);
7437         ok(color == 0x000000ff || !s_ok,
7438            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7439     }
7440     if(dcl_ubyte) {
7441         color = getPixelColor(device, 160, 120);
7442         ok(color == 0x0000ffff || !ub_ok,
7443            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7444     }
7445     if(dcl_color) {
7446         color = getPixelColor(device, 160, 360);
7447         ok(color == 0x00ffff00,
7448            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7449     }
7450     if(dcl_float) {
7451         color = getPixelColor(device, 480, 120);
7452         ok(color == 0x00ff0000 || !f_ok,
7453            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7454     }
7455     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7456
7457     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7458      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7459      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7460      * whether the immediate mode code works
7461      */
7462     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7463     hr = IDirect3DDevice9_BeginScene(device);
7464     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7465     if(SUCCEEDED(hr)) {
7466         if(dcl_color) {
7467             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7468             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7469             memcpy(data, quad1, sizeof(quad1));
7470             hr = IDirect3DVertexBuffer9_Unlock(vb);
7471             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7472             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7473             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7474             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7475             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7476             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7477             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7478         }
7479
7480         if(dcl_ubyte) {
7481             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7482             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7483             memcpy(data, quad2, sizeof(quad2));
7484             hr = IDirect3DVertexBuffer9_Unlock(vb);
7485             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7486             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7487             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7488             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7489             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7490             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7491             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7492                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7493             ub_ok = SUCCEEDED(hr);
7494         }
7495
7496         if(dcl_short) {
7497             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7498             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7499             memcpy(data, quad3, sizeof(quad3));
7500             hr = IDirect3DVertexBuffer9_Unlock(vb);
7501             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7502             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7503             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7504             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7505             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7506             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7507             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7508                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7509             s_ok = SUCCEEDED(hr);
7510         }
7511
7512         if(dcl_float) {
7513             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7514             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7515             memcpy(data, quad4, sizeof(quad4));
7516             hr = IDirect3DVertexBuffer9_Unlock(vb);
7517             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7518             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7519             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7520             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7521             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7522             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7523             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7524                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7525             f_ok = SUCCEEDED(hr);
7526         }
7527
7528         hr = IDirect3DDevice9_EndScene(device);
7529         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7530     }
7531
7532     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7533     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7534     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7535     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7536
7537     if(dcl_short) {
7538         color = getPixelColor(device, 480, 360);
7539         ok(color == 0x000000ff || !s_ok,
7540            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7541     }
7542     if(dcl_ubyte) {
7543         color = getPixelColor(device, 160, 120);
7544         ok(color == 0x0000ffff || !ub_ok,
7545            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7546     }
7547     if(dcl_color) {
7548         color = getPixelColor(device, 160, 360);
7549         ok(color == 0x00ffff00,
7550            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7551     }
7552     if(dcl_float) {
7553         color = getPixelColor(device, 480, 120);
7554         ok(color == 0x00ff0000 || !f_ok,
7555            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7556     }
7557     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7558
7559     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7560     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7561
7562     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7563     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7564     memcpy(data, quad_transformed, sizeof(quad_transformed));
7565     hr = IDirect3DVertexBuffer9_Unlock(vb);
7566     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7567
7568     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7569     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7570
7571     hr = IDirect3DDevice9_BeginScene(device);
7572     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7573     if(SUCCEEDED(hr)) {
7574         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7575         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7576         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7577         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7578
7579         hr = IDirect3DDevice9_EndScene(device);
7580         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7581     }
7582
7583     color = getPixelColor(device, 88, 108);
7584     ok(color == 0x000000ff,
7585        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7586     color = getPixelColor(device, 92, 108);
7587     ok(color == 0x000000ff,
7588        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7589     color = getPixelColor(device, 88, 112);
7590     ok(color == 0x000000ff,
7591        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7592     color = getPixelColor(device, 92, 112);
7593     ok(color == 0x00ffff00,
7594        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7595
7596     color = getPixelColor(device, 568, 108);
7597     ok(color == 0x000000ff,
7598        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7599     color = getPixelColor(device, 572, 108);
7600     ok(color == 0x000000ff,
7601        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7602     color = getPixelColor(device, 568, 112);
7603     ok(color == 0x00ffff00,
7604        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7605     color = getPixelColor(device, 572, 112);
7606     ok(color == 0x000000ff,
7607        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7608
7609     color = getPixelColor(device, 88, 298);
7610     ok(color == 0x000000ff,
7611        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7612     color = getPixelColor(device, 92, 298);
7613     ok(color == 0x00ffff00,
7614        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7615     color = getPixelColor(device, 88, 302);
7616     ok(color == 0x000000ff,
7617        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7618     color = getPixelColor(device, 92, 302);
7619     ok(color == 0x000000ff,
7620        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7621
7622     color = getPixelColor(device, 568, 298);
7623     ok(color == 0x00ffff00,
7624        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7625     color = getPixelColor(device, 572, 298);
7626     ok(color == 0x000000ff,
7627        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7628     color = getPixelColor(device, 568, 302);
7629     ok(color == 0x000000ff,
7630        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7631     color = getPixelColor(device, 572, 302);
7632     ok(color == 0x000000ff,
7633        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7634
7635     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7636
7637     /* This test is pointless without those two declarations: */
7638     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7639         skip("color-ubyte switching test declarations aren't supported\n");
7640         goto out;
7641     }
7642
7643     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7644     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7645     memcpy(data, quads, sizeof(quads));
7646     hr = IDirect3DVertexBuffer9_Unlock(vb);
7647     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7648     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7649                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7650     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7651     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7652     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7653     memcpy(data, colors, sizeof(colors));
7654     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7655     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7656
7657     for(i = 0; i < 2; i++) {
7658         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7659         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7660
7661         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7662         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7663         if(i == 0) {
7664             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7665         } else {
7666             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7667         }
7668         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7669
7670         hr = IDirect3DDevice9_BeginScene(device);
7671         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7672         ub_ok = FALSE;
7673         if(SUCCEEDED(hr)) {
7674             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7675             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7676             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7677             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7678                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7679             ub_ok = SUCCEEDED(hr);
7680
7681             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7682             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7683             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7684             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7685
7686             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7687             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7688             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7689             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7690                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7691             ub_ok = (SUCCEEDED(hr) && ub_ok);
7692
7693             hr = IDirect3DDevice9_EndScene(device);
7694             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7695         }
7696
7697         if(i == 0) {
7698             color = getPixelColor(device, 480, 360);
7699             ok(color == 0x00ff0000,
7700                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7701             color = getPixelColor(device, 160, 120);
7702             ok(color == 0x00ffffff,
7703                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7704             color = getPixelColor(device, 160, 360);
7705             ok(color == 0x000000ff || !ub_ok,
7706                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7707             color = getPixelColor(device, 480, 120);
7708             ok(color == 0x000000ff || !ub_ok,
7709                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7710         } else {
7711             color = getPixelColor(device, 480, 360);
7712             ok(color == 0x000000ff,
7713                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7714             color = getPixelColor(device, 160, 120);
7715             ok(color == 0x00ffffff,
7716                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7717             color = getPixelColor(device, 160, 360);
7718             ok(color == 0x00ff0000 || !ub_ok,
7719                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7720             color = getPixelColor(device, 480, 120);
7721             ok(color == 0x00ff0000 || !ub_ok,
7722                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7723         }
7724         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7725     }
7726
7727     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7728     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7729     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7730     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7731     IDirect3DVertexBuffer9_Release(vb2);
7732
7733     out:
7734     IDirect3DVertexBuffer9_Release(vb);
7735     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7736     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7737     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7738     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7739     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7740     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7741     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7742 }
7743
7744 struct vertex_float16color {
7745     float x, y, z;
7746     DWORD c1, c2;
7747 };
7748
7749 static void test_vshader_float16(IDirect3DDevice9 *device)
7750 {
7751     HRESULT hr;
7752     DWORD color;
7753     void *data;
7754     static const D3DVERTEXELEMENT9 decl_elements[] = {
7755         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7756         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7757         D3DDECL_END()
7758     };
7759     IDirect3DVertexDeclaration9 *vdecl = NULL;
7760     IDirect3DVertexBuffer9 *buffer = NULL;
7761     IDirect3DVertexShader9 *shader;
7762     DWORD shader_code[] = {
7763         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7764         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7765         0x90e40001, 0x0000ffff
7766     };
7767     struct vertex_float16color quad[] = {
7768         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7769         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7770         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7771         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7772
7773         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7774         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7775         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7776         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7777
7778         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7779         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7780         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7781         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7782
7783         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7784         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7785         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7786         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7787     };
7788
7789     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7790     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7791
7792     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7793     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7794     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7795     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7796     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7797     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7798
7799     hr = IDirect3DDevice9_BeginScene(device);
7800     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7801     if(SUCCEEDED(hr)) {
7802         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7803         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7804         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7805         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7806         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7807         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7808         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7809         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7810         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7811         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7812
7813         hr = IDirect3DDevice9_EndScene(device);
7814         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7815     }
7816     color = getPixelColor(device, 480, 360);
7817     ok(color == 0x00ff0000,
7818        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7819     color = getPixelColor(device, 160, 120);
7820     ok(color == 0x00000000,
7821        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7822     color = getPixelColor(device, 160, 360);
7823     ok(color == 0x0000ff00,
7824        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7825     color = getPixelColor(device, 480, 120);
7826     ok(color == 0x000000ff,
7827        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7828     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7829
7830     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7831     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7832
7833     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7834                                              D3DPOOL_MANAGED, &buffer, NULL);
7835     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7836     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7837     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7838     memcpy(data, quad, sizeof(quad));
7839     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7840     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7841     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7842     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7843
7844     hr = IDirect3DDevice9_BeginScene(device);
7845     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7846     if(SUCCEEDED(hr)) {
7847             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7848             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7849             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7850             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7851             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7852             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7853             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7854             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7855
7856             hr = IDirect3DDevice9_EndScene(device);
7857             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7858     }
7859
7860     color = getPixelColor(device, 480, 360);
7861     ok(color == 0x00ff0000,
7862        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7863     color = getPixelColor(device, 160, 120);
7864     ok(color == 0x00000000,
7865        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7866     color = getPixelColor(device, 160, 360);
7867     ok(color == 0x0000ff00,
7868        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7869     color = getPixelColor(device, 480, 120);
7870     ok(color == 0x000000ff,
7871        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7872     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7873
7874     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7875     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7876     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7877     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7878     IDirect3DDevice9_SetVertexShader(device, NULL);
7879     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7880
7881     IDirect3DVertexDeclaration9_Release(vdecl);
7882     IDirect3DVertexShader9_Release(shader);
7883     IDirect3DVertexBuffer9_Release(buffer);
7884 }
7885
7886 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7887 {
7888     D3DCAPS9 caps;
7889     IDirect3DTexture9 *texture;
7890     HRESULT hr;
7891     D3DLOCKED_RECT rect;
7892     unsigned int x, y;
7893     DWORD *dst, color;
7894     const float quad[] = {
7895         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
7896          1.0,   -1.0,   0.1,    1.2,   -0.2,
7897         -1.0,    1.0,   0.1,   -0.2,    1.2,
7898          1.0,    1.0,   0.1,    1.2,    1.2
7899     };
7900     memset(&caps, 0, sizeof(caps));
7901
7902     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7903     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7904     if (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)
7905     {
7906         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7907         ok(caps.TextureCaps & D3DPTEXTURECAPS_POW2,
7908                 "Card has conditional NP2 support without power of two restriction set\n");
7909     }
7910     else if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
7911     {
7912         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7913         return;
7914     }
7915     else
7916     {
7917         skip("Card has unconditional NP2 support, skipping conditional NP2 tests\n");
7918         return;
7919     }
7920
7921     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7922     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7923
7924     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7925     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7926
7927     memset(&rect, 0, sizeof(rect));
7928     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7929     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7930     for(y = 0; y < 10; y++) {
7931         for(x = 0; x < 10; x++) {
7932             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7933             if(x == 0 || x == 9 || y == 0 || y == 9) {
7934                 *dst = 0x00ff0000;
7935             } else {
7936                 *dst = 0x000000ff;
7937             }
7938         }
7939     }
7940     hr = IDirect3DTexture9_UnlockRect(texture, 0);
7941     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7942
7943     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7944     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7945     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7946     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7947     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7948     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7949     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7950     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7951
7952     hr = IDirect3DDevice9_BeginScene(device);
7953     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7954     if(SUCCEEDED(hr)) {
7955         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7956         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7957
7958         hr = IDirect3DDevice9_EndScene(device);
7959         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7960     }
7961
7962     color = getPixelColor(device,    1,  1);
7963     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
7964     color = getPixelColor(device, 639, 479);
7965     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7966
7967     color = getPixelColor(device, 135, 101);
7968     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7969     color = getPixelColor(device, 140, 101);
7970     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7971     color = getPixelColor(device, 135, 105);
7972     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7973     color = getPixelColor(device, 140, 105);
7974     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7975
7976     color = getPixelColor(device, 135, 376);
7977     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7978     color = getPixelColor(device, 140, 376);
7979     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7980     color = getPixelColor(device, 135, 379);
7981     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7982     color = getPixelColor(device, 140, 379);
7983     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7984
7985     color = getPixelColor(device, 500, 101);
7986     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7987     color = getPixelColor(device, 504, 101);
7988     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7989     color = getPixelColor(device, 500, 105);
7990     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7991     color = getPixelColor(device, 504, 105);
7992     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7993
7994     color = getPixelColor(device, 500, 376);
7995     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7996     color = getPixelColor(device, 504, 376);
7997     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7998     color = getPixelColor(device, 500, 380);
7999     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
8000     color = getPixelColor(device, 504, 380);
8001     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
8002
8003     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8004
8005     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8006     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8007     IDirect3DTexture9_Release(texture);
8008 }
8009
8010 static void vFace_register_test(IDirect3DDevice9 *device)
8011 {
8012     HRESULT hr;
8013     DWORD color;
8014     const DWORD shader_code[] = {
8015         0xffff0300,                                                             /* ps_3_0                     */
8016         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8017         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
8018         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
8019         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
8020         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
8021         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8022         0x0000ffff                                                              /* END                        */
8023     };
8024     const DWORD vshader_code[] = {
8025         0xfffe0300,                                                             /* vs_3_0               */
8026         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
8027         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
8028         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
8029         0x0000ffff                                                              /* end                  */
8030     };
8031     IDirect3DPixelShader9 *shader;
8032     IDirect3DVertexShader9 *vshader;
8033     IDirect3DTexture9 *texture;
8034     IDirect3DSurface9 *surface, *backbuffer;
8035     const float quad[] = {
8036         -1.0,   -1.0,   0.1,
8037          1.0,   -1.0,   0.1,
8038         -1.0,    0.0,   0.1,
8039
8040          1.0,   -1.0,   0.1,
8041          1.0,    0.0,   0.1,
8042         -1.0,    0.0,   0.1,
8043
8044         -1.0,    0.0,   0.1,
8045         -1.0,    1.0,   0.1,
8046          1.0,    0.0,   0.1,
8047
8048          1.0,    0.0,   0.1,
8049         -1.0,    1.0,   0.1,
8050          1.0,    1.0,   0.1,
8051     };
8052     const float blit[] = {
8053          0.0,   -1.0,   0.1,    0.0,    0.0,
8054          1.0,   -1.0,   0.1,    1.0,    0.0,
8055          0.0,    1.0,   0.1,    0.0,    1.0,
8056          1.0,    1.0,   0.1,    1.0,    1.0,
8057     };
8058
8059     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8060     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8061     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8062     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8063     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
8064     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8065     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8066     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
8067     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8068     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8069     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8070     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8071     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8072     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8073     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8074     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8075
8076     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8077     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8078
8079     hr = IDirect3DDevice9_BeginScene(device);
8080     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8081     if(SUCCEEDED(hr)) {
8082         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
8083         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8084         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8085         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8086         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8087         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8088         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8089         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8090         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8091         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8092         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8093
8094         /* Blit the texture onto the back buffer to make it visible */
8095         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8096         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
8097         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8098         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8099         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8100         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8101         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8102         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8103         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8104         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8105         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8106         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8107
8108         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
8109         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8110
8111         hr = IDirect3DDevice9_EndScene(device);
8112         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8113     }
8114
8115     color = getPixelColor(device, 160, 360);
8116     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8117     color = getPixelColor(device, 160, 120);
8118     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8119     color = getPixelColor(device, 480, 360);
8120     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8121     color = getPixelColor(device, 480, 120);
8122     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8123     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8124
8125     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8126     IDirect3DDevice9_SetTexture(device, 0, NULL);
8127     IDirect3DPixelShader9_Release(shader);
8128     IDirect3DVertexShader9_Release(vshader);
8129     IDirect3DSurface9_Release(surface);
8130     IDirect3DSurface9_Release(backbuffer);
8131     IDirect3DTexture9_Release(texture);
8132 }
8133
8134 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
8135 {
8136     HRESULT hr;
8137     DWORD color;
8138     int i;
8139     D3DCAPS9 caps;
8140     BOOL L6V5U5_supported = FALSE;
8141     IDirect3DTexture9 *tex1, *tex2;
8142     D3DLOCKED_RECT locked_rect;
8143
8144     static const float quad[][7] = {
8145         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
8146         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
8147         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
8148         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
8149     };
8150
8151     static const D3DVERTEXELEMENT9 decl_elements[] = {
8152         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8153         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8154         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
8155         D3DDECL_END()
8156     };
8157
8158     /* use asymmetric matrix to test loading */
8159     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
8160     float scale, offset;
8161
8162     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
8163     IDirect3DTexture9           *texture            = NULL;
8164
8165     memset(&caps, 0, sizeof(caps));
8166     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8167     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8168     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
8169         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
8170         return;
8171     } else {
8172         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
8173          * They report that it is not supported, but after that bump mapping works properly. So just test
8174          * if the format is generally supported, and check the BUMPENVMAP flag
8175          */
8176         IDirect3D9 *d3d9;
8177
8178         IDirect3DDevice9_GetDirect3D(device, &d3d9);
8179         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8180                                           D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
8181         L6V5U5_supported = SUCCEEDED(hr);
8182         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8183                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
8184         IDirect3D9_Release(d3d9);
8185         if(FAILED(hr)) {
8186             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
8187             return;
8188         }
8189     }
8190
8191     /* Generate the textures */
8192     generate_bumpmap_textures(device);
8193
8194     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
8195     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8196     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
8197     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8198     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
8199     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8200     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
8201     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8202
8203     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
8204     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8205     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
8206     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8207     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
8208     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8209
8210     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8211     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8212     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8213     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8214     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8215     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8216
8217     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8218     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8219
8220     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8221     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
8222
8223     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
8224     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
8225
8226
8227     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
8228     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
8229     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
8230     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
8231
8232     hr = IDirect3DDevice9_BeginScene(device);
8233     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8234
8235     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8236     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8237
8238     hr = IDirect3DDevice9_EndScene(device);
8239     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8240
8241     /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
8242      * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
8243      * But since testing the color match is not the purpose of the test don't be too picky
8244      */
8245     color = getPixelColor(device, 320-32, 240);
8246     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8247     color = getPixelColor(device, 320+32, 240);
8248     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8249     color = getPixelColor(device, 320, 240-32);
8250     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8251     color = getPixelColor(device, 320, 240+32);
8252     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8253     color = getPixelColor(device, 320, 240);
8254     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8255     color = getPixelColor(device, 320+32, 240+32);
8256     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8257     color = getPixelColor(device, 320-32, 240+32);
8258     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8259     color = getPixelColor(device, 320+32, 240-32);
8260     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8261     color = getPixelColor(device, 320-32, 240-32);
8262     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8263     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8264     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8265
8266     for(i = 0; i < 2; i++) {
8267         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
8268         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
8269         IDirect3DTexture9_Release(texture); /* For the GetTexture */
8270         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
8271         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
8272         IDirect3DTexture9_Release(texture); /* To destroy it */
8273     }
8274
8275     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
8276         skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
8277         goto cleanup;
8278     }
8279     if(L6V5U5_supported == FALSE) {
8280         skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
8281         goto cleanup;
8282     }
8283
8284     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
8285     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8286     /* This test only tests the luminance part. The bumpmapping part was already tested above and
8287      * would only make this test more complicated
8288      */
8289     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
8290     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8291     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8292     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8293
8294     memset(&locked_rect, 0, sizeof(locked_rect));
8295     hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
8296     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8297     *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
8298     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8299     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8300
8301     memset(&locked_rect, 0, sizeof(locked_rect));
8302     hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
8303     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8304     *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
8305     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8306     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8307
8308     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8309     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8310     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8311     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8312
8313     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
8314     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8315     scale = 2.0;
8316     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8317     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8318     offset = 0.1;
8319     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8320     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8321
8322     hr = IDirect3DDevice9_BeginScene(device);
8323     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8324     if(SUCCEEDED(hr)) {
8325         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8326         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8327         hr = IDirect3DDevice9_EndScene(device);
8328         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8329     }
8330
8331     color = getPixelColor(device, 320, 240);
8332     /* red:   1.0  * (0.25 * 2.0 + 0.1) = 1.0  * 0.6 = 0.6  = 0x99
8333      * green: 0.5  * (0.25 * 2.0 + 0.1) = 0.5  * 0.6 = 0.3  = 0x4c
8334      * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
8335      */
8336     ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
8337     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8338     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8339
8340     /* Check a result scale factor > 1.0 */
8341     scale = 10;
8342     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8343     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8344     offset = 10;
8345     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8346     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8347
8348     hr = IDirect3DDevice9_BeginScene(device);
8349     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8350     if(SUCCEEDED(hr)) {
8351         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8352         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8353         hr = IDirect3DDevice9_EndScene(device);
8354         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8355     }
8356     color = getPixelColor(device, 320, 240);
8357     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8358     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8359     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8360
8361     /* Check clamping in the scale factor calculation */
8362     scale = 1000;
8363     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8364     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8365     offset = -1;
8366     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8367     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8368
8369     hr = IDirect3DDevice9_BeginScene(device);
8370     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8371     if(SUCCEEDED(hr)) {
8372         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8373         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8374         hr = IDirect3DDevice9_EndScene(device);
8375         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8376     }
8377     color = getPixelColor(device, 320, 240);
8378     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8379     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8380     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8381
8382     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8383     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8384     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8385     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8386
8387     IDirect3DTexture9_Release(tex1);
8388     IDirect3DTexture9_Release(tex2);
8389
8390 cleanup:
8391     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8392     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8393     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8394     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8395
8396     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8397     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8398     IDirect3DVertexDeclaration9_Release(vertex_declaration);
8399 }
8400
8401 static void stencil_cull_test(IDirect3DDevice9 *device) {
8402     HRESULT hr;
8403     IDirect3DSurface9 *depthstencil = NULL;
8404     D3DSURFACE_DESC desc;
8405     float quad1[] = {
8406         -1.0,   -1.0,   0.1,
8407          0.0,   -1.0,   0.1,
8408         -1.0,    0.0,   0.1,
8409          0.0,    0.0,   0.1,
8410     };
8411     float quad2[] = {
8412          0.0,   -1.0,   0.1,
8413          1.0,   -1.0,   0.1,
8414          0.0,    0.0,   0.1,
8415          1.0,    0.0,   0.1,
8416     };
8417     float quad3[] = {
8418         0.0,    0.0,   0.1,
8419         1.0,    0.0,   0.1,
8420         0.0,    1.0,   0.1,
8421         1.0,    1.0,   0.1,
8422     };
8423     float quad4[] = {
8424         -1.0,    0.0,   0.1,
8425          0.0,    0.0,   0.1,
8426         -1.0,    1.0,   0.1,
8427          0.0,    1.0,   0.1,
8428     };
8429     struct vertex painter[] = {
8430        {-1.0,   -1.0,   0.0,    0x00000000},
8431        { 1.0,   -1.0,   0.0,    0x00000000},
8432        {-1.0,    1.0,   0.0,    0x00000000},
8433        { 1.0,    1.0,   0.0,    0x00000000},
8434     };
8435     WORD indices_cw[]  = {0, 1, 3};
8436     WORD indices_ccw[] = {0, 2, 3};
8437     unsigned int i;
8438     DWORD color;
8439
8440     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8441     if(depthstencil == NULL) {
8442         skip("No depth stencil buffer\n");
8443         return;
8444     }
8445     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8446     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8447     IDirect3DSurface9_Release(depthstencil);
8448     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8449         skip("No 4 or 8 bit stencil surface\n");
8450         return;
8451     }
8452
8453     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8454     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8455     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8456
8457     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8458     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8459     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8460     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8461     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8462     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8463     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8464     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8465
8466     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8467     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8468     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8469     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8470     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8471     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8472
8473     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8474     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8475     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8476     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8477
8478     /* First pass: Fill the stencil buffer with some values... */
8479     hr = IDirect3DDevice9_BeginScene(device);
8480     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8481     if(SUCCEEDED(hr))
8482     {
8483         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8484         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8485         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8486                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8487         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8488         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8489                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8490         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8491
8492         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8493         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8494         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8495         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8496         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8497                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8498         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8499         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8500                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8501         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8502
8503         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8504         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8505         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8506                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8507         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8508         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8509                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8510         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8511
8512         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8513         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8514         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8515                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8516         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8517         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8518                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8519         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8520
8521         hr = IDirect3DDevice9_EndScene(device);
8522         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8523     }
8524
8525     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8526     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8527     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8528     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8529     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8530     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8531     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8532     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8533     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8534     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8535     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8536     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8537     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8538
8539     /* 2nd pass: Make the stencil values visible */
8540     hr = IDirect3DDevice9_BeginScene(device);
8541     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8542     if(SUCCEEDED(hr))
8543     {
8544         IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8545         for(i = 0; i < 16; i++) {
8546             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8547             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8548
8549             painter[0].diffuse = (i * 16); /* Creates shades of blue */
8550             painter[1].diffuse = (i * 16);
8551             painter[2].diffuse = (i * 16);
8552             painter[3].diffuse = (i * 16);
8553             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8554             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8555         }
8556         hr = IDirect3DDevice9_EndScene(device);
8557         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8558     }
8559
8560     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8561     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8562
8563     color = getPixelColor(device, 160, 420);
8564     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8565     color = getPixelColor(device, 160, 300);
8566     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8567
8568     color = getPixelColor(device, 480, 420);
8569     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8570     color = getPixelColor(device, 480, 300);
8571     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8572
8573     color = getPixelColor(device, 160, 180);
8574     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8575     color = getPixelColor(device, 160, 60);
8576     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8577
8578     color = getPixelColor(device, 480, 180);
8579     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8580     color = getPixelColor(device, 480, 60);
8581     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8582
8583     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8584     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8585 }
8586
8587 static void vpos_register_test(IDirect3DDevice9 *device)
8588 {
8589     HRESULT hr;
8590     DWORD color;
8591     const DWORD shader_code[] = {
8592     0xffff0300,                                                             /* ps_3_0                     */
8593     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8594     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8595     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8596     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8597     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8598     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8599     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8600     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8601     0x0000ffff                                                              /* end                        */
8602     };
8603     const DWORD shader_frac_code[] = {
8604     0xffff0300,                                                             /* ps_3_0                     */
8605     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8606     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8607     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8608     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8609     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8610     0x0000ffff                                                              /* end                        */
8611     };
8612     const DWORD vshader_code[] = {
8613         0xfffe0300,                                                             /* vs_3_0               */
8614         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
8615         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
8616         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
8617         0x0000ffff                                                              /* end                  */
8618     };
8619     IDirect3DVertexShader9 *vshader;
8620     IDirect3DPixelShader9 *shader, *shader_frac;
8621     IDirect3DSurface9 *surface = NULL, *backbuffer;
8622     const float quad[] = {
8623         -1.0,   -1.0,   0.1,    0.0,    0.0,
8624          1.0,   -1.0,   0.1,    1.0,    0.0,
8625         -1.0,    1.0,   0.1,    0.0,    1.0,
8626          1.0,    1.0,   0.1,    1.0,    1.0,
8627     };
8628     D3DLOCKED_RECT lr;
8629     float constant[4] = {1.0, 0.0, 320, 240};
8630     DWORD *pos;
8631
8632     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8633     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8634     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8635     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8636     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8637     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8638     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8639     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8640     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8641     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8642     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8643     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8644     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8645     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8646     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8647     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8648
8649     hr = IDirect3DDevice9_BeginScene(device);
8650     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8651     if(SUCCEEDED(hr)) {
8652         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8653         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8654         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8655         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8656         hr = IDirect3DDevice9_EndScene(device);
8657         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8658     }
8659
8660     /* This has to be pixel exact */
8661     color = getPixelColor(device, 319, 239);
8662     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8663     color = getPixelColor(device, 320, 239);
8664     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8665     color = getPixelColor(device, 319, 240);
8666     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8667     color = getPixelColor(device, 320, 240);
8668     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8669     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8670
8671     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8672                                              &surface, NULL);
8673     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8674     hr = IDirect3DDevice9_BeginScene(device);
8675     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8676     if(SUCCEEDED(hr)) {
8677         constant[2] = 16; constant[3] = 16;
8678         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8679         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8680         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8681         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8682         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8683         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8684         hr = IDirect3DDevice9_EndScene(device);
8685         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8686     }
8687     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8688     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8689
8690     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8691     color = *pos & 0x00ffffff;
8692     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8693     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8694     color = *pos & 0x00ffffff;
8695     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8696     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8697     color = *pos & 0x00ffffff;
8698     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8699     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8700     color = *pos & 0x00ffffff;
8701     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8702
8703     hr = IDirect3DSurface9_UnlockRect(surface);
8704     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8705
8706     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8707      * have full control over the multisampling setting inside this test
8708      */
8709     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8710     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8711     hr = IDirect3DDevice9_BeginScene(device);
8712     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8713     if(SUCCEEDED(hr)) {
8714         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8715         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8716         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8717         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8718         hr = IDirect3DDevice9_EndScene(device);
8719         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8720     }
8721     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8722     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8723
8724     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8725     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8726
8727     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8728     color = *pos & 0x00ffffff;
8729     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8730
8731     hr = IDirect3DSurface9_UnlockRect(surface);
8732     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8733
8734     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8735     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8736     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8737     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8738     IDirect3DPixelShader9_Release(shader);
8739     IDirect3DPixelShader9_Release(shader_frac);
8740     IDirect3DVertexShader9_Release(vshader);
8741     if(surface) IDirect3DSurface9_Release(surface);
8742     IDirect3DSurface9_Release(backbuffer);
8743 }
8744
8745 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
8746 {
8747     D3DCOLOR color;
8748
8749     color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
8750     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8751     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8752     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8753     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8754
8755     ++r;
8756     color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
8757     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8758     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8759     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8760     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8761
8762     return TRUE;
8763 }
8764
8765 static void pointsize_test(IDirect3DDevice9 *device)
8766 {
8767     HRESULT hr;
8768     D3DCAPS9 caps;
8769     D3DMATRIX matrix;
8770     D3DMATRIX identity;
8771     float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8772     DWORD color;
8773     IDirect3DSurface9 *rt, *backbuffer;
8774     IDirect3DTexture9 *tex1, *tex2;
8775     RECT rect = {0, 0, 128, 128};
8776     D3DLOCKED_RECT lr;
8777     const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8778                                 0x00000000, 0x00000000};
8779     const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8780                                 0x00000000, 0x0000ff00};
8781
8782     const float vertices[] = {
8783         64,     64,     0.1,
8784         128,    64,     0.1,
8785         192,    64,     0.1,
8786         256,    64,     0.1,
8787         320,    64,     0.1,
8788         384,    64,     0.1,
8789         448,    64,     0.1,
8790         512,    64,     0.1,
8791     };
8792
8793     /* 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 */
8794     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;
8795     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;
8796     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;
8797     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;
8798
8799     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;
8800     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;
8801     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;
8802     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;
8803
8804     memset(&caps, 0, sizeof(caps));
8805     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8806     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8807     if(caps.MaxPointSize < 32.0) {
8808         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8809         return;
8810     }
8811
8812     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8813     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8814     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8815     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8816     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8817     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8818     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8819     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8820
8821     hr = IDirect3DDevice9_BeginScene(device);
8822     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8823     if (SUCCEEDED(hr))
8824     {
8825         ptsize = 15.0;
8826         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8827         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8828         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8829         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8830
8831         ptsize = 31.0;
8832         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8833         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8834         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8835         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8836
8837         ptsize = 30.75;
8838         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8839         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8840         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8841         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8842
8843         if (caps.MaxPointSize >= 63.0)
8844         {
8845             ptsize = 63.0;
8846             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8847             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8848             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8849             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8850
8851             ptsize = 62.75;
8852             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8853             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8854             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8855             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8856         }
8857
8858         ptsize = 1.0;
8859         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8860         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8861         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8862         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8863
8864         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8865         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8866         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8867         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8868
8869         /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8870         ptsize = 15.0;
8871         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8872         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8873         ptsize = 1.0;
8874         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8875         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8876         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8877         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8878
8879         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8880         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8881
8882         /* pointsize < pointsize_min < pointsize_max?
8883          * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
8884         ptsize = 1.0;
8885         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8886         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8887         ptsize = 15.0;
8888         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8889         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8890         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8891         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8892
8893         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8894         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8895
8896         hr = IDirect3DDevice9_EndScene(device);
8897         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8898     }
8899
8900     ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
8901     ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
8902     ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
8903
8904     if (caps.MaxPointSize >= 63.0)
8905     {
8906         ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
8907         ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
8908     }
8909
8910     ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
8911     /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
8912     ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
8913     /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
8914     ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
8915
8916     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8917
8918     /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8919      * generates texture coordinates for the point(result: Yes, it does)
8920      *
8921      * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8922      * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8923      * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8924      */
8925     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8926     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8927
8928     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8929     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8930     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8931     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8932     memset(&lr, 0, sizeof(lr));
8933     hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8934     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8935     memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8936     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8937     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8938     memset(&lr, 0, sizeof(lr));
8939     hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8940     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8941     memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8942     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8943     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8944     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8945     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8946     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8947     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8948     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8949     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8950     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8951     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8952     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8953     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8954     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8955     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8956     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8957     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8958
8959     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8960     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8961     ptsize = 32.0;
8962     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8963     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8964
8965     hr = IDirect3DDevice9_BeginScene(device);
8966     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8967     if(SUCCEEDED(hr))
8968     {
8969         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8970         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8971         hr = IDirect3DDevice9_EndScene(device);
8972         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8973     }
8974
8975     color = getPixelColor(device, 64-4, 64-4);
8976     ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
8977     color = getPixelColor(device, 64-4, 64+4);
8978     ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
8979     color = getPixelColor(device, 64+4, 64+4);
8980     ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
8981     color = getPixelColor(device, 64+4, 64-4);
8982     ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
8983     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8984
8985     U(matrix).m[0][0] =  1.0f / 64.0f;
8986     U(matrix).m[1][1] = -1.0f / 64.0f;
8987     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8988     ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
8989
8990     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
8991     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
8992
8993     hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
8994             D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
8995     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
8996
8997     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
8998     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8999     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 0.0f, 0);
9000     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
9001
9002     hr = IDirect3DDevice9_BeginScene(device);
9003     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
9004     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9005     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
9006     hr = IDirect3DDevice9_EndScene(device);
9007     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
9008
9009     hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
9010     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
9011     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9012     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
9013     IDirect3DSurface9_Release(backbuffer);
9014     IDirect3DSurface9_Release(rt);
9015
9016     color = getPixelColor(device, 64-4, 64-4);
9017     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
9018             "Expected color 0x00ff0000, got 0x%08x.\n", color);
9019     color = getPixelColor(device, 64+4, 64-4);
9020     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
9021             "Expected color 0x00ffff00, got 0x%08x.\n", color);
9022     color = getPixelColor(device, 64-4, 64+4);
9023     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
9024             "Expected color 0x00000000, got 0x%08x.\n", color);
9025     color = getPixelColor(device, 64+4, 64+4);
9026     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
9027             "Expected color 0x0000ff00, got 0x%08x.\n", color);
9028
9029     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9030     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
9031
9032     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9033     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9034     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9035     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9036     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9037     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9038     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
9039     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9040     IDirect3DTexture9_Release(tex1);
9041     IDirect3DTexture9_Release(tex2);
9042
9043     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
9044     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9045     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
9046     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9047     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
9048     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
9049 }
9050
9051 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
9052 {
9053     static const DWORD vshader_code[] =
9054     {
9055         0xfffe0300,                                                             /* vs_3_0                     */
9056         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0            */
9057         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0            */
9058         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                 */
9059         0x0000ffff                                                              /* end                        */
9060     };
9061     static const DWORD pshader_code1[] =
9062     {
9063         0xffff0300,                                                             /* ps_3_0                     */
9064         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9065         0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
9066         0x0000ffff                                                              /* end                        */
9067     };
9068     static const DWORD pshader_code2[] =
9069     {
9070         0xffff0300,                                                             /* ps_3_0                     */
9071         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9072         0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
9073         0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
9074         0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1                */
9075         0x0000ffff                                                              /* end                        */
9076     };
9077
9078     HRESULT hr;
9079     IDirect3DVertexShader9 *vs;
9080     IDirect3DPixelShader9 *ps1, *ps2;
9081     IDirect3DTexture9 *tex1, *tex2;
9082     IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
9083     D3DCAPS9 caps;
9084     DWORD color;
9085     UINT i, j;
9086     float quad[] = {
9087        -1.0,   -1.0,    0.1,
9088         1.0,   -1.0,    0.1,
9089        -1.0,    1.0,    0.1,
9090         1.0,    1.0,    0.1,
9091     };
9092     float texquad[] = {
9093        -1.0,   -1.0,    0.1,    0.0,    0.0,
9094         0.0,   -1.0,    0.1,    1.0,    0.0,
9095        -1.0,    1.0,    0.1,    0.0,    1.0,
9096         0.0,    1.0,    0.1,    1.0,    1.0,
9097
9098         0.0,   -1.0,    0.1,    0.0,    0.0,
9099         1.0,   -1.0,    0.1,    1.0,    0.0,
9100         0.0,    1.0,    0.1,    0.0,    1.0,
9101         1.0,    1.0,    0.1,    1.0,    1.0,
9102     };
9103
9104     memset(&caps, 0, sizeof(caps));
9105     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9106     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
9107     if(caps.NumSimultaneousRTs < 2) {
9108         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
9109         return;
9110     }
9111
9112     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
9113     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9114
9115     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
9116             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
9117     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
9118
9119     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
9120             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
9121     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9122     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
9123             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
9124     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9125     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
9126     ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
9127     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code1, &ps1);
9128     ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
9129     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code2, &ps2);
9130     ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
9131
9132     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
9133     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
9134     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
9135     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9136     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
9137     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9138
9139     hr = IDirect3DDevice9_SetVertexShader(device, vs);
9140     ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
9141     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
9142     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9143     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
9144     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9145     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9146     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9147
9148     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
9149     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
9150     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9151     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9152     color = getPixelColorFromSurface(readback, 8, 8);
9153     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9154             "Expected color 0x000000ff, got 0x%08x.\n", color);
9155     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9156     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9157     color = getPixelColorFromSurface(readback, 8, 8);
9158     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9159             "Expected color 0x000000ff, got 0x%08x.\n", color);
9160
9161     /* Render targets not written by the pixel shader should be unmodified. */
9162     hr = IDirect3DDevice9_SetPixelShader(device, ps1);
9163     ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9164     hr = IDirect3DDevice9_BeginScene(device);
9165     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
9166     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
9167     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
9168     hr = IDirect3DDevice9_EndScene(device);
9169     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
9170     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9171     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9172     color = getPixelColorFromSurface(readback, 8, 8);
9173     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
9174             "Expected color 0xff00ff00, got 0x%08x.\n", color);
9175     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9176     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9177     for (i = 6; i < 10; ++i)
9178     {
9179         for (j = 6; j < 10; ++j)
9180         {
9181             color = getPixelColorFromSurface(readback, j, i);
9182             ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9183                     "Expected color 0xff0000ff, got 0x%08x at %u, %u.\n", color, j, i);
9184         }
9185     }
9186
9187     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
9188     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
9189     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9190     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9191     color = getPixelColorFromSurface(readback, 8, 8);
9192     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
9193             "Expected color 0x0000ff00, got 0x%08x.\n", color);
9194     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9195     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9196     color = getPixelColorFromSurface(readback, 8, 8);
9197     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
9198             "Expected color 0x0000ff00, got 0x%08x.\n", color);
9199
9200     hr = IDirect3DDevice9_SetPixelShader(device, ps2);
9201     ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9202
9203     hr = IDirect3DDevice9_BeginScene(device);
9204     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
9205     if(SUCCEEDED(hr)) {
9206         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
9207         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9208
9209         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9210         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
9211         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9212         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
9213         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
9214         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9215         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
9216         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9217         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9218         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9219
9220         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9221         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9222         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
9223         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9224
9225         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
9226         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9227         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
9228         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9229
9230         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9231         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9232
9233         hr = IDirect3DDevice9_EndScene(device);
9234         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9235     }
9236
9237     color = getPixelColor(device, 160, 240);
9238     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
9239     color = getPixelColor(device, 480, 240);
9240     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
9241     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9242
9243     IDirect3DPixelShader9_Release(ps2);
9244     IDirect3DPixelShader9_Release(ps1);
9245     IDirect3DVertexShader9_Release(vs);
9246     IDirect3DTexture9_Release(tex1);
9247     IDirect3DTexture9_Release(tex2);
9248     IDirect3DSurface9_Release(surf1);
9249     IDirect3DSurface9_Release(surf2);
9250     IDirect3DSurface9_Release(backbuf);
9251     IDirect3DSurface9_Release(readback);
9252 }
9253
9254 struct formats {
9255     const char *fmtName;
9256     D3DFORMAT textureFormat;
9257     DWORD resultColorBlending;
9258     DWORD resultColorNoBlending;
9259 };
9260
9261 static const struct formats test_formats[] = {
9262   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
9263   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
9264   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
9265   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
9266   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
9267   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
9268   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
9269   { NULL, 0 }
9270 };
9271
9272 static void pixelshader_blending_test(IDirect3DDevice9 *device)
9273 {
9274     HRESULT hr;
9275     IDirect3DTexture9 *offscreenTexture = NULL;
9276     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
9277     IDirect3D9 *d3d = NULL;
9278     DWORD color;
9279     DWORD r0, g0, b0, r1, g1, b1;
9280     int fmt_index;
9281
9282     static const float quad[][5] = {
9283         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
9284         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
9285         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
9286         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
9287     };
9288
9289     /* Quad with R=0x10, G=0x20 */
9290     static const struct vertex quad1[] = {
9291         {-1.0f, -1.0f, 0.1f, 0x80102000},
9292         {-1.0f,  1.0f, 0.1f, 0x80102000},
9293         { 1.0f, -1.0f, 0.1f, 0x80102000},
9294         { 1.0f,  1.0f, 0.1f, 0x80102000},
9295     };
9296
9297     /* Quad with R=0x20, G=0x10 */
9298     static const struct vertex quad2[] = {
9299         {-1.0f, -1.0f, 0.1f, 0x80201000},
9300         {-1.0f,  1.0f, 0.1f, 0x80201000},
9301         { 1.0f, -1.0f, 0.1f, 0x80201000},
9302         { 1.0f,  1.0f, 0.1f, 0x80201000},
9303     };
9304
9305     IDirect3DDevice9_GetDirect3D(device, &d3d);
9306
9307     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9308     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
9309     if(!backbuffer) {
9310         goto out;
9311     }
9312
9313     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
9314     {
9315         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
9316
9317         if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
9318                 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
9319         {
9320             skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
9321             continue;
9322         }
9323
9324         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9325         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9326
9327         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
9328         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
9329         if(!offscreenTexture) {
9330             continue;
9331         }
9332
9333         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
9334         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
9335         if(!offscreen) {
9336             continue;
9337         }
9338
9339         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9340         ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9341
9342         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9343         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9344         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9345         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9346         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
9347         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
9348         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
9349         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
9350         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9351         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9352
9353         /* Below we will draw two quads with different colors and try to blend them together.
9354          * The result color is compared with the expected outcome.
9355          */
9356         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
9357             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
9358             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9359             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
9360             ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9361
9362             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9363             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9364
9365             /* Draw a quad using color 0x0010200 */
9366             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
9367             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9368             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
9369             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9370             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9371             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9372
9373             /* Draw a quad using color 0x0020100 */
9374             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9375             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9376             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
9377             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9378             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9379             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9380
9381             /* We don't want to blend the result on the backbuffer */
9382             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9383             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9384
9385             /* Prepare rendering the 'blended' texture quad to the backbuffer */
9386             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9387             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9388             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
9389             ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
9390
9391             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9392             ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9393
9394             /* This time with the texture */
9395             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9396             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
9397
9398             IDirect3DDevice9_EndScene(device);
9399         }
9400
9401         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
9402             /* Compare the color of the center quad with our expectation */
9403             color = getPixelColor(device, 320, 240);
9404             r0 = (color & 0x00ff0000) >> 16;
9405             g0 = (color & 0x0000ff00) >>  8;
9406             b0 = (color & 0x000000ff) >>  0;
9407
9408             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
9409             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
9410             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
9411
9412             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9413                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9414                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9415                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9416         } else {
9417             /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9418              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9419              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9420             color = getPixelColor(device, 320, 240);
9421             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);
9422         }
9423         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9424
9425         IDirect3DDevice9_SetTexture(device, 0, NULL);
9426         if(offscreenTexture) {
9427             IDirect3DTexture9_Release(offscreenTexture);
9428         }
9429         if(offscreen) {
9430             IDirect3DSurface9_Release(offscreen);
9431         }
9432     }
9433
9434 out:
9435     /* restore things */
9436     if(backbuffer) {
9437         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9438         IDirect3DSurface9_Release(backbuffer);
9439     }
9440 }
9441
9442 static void tssargtemp_test(IDirect3DDevice9 *device)
9443 {
9444     HRESULT hr;
9445     DWORD color;
9446     static const struct vertex quad[] = {
9447         {-1.0,     -1.0,    0.1,    0x00ff0000},
9448         { 1.0,     -1.0,    0.1,    0x00ff0000},
9449         {-1.0,      1.0,    0.1,    0x00ff0000},
9450         { 1.0,      1.0,    0.1,    0x00ff0000}
9451     };
9452     D3DCAPS9 caps;
9453
9454     memset(&caps, 0, sizeof(caps));
9455     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9456     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9457     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9458         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9459         return;
9460     }
9461
9462     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9463     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9464
9465     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9466     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9467     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9468     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9469
9470     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9471     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9472     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9473     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9474     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9475     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9476
9477     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9478     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9479     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9480     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9481     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9482     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9483
9484     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9485     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9486
9487     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9488     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9489     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9490     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9491
9492     hr = IDirect3DDevice9_BeginScene(device);
9493     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9494     if(SUCCEEDED(hr)) {
9495         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9496         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9497         hr = IDirect3DDevice9_EndScene(device);
9498         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9499     }
9500     color = getPixelColor(device, 320, 240);
9501     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9502     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9503
9504     /* Set stage 1 back to default */
9505     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9506     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9507     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9508     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9509     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9510     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9511     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9512     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9513     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9514     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9515 }
9516
9517 struct testdata
9518 {
9519     DWORD idxVertex; /* number of instances in the first stream */
9520     DWORD idxColor; /* number of instances in the second stream */
9521     DWORD idxInstance; /* should be 1 ?? */
9522     DWORD color1; /* color 1 instance */
9523     DWORD color2; /* color 2 instance */
9524     DWORD color3; /* color 3 instance */
9525     DWORD color4; /* color 4 instance */
9526     WORD strVertex; /* specify which stream to use 0-2*/
9527     WORD strColor;
9528     WORD strInstance;
9529 };
9530
9531 static const struct testdata testcases[]=
9532 {
9533     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
9534     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
9535     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
9536     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
9537     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  4 */
9538     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
9539     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
9540     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
9541     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  8 */
9542     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /*  9 */
9543     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 10 */
9544     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 11 */
9545     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 12 */
9546     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 13 */
9547 /*
9548     This draws one instance on some machines, no instance on others
9549     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2},
9550 */
9551 /*
9552     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
9553     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9554 */
9555 };
9556
9557 /* Drawing Indexed Geometry with instances*/
9558 static void stream_test(IDirect3DDevice9 *device)
9559 {
9560     IDirect3DVertexBuffer9 *vb = NULL;
9561     IDirect3DVertexBuffer9 *vb2 = NULL;
9562     IDirect3DVertexBuffer9 *vb3 = NULL;
9563     IDirect3DIndexBuffer9 *ib = NULL;
9564     IDirect3DVertexDeclaration9 *pDecl = NULL;
9565     IDirect3DVertexShader9 *shader = NULL;
9566     HRESULT hr;
9567     BYTE *data;
9568     DWORD color;
9569     DWORD ind;
9570     unsigned i;
9571
9572     const DWORD shader_code[] =
9573     {
9574         0xfffe0101,                                     /* vs_1_1 */
9575         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
9576         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
9577         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
9578         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
9579         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9580         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
9581         0x0000ffff
9582     };
9583
9584     const float quad[][3] =
9585     {
9586         {-0.5f, -0.5f,  1.1f}, /*0 */
9587         {-0.5f,  0.5f,  1.1f}, /*1 */
9588         { 0.5f, -0.5f,  1.1f}, /*2 */
9589         { 0.5f,  0.5f,  1.1f}, /*3 */
9590     };
9591
9592     const float vertcolor[][4] =
9593     {
9594         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9595         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9596         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9597         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9598     };
9599
9600     /* 4 position for 4 instances */
9601     const float instancepos[][3] =
9602     {
9603         {-0.6f,-0.6f, 0.0f},
9604         { 0.6f,-0.6f, 0.0f},
9605         { 0.6f, 0.6f, 0.0f},
9606         {-0.6f, 0.6f, 0.0f},
9607     };
9608
9609     short indices[] = {0, 1, 2, 1, 2, 3};
9610
9611     D3DVERTEXELEMENT9 decl[] =
9612     {
9613         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9614         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9615         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9616         D3DDECL_END()
9617     };
9618
9619     /* set the default value because it isn't done in wine? */
9620     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9621     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9622
9623     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9624     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9625     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9626
9627     /* check wrong cases */
9628     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9629     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9630     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9631     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9632     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9633     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9634     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9635     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9636     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9637     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9638     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9639     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9640     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9641     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9642     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9643     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9644     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9645     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9646     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9647     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9648
9649     /* set the default value back */
9650     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9651     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9652
9653     /* create all VertexBuffers*/
9654     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9655     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9656     if(!vb) {
9657         skip("Failed to create a vertex buffer\n");
9658         return;
9659     }
9660     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9661     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9662     if(!vb2) {
9663         skip("Failed to create a vertex buffer\n");
9664         goto out;
9665     }
9666     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9667     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9668     if(!vb3) {
9669         skip("Failed to create a vertex buffer\n");
9670         goto out;
9671     }
9672
9673     /* create IndexBuffer*/
9674     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9675     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9676     if(!ib) {
9677         skip("Failed to create a index buffer\n");
9678         goto out;
9679     }
9680
9681     /* copy all Buffers (Vertex + Index)*/
9682     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9683     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9684     memcpy(data, quad, sizeof(quad));
9685     hr = IDirect3DVertexBuffer9_Unlock(vb);
9686     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9687     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9688     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9689     memcpy(data, vertcolor, sizeof(vertcolor));
9690     hr = IDirect3DVertexBuffer9_Unlock(vb2);
9691     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9692     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9693     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9694     memcpy(data, instancepos, sizeof(instancepos));
9695     hr = IDirect3DVertexBuffer9_Unlock(vb3);
9696     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9697     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9698     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9699     memcpy(data, indices, sizeof(indices));
9700     hr = IDirect3DIndexBuffer9_Unlock(ib);
9701     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9702
9703     /* create VertexShader */
9704     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9705     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9706     if(!shader) {
9707         skip("Failed to create a vetex shader\n");
9708         goto out;
9709     }
9710
9711     hr = IDirect3DDevice9_SetVertexShader(device, shader);
9712     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9713
9714     hr = IDirect3DDevice9_SetIndices(device, ib);
9715     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9716
9717     /* run all tests */
9718     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9719     {
9720         struct testdata act = testcases[i];
9721         decl[0].Stream = act.strVertex;
9722         decl[1].Stream = act.strColor;
9723         decl[2].Stream = act.strInstance;
9724         /* create VertexDeclarations */
9725         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9726         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9727
9728         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9729         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9730
9731         hr = IDirect3DDevice9_BeginScene(device);
9732         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9733         if(SUCCEEDED(hr))
9734         {
9735             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9736             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9737
9738             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9739             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9740             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9741             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9742
9743             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9744             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9745             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9746             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9747
9748             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9749             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9750             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9751             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9752
9753             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
9754             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9755             hr = IDirect3DDevice9_EndScene(device);
9756             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9757
9758             /* set all StreamSource && StreamSourceFreq back to default */
9759             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9760             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9761             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9762             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9763             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9764             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9765             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9766             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9767             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9768             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9769             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9770             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9771         }
9772
9773         hr = IDirect3DVertexDeclaration9_Release(pDecl);
9774         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9775
9776         color = getPixelColor(device, 160, 360);
9777         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9778         color = getPixelColor(device, 480, 360);
9779         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9780         color = getPixelColor(device, 480, 120);
9781         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9782         color = getPixelColor(device, 160, 120);
9783         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9784
9785         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9786         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9787     }
9788
9789     hr = IDirect3DDevice9_SetIndices(device, NULL);
9790     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9791
9792 out:
9793     if(vb) IDirect3DVertexBuffer9_Release(vb);
9794     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9795     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9796     if(ib)IDirect3DIndexBuffer9_Release(ib);
9797     if(shader)IDirect3DVertexShader9_Release(shader);
9798 }
9799
9800 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9801     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9802     IDirect3DTexture9 *dsttex = NULL;
9803     HRESULT hr;
9804     DWORD color;
9805     D3DRECT r1 = {0,  0,  50,  50 };
9806     D3DRECT r2 = {50, 0,  100, 50 };
9807     D3DRECT r3 = {50, 50, 100, 100};
9808     D3DRECT r4 = {0,  50,  50, 100};
9809     const float quad[] = {
9810         -1.0,   -1.0,   0.1,    0.0,    0.0,
9811          1.0,   -1.0,   0.1,    1.0,    0.0,
9812         -1.0,    1.0,   0.1,    0.0,    1.0,
9813          1.0,    1.0,   0.1,    1.0,    1.0,
9814     };
9815
9816     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9817     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9818
9819     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9820     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9821     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9822     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9823
9824     if(!src || !dsttex) {
9825         skip("One or more test resources could not be created\n");
9826         goto cleanup;
9827     }
9828
9829     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9830     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9831
9832     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9833     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9834
9835     /* Clear the StretchRect destination for debugging */
9836     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9837     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9838     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9839     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9840
9841     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9842     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9843
9844     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9845     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9846     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9847     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9848     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9849     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9850     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9851     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9852
9853     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9854      * the target -> texture GL blit path
9855      */
9856     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9857     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9858     IDirect3DSurface9_Release(dst);
9859
9860     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9861     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9862
9863     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9864     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9865     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9866     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9867     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9868     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9869     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9870     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9871
9872     hr = IDirect3DDevice9_BeginScene(device);
9873     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9874     if(SUCCEEDED(hr)) {
9875         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9876         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9877         hr = IDirect3DDevice9_EndScene(device);
9878         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9879     }
9880
9881     color = getPixelColor(device, 160, 360);
9882     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9883     color = getPixelColor(device, 480, 360);
9884     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9885     color = getPixelColor(device, 480, 120);
9886     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9887     color = getPixelColor(device, 160, 120);
9888     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9889     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9890     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9891
9892     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9893     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9894     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9895     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9896
9897 cleanup:
9898     if(src) IDirect3DSurface9_Release(src);
9899     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9900     if(dsttex) IDirect3DTexture9_Release(dsttex);
9901 }
9902
9903 static void texop_test(IDirect3DDevice9 *device)
9904 {
9905     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9906     IDirect3DTexture9 *texture = NULL;
9907     D3DLOCKED_RECT locked_rect;
9908     D3DCOLOR color;
9909     D3DCAPS9 caps;
9910     HRESULT hr;
9911     unsigned i;
9912
9913     static const struct {
9914         float x, y, z;
9915         float s, t;
9916         D3DCOLOR diffuse;
9917     } quad[] = {
9918         {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9919         {-1.0f,  1.0f, 0.1f, -1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9920         { 1.0f, -1.0f, 0.1f,  1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9921         { 1.0f,  1.0f, 0.1f,  1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9922     };
9923
9924     static const D3DVERTEXELEMENT9 decl_elements[] = {
9925         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9926         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9927         {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9928         D3DDECL_END()
9929     };
9930
9931     static const struct {
9932         D3DTEXTUREOP op;
9933         const char *name;
9934         DWORD caps_flag;
9935         D3DCOLOR result;
9936     } test_data[] = {
9937         {D3DTOP_SELECTARG1,                "SELECTARG1",                D3DTEXOPCAPS_SELECTARG1,                D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9938         {D3DTOP_SELECTARG2,                "SELECTARG2",                D3DTEXOPCAPS_SELECTARG2,                D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9939         {D3DTOP_MODULATE,                  "MODULATE",                  D3DTEXOPCAPS_MODULATE,                  D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9940         {D3DTOP_MODULATE2X,                "MODULATE2X",                D3DTEXOPCAPS_MODULATE2X,                D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9941         {D3DTOP_MODULATE4X,                "MODULATE4X",                D3DTEXOPCAPS_MODULATE4X,                D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9942         {D3DTOP_ADD,                       "ADD",                       D3DTEXOPCAPS_ADD,                       D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9943         {D3DTOP_ADDSIGNED,                 "ADDSIGNED",                 D3DTEXOPCAPS_ADDSIGNED,                 D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9944         {D3DTOP_ADDSIGNED2X,               "ADDSIGNED2X",               D3DTEXOPCAPS_ADDSIGNED2X,               D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9945         {D3DTOP_SUBTRACT,                  "SUBTRACT",                  D3DTEXOPCAPS_SUBTRACT,                  D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9946         {D3DTOP_ADDSMOOTH,                 "ADDSMOOTH",                 D3DTEXOPCAPS_ADDSMOOTH,                 D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9947         {D3DTOP_BLENDDIFFUSEALPHA,         "BLENDDIFFUSEALPHA",         D3DTEXOPCAPS_BLENDDIFFUSEALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9948         {D3DTOP_BLENDTEXTUREALPHA,         "BLENDTEXTUREALPHA",         D3DTEXOPCAPS_BLENDTEXTUREALPHA,         D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9949         {D3DTOP_BLENDFACTORALPHA,          "BLENDFACTORALPHA",          D3DTEXOPCAPS_BLENDFACTORALPHA,          D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9950         {D3DTOP_BLENDTEXTUREALPHAPM,       "BLENDTEXTUREALPHAPM",       D3DTEXOPCAPS_BLENDTEXTUREALPHAPM,       D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9951         {D3DTOP_BLENDCURRENTALPHA,         "BLENDCURRENTALPHA",         D3DTEXOPCAPS_BLENDCURRENTALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9952         {D3DTOP_MODULATEALPHA_ADDCOLOR,    "MODULATEALPHA_ADDCOLOR",    D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR,    D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9953         {D3DTOP_MODULATECOLOR_ADDALPHA,    "MODULATECOLOR_ADDALPHA",    D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA,    D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9954         {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9955         {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9956         /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9957         {D3DTOP_DOTPRODUCT3,               "DOTPRODUCT3",               D3DTEXOPCAPS_DOTPRODUCT3,               D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9958         {D3DTOP_MULTIPLYADD,               "MULTIPLYADD",               D3DTEXOPCAPS_MULTIPLYADD,               D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9959         {D3DTOP_LERP,                      "LERP",                      D3DTEXOPCAPS_LERP,                      D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9960     };
9961
9962     memset(&caps, 0, sizeof(caps));
9963     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9964     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9965
9966     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9967     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9968     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9969     ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9970
9971     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9972     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9973     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9974     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9975     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9976     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9977     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9978     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9979     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9980
9981     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9982     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9983     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9984     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9985     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9986     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9987
9988     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9989     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9990
9991     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9992     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9993     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9994     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9995     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9996     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9997
9998     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9999     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10000
10001     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
10002     {
10003         if (!(caps.TextureOpCaps & test_data[i].caps_flag))
10004         {
10005             skip("tex operation %s not supported\n", test_data[i].name);
10006             continue;
10007         }
10008
10009         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
10010         ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
10011
10012         hr = IDirect3DDevice9_BeginScene(device);
10013         ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10014
10015         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10016         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10017
10018         hr = IDirect3DDevice9_EndScene(device);
10019         ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10020
10021         color = getPixelColor(device, 320, 240);
10022         ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
10023                 test_data[i].name, color, test_data[i].result);
10024
10025         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10026         ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10027     }
10028
10029     if (texture) IDirect3DTexture9_Release(texture);
10030     if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
10031 }
10032
10033 static void yuv_color_test(IDirect3DDevice9 *device) {
10034     HRESULT hr;
10035     IDirect3DSurface9 *surface = NULL, *target = NULL;
10036     unsigned int fmt, i;
10037     D3DFORMAT format;
10038     const char *fmt_string;
10039     D3DLOCKED_RECT lr;
10040     IDirect3D9 *d3d;
10041     HRESULT color;
10042     DWORD ref_color_left, ref_color_right;
10043
10044     struct {
10045         DWORD in;           /* The input color */
10046         DWORD uyvy_left;    /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
10047         DWORD uyvy_right;   /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
10048         DWORD yuy2_left;    /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
10049         DWORD yuy2_right;   /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
10050     } test_data[] = {
10051     /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
10052      * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
10053      * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
10054      * that
10055      */
10056       { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
10057       { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
10058       { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
10059       { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
10060       { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
10061       { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
10062       { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
10063       { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
10064       { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
10065       { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
10066       { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
10067       { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
10068       { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
10069       { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
10070
10071       { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
10072       { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
10073       { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
10074       { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
10075     };
10076
10077     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
10078     ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
10079     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
10080     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
10081
10082     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
10083     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
10084
10085     for(fmt = 0; fmt < 2; fmt++) {
10086         if(fmt == 0) {
10087             format = D3DFMT_UYVY;
10088             fmt_string = "D3DFMT_UYVY";
10089         } else {
10090             format = D3DFMT_YUY2;
10091             fmt_string = "D3DFMT_YUY2";
10092         }
10093
10094         /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
10095                        * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
10096                        */
10097         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
10098                                         D3DRTYPE_SURFACE, format) != D3D_OK) {
10099             skip("%s is not supported\n", fmt_string);
10100             continue;
10101         }
10102
10103         /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
10104         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
10105         ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
10106
10107         for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
10108             if(fmt == 0) {
10109                 ref_color_left = test_data[i].uyvy_left;
10110                 ref_color_right = test_data[i].uyvy_right;
10111             } else {
10112                 ref_color_left = test_data[i].yuy2_left;
10113                 ref_color_right = test_data[i].yuy2_right;
10114             }
10115
10116             memset(&lr, 0, sizeof(lr));
10117             hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
10118             ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
10119             *((DWORD *) lr.pBits) = test_data[i].in;
10120             hr = IDirect3DSurface9_UnlockRect(surface);
10121             ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
10122
10123             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10124             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10125             hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
10126             ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
10127
10128             /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
10129              * prevent running into precision problems, read a far left and far right pixel. In the future we may
10130              * want to add tests for the filtered pixels as well.
10131              *
10132              * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
10133              * differently, so we need a max diff of 16
10134              */
10135             color = getPixelColor(device, 40, 240);
10136
10137             /* Newer versions of the Nvidia Windows driver mix up the U and V channels, breaking all the tests
10138              * where U != V. Skip the entire test if this bug in this case
10139              */
10140             if (broken(test_data[i].in == 0xff000000 && color == 0x00008800 && format == D3DFMT_UYVY))
10141             {
10142                 skip("Nvidia channel confusion bug detected, skipping YUV tests\n");
10143                 IDirect3DSurface9_Release(surface);
10144                 goto out;
10145             }
10146
10147             ok(color_match(color, ref_color_left, 18),
10148                "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
10149                test_data[i].in, color, ref_color_left, fmt_string);
10150             color = getPixelColor(device, 600, 240);
10151             ok(color_match(color, ref_color_right, 18),
10152                "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
10153                test_data[i].in, color, ref_color_right, fmt_string);
10154             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10155             ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10156         }
10157         IDirect3DSurface9_Release(surface);
10158     }
10159
10160 out:
10161     IDirect3DSurface9_Release(target);
10162     IDirect3D9_Release(d3d);
10163 }
10164
10165 static void texop_range_test(IDirect3DDevice9 *device)
10166 {
10167     static const struct {
10168         float x, y, z;
10169         D3DCOLOR diffuse;
10170     } quad[] = {
10171         {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10172         {-1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10173         { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10174         { 1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
10175     };
10176     HRESULT hr;
10177     IDirect3DTexture9 *texture;
10178     D3DLOCKED_RECT locked_rect;
10179     D3DCAPS9 caps;
10180     DWORD color;
10181
10182     /* We need ADD and SUBTRACT operations */
10183     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10184     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10185     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
10186         skip("D3DTOP_ADD is not supported, skipping value range test\n");
10187         return;
10188     }
10189     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
10190         skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
10191         return;
10192     }
10193
10194     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10195     ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
10196     /* Stage 1: result = diffuse(=1.0) + diffuse
10197      * stage 2: result = result - tfactor(= 0.5)
10198      */
10199     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10200     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10201     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10202     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10203     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10204     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10205     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
10206     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10207     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10208     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10209     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10210     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10211     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10212     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10213
10214     hr = IDirect3DDevice9_BeginScene(device);
10215     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10216     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10217     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10218     hr = IDirect3DDevice9_EndScene(device);
10219     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10220
10221     color = getPixelColor(device, 320, 240);
10222     ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
10223        color);
10224     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10225     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10226
10227     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
10228     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
10229     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
10230     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10231     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
10232     hr = IDirect3DTexture9_UnlockRect(texture, 0);
10233     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10234     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10235     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10236
10237     /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
10238      * stage 2: result = result + diffuse(1.0)
10239      */
10240     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10241     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10242     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10243     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10244     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10245     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10246     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10247     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10248     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10249     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10250     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10251     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10252     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
10253     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10254
10255     hr = IDirect3DDevice9_BeginScene(device);
10256     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10257     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10258     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10259     hr = IDirect3DDevice9_EndScene(device);
10260     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10261
10262     color = getPixelColor(device, 320, 240);
10263     ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
10264        color);
10265     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10266     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10267
10268     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10269     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10270     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10271     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10272     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
10273     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10274     IDirect3DTexture9_Release(texture);
10275 }
10276
10277 static void alphareplicate_test(IDirect3DDevice9 *device) {
10278     struct vertex quad[] = {
10279         { -1.0,    -1.0,    0.1,    0x80ff00ff },
10280         {  1.0,    -1.0,    0.1,    0x80ff00ff },
10281         { -1.0,     1.0,    0.1,    0x80ff00ff },
10282         {  1.0,     1.0,    0.1,    0x80ff00ff },
10283     };
10284     HRESULT hr;
10285     DWORD color;
10286
10287     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10288     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10289
10290     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10291     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10292
10293     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10294     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10295     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
10296     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10297
10298     hr = IDirect3DDevice9_BeginScene(device);
10299     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10300     if(SUCCEEDED(hr)) {
10301         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10302         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10303         hr = IDirect3DDevice9_EndScene(device);
10304         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10305     }
10306
10307     color = getPixelColor(device, 320, 240);
10308     ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
10309        color);
10310     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10311     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10312
10313     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10314     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10315
10316 }
10317
10318 static void dp3_alpha_test(IDirect3DDevice9 *device) {
10319     HRESULT hr;
10320     D3DCAPS9 caps;
10321     DWORD color;
10322     struct vertex quad[] = {
10323         { -1.0,    -1.0,    0.1,    0x408080c0 },
10324         {  1.0,    -1.0,    0.1,    0x408080c0 },
10325         { -1.0,     1.0,    0.1,    0x408080c0 },
10326         {  1.0,     1.0,    0.1,    0x408080c0 },
10327     };
10328
10329     memset(&caps, 0, sizeof(caps));
10330     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10331     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10332     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
10333         skip("D3DTOP_DOTPRODUCT3 not supported\n");
10334         return;
10335     }
10336
10337     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10338     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10339
10340     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10341     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10342
10343     /* dp3_x4 r0, diffuse_bias, tfactor_bias
10344      * mov r0.a, diffuse.a
10345      * mov r0, r0.a
10346      *
10347      * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
10348      * 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
10349      * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
10350      */
10351     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
10352     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10353     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10354     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10355     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10356     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10357     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
10358     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10359     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
10360     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10361     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10362     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10363     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
10364     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10365     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10366     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10367     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
10368     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10369
10370     hr = IDirect3DDevice9_BeginScene(device);
10371     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10372     if(SUCCEEDED(hr)) {
10373         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10374         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10375         hr = IDirect3DDevice9_EndScene(device);
10376         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10377     }
10378
10379     color = getPixelColor(device, 320, 240);
10380     ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
10381        color);
10382     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10383     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10384
10385     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10386     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10387     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10388     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10389     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10390     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10391 }
10392
10393 static void zwriteenable_test(IDirect3DDevice9 *device) {
10394     HRESULT hr;
10395     DWORD color;
10396     struct vertex quad1[] = {
10397         { -1.0,  -1.0,  0.1,    0x00ff0000},
10398         { -1.0,   1.0,  0.1,    0x00ff0000},
10399         {  1.0,  -1.0,  0.1,    0x00ff0000},
10400         {  1.0,   1.0,  0.1,    0x00ff0000},
10401     };
10402     struct vertex quad2[] = {
10403         { -1.0,  -1.0,  0.9,    0x0000ff00},
10404         { -1.0,   1.0,  0.9,    0x0000ff00},
10405         {  1.0,  -1.0,  0.9,    0x0000ff00},
10406         {  1.0,   1.0,  0.9,    0x0000ff00},
10407     };
10408
10409     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
10410     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10411
10412     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10413     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10414     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10415     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10416     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10417     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10418     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10419     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10420
10421     hr = IDirect3DDevice9_BeginScene(device);
10422     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10423     if(SUCCEEDED(hr)) {
10424         /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10425          * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10426          * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10427          * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10428          * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10429          * the screen is green, so zenable = D3DZB_FALSE and zwriteenable  = TRUE does NOT write to the z buffer.
10430          */
10431         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10432         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10433         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10434         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10435         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10436         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10437
10438         hr = IDirect3DDevice9_EndScene(device);
10439         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10440     }
10441
10442     color = getPixelColor(device, 320, 240);
10443     ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10444        color);
10445     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10446     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10447
10448     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10449     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10450 }
10451
10452 static void alphatest_test(IDirect3DDevice9 *device) {
10453 #define ALPHATEST_PASSED 0x0000ff00
10454 #define ALPHATEST_FAILED 0x00ff0000
10455     struct {
10456         D3DCMPFUNC  func;
10457         DWORD       color_less;
10458         DWORD       color_equal;
10459         DWORD       color_greater;
10460     } testdata[] = {
10461         {   D3DCMP_NEVER,           ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10462         {   D3DCMP_LESS,            ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10463         {   D3DCMP_EQUAL,           ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10464         {   D3DCMP_LESSEQUAL,       ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10465         {   D3DCMP_GREATER,         ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10466         {   D3DCMP_NOTEQUAL,        ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10467         {   D3DCMP_GREATEREQUAL,    ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10468         {   D3DCMP_ALWAYS,          ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10469     };
10470     unsigned int i, j;
10471     HRESULT hr;
10472     DWORD color;
10473     struct vertex quad[] = {
10474         {   -1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10475         {    1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10476         {   -1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10477         {    1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10478     };
10479     D3DCAPS9 caps;
10480
10481     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10482     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10483     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10484     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10485
10486     for(j = 0; j < 2; j++) {
10487         if(j == 1) {
10488             /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10489              * the alpha test either for performance reasons(floating point RTs) or to work
10490              * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10491              * codepath for ffp and shader in this case, and the test should cover both
10492              */
10493             IDirect3DPixelShader9 *ps;
10494             DWORD shader_code[] = {
10495                 0xffff0101,                                 /* ps_1_1           */
10496                 0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
10497                 0x0000ffff                                  /* end              */
10498             };
10499             memset(&caps, 0, sizeof(caps));
10500             IDirect3DDevice9_GetDeviceCaps(device, &caps);
10501             ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10502             if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10503                 break;
10504             }
10505
10506             hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10507             ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10508             IDirect3DDevice9_SetPixelShader(device, ps);
10509             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10510             IDirect3DPixelShader9_Release(ps);
10511         }
10512
10513         for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10514             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10515             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10516
10517             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10518             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10519             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10520             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10521             hr = IDirect3DDevice9_BeginScene(device);
10522             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10523             if(SUCCEEDED(hr)) {
10524                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10525                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10526                 hr = IDirect3DDevice9_EndScene(device);
10527                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10528             }
10529             color = getPixelColor(device, 320, 240);
10530             ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10531             color, testdata[i].color_less, testdata[i].func);
10532             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10533             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10534
10535             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10536             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10537             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10538             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10539             hr = IDirect3DDevice9_BeginScene(device);
10540             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10541             if(SUCCEEDED(hr)) {
10542                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10543                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10544                 hr = IDirect3DDevice9_EndScene(device);
10545                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10546             }
10547             color = getPixelColor(device, 320, 240);
10548             ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10549             color, testdata[i].color_equal, testdata[i].func);
10550             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10551             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10552
10553             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10554             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10555             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10556             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10557             hr = IDirect3DDevice9_BeginScene(device);
10558             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10559             if(SUCCEEDED(hr)) {
10560                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10561                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10562                 hr = IDirect3DDevice9_EndScene(device);
10563                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10564             }
10565             color = getPixelColor(device, 320, 240);
10566             ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10567             color, testdata[i].color_greater, testdata[i].func);
10568             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10569             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10570         }
10571     }
10572
10573     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10574     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10575     IDirect3DDevice9_SetPixelShader(device, NULL);
10576     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10577 }
10578
10579 static void sincos_test(IDirect3DDevice9 *device) {
10580     const DWORD sin_shader_code[] = {
10581         0xfffe0200,                                                                 /* vs_2_0                       */
10582         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10583         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10584         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10585         0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.y, r1.x, c0, c1    */
10586         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10587         0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002,                             /* mul oPos.y, r0.y, c2.w       */
10588         0x02000001, 0xd00f0000, 0xa0a60002,                                         /* mov oD0, c2.zyzz             */
10589         0x0000ffff                                                                  /* end                          */
10590     };
10591     const DWORD cos_shader_code[] = {
10592         0xfffe0200,                                                                 /* vs_2_0                       */
10593         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10594         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10595         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10596         0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.x, r1.x, c0, c1    */
10597         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10598         0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002,                             /* mul oPos.y, r0.x, c2.w       */
10599         0x02000001, 0xd00f0000, 0xa0a90002,                                         /* mov oD0, c2.yzzz             */
10600         0x0000ffff                                                                  /* end                          */
10601     };
10602     IDirect3DVertexShader9 *sin_shader, *cos_shader;
10603     HRESULT hr;
10604     struct {
10605         float x, y, z;
10606     } data[1280];
10607     unsigned int i;
10608     float sincosc1[4] = {D3DSINCOSCONST1};
10609     float sincosc2[4] = {D3DSINCOSCONST2};
10610
10611     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10612     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10613
10614     hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10615     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10616     hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10617     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10618     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10619     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10620     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10621     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10622     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10623     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10624
10625     /* Generate a point from -1 to 1 every 0.5 pixels */
10626     for(i = 0; i < 1280; i++) {
10627         data[i].x = (-640.0 + i) / 640.0;
10628         data[i].y = 0.0;
10629         data[i].z = 0.1;
10630     }
10631
10632     hr = IDirect3DDevice9_BeginScene(device);
10633     if(SUCCEEDED(hr)) {
10634         hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10635         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10636         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10637         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10638
10639         hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10640         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10641         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10642         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10643
10644         hr = IDirect3DDevice9_EndScene(device);
10645         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10646     }
10647     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10648     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10649     /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10650
10651     IDirect3DDevice9_SetVertexShader(device, NULL);
10652     IDirect3DVertexShader9_Release(sin_shader);
10653     IDirect3DVertexShader9_Release(cos_shader);
10654 }
10655
10656 static void loop_index_test(IDirect3DDevice9 *device) {
10657     const DWORD shader_code[] = {
10658         0xfffe0200,                                                 /* vs_2_0                   */
10659         0x0200001f, 0x80000000, 0x900f0000,                         /* dcl_position v0          */
10660         0x02000001, 0x800f0000, 0xa0e40000,                         /* mov r0, c0               */
10661         0x0200001b, 0xf0e40800, 0xf0e40000,                         /* loop aL, i0              */
10662         0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1]    */
10663         0x0000001d,                                                 /* endloop                  */
10664         0x02000001, 0xc00f0000, 0x90e40000,                         /* mov oPos, v0             */
10665         0x02000001, 0xd00f0000, 0x80e40000,                         /* mov oD0, r0              */
10666         0x0000ffff                                                  /* END                      */
10667     };
10668     IDirect3DVertexShader9 *shader;
10669     HRESULT hr;
10670     DWORD color;
10671     const float quad[] = {
10672         -1.0,   -1.0,   0.1,
10673          1.0,   -1.0,   0.1,
10674         -1.0,    1.0,   0.1,
10675          1.0,    1.0,   0.1
10676     };
10677     const float zero[4] = {0, 0, 0, 0};
10678     const float one[4] = {1, 1, 1, 1};
10679     int i0[4] = {2, 10, -3, 0};
10680     float values[4];
10681
10682     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10683     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10684     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10685     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10686     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10687     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10688     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10689     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10690
10691     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10692     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10693     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10694     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10695     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10696     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10697     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10698     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10699     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10700     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10701     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10702     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10703     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10704     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10705     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10706     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10707     values[0] = 1.0;
10708     values[1] = 1.0;
10709     values[2] = 0.0;
10710     values[3] = 0.0;
10711     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10712     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10713     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10714     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10715     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10716     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10717     values[0] = -1.0;
10718     values[1] = 0.0;
10719     values[2] = 0.0;
10720     values[3] = 0.0;
10721     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10722     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10723     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10724     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10725     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10726     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10727     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10728     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10729     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10730     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10731
10732     hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10733     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10734
10735     hr = IDirect3DDevice9_BeginScene(device);
10736     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10737     if(SUCCEEDED(hr))
10738     {
10739         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10740         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10741         hr = IDirect3DDevice9_EndScene(device);
10742         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10743     }
10744     color = getPixelColor(device, 320, 240);
10745     ok(color_match(color, 0x0000ff00, 1),
10746        "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10747     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10748     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10749
10750     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10751     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10752     IDirect3DVertexShader9_Release(shader);
10753 }
10754
10755 static void sgn_test(IDirect3DDevice9 *device) {
10756     const DWORD shader_code[] = {
10757         0xfffe0200,                                                             /* vs_2_0                       */
10758         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position o0              */
10759         0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10760         0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0   */
10761         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
10762         0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002,             /* sgn r0, c0, r1, r2           */
10763         0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001,                         /* add oD0, r0, c1              */
10764         0x0000ffff                                                              /* end                          */
10765     };
10766     IDirect3DVertexShader9 *shader;
10767     HRESULT hr;
10768     DWORD color;
10769     const float quad[] = {
10770         -1.0,   -1.0,   0.1,
10771          1.0,   -1.0,   0.1,
10772         -1.0,    1.0,   0.1,
10773          1.0,    1.0,   0.1
10774     };
10775
10776     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10777     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10778     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10779     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10780     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10781     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10782     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10783     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10784
10785     hr = IDirect3DDevice9_BeginScene(device);
10786     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10787     if(SUCCEEDED(hr))
10788     {
10789         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10790         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10791         hr = IDirect3DDevice9_EndScene(device);
10792         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10793     }
10794     color = getPixelColor(device, 320, 240);
10795     ok(color_match(color, 0x008000ff, 1),
10796        "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10797     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10798     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10799
10800     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10801     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10802     IDirect3DVertexShader9_Release(shader);
10803 }
10804
10805 static void viewport_test(IDirect3DDevice9 *device) {
10806     HRESULT hr;
10807     DWORD color;
10808     D3DVIEWPORT9 vp, old_vp;
10809     BOOL draw_failed = TRUE;
10810     const float quad[] =
10811     {
10812         -0.5,   -0.5,   0.1,
10813          0.5,   -0.5,   0.1,
10814         -0.5,    0.5,   0.1,
10815          0.5,    0.5,   0.1
10816     };
10817
10818     memset(&old_vp, 0, sizeof(old_vp));
10819     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10820     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10821
10822     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10823     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10824
10825     /* Test a viewport with Width and Height bigger than the surface dimensions
10826      *
10827      * TODO: Test Width < surface.width, but X + Width > surface.width
10828      * TODO: Test Width < surface.width, what happens with the height?
10829      *
10830      * The expected behavior is that the viewport behaves like the "default"
10831      * viewport with X = Y = 0, Width = surface_width, Height = surface_height,
10832      * MinZ = 0.0, MaxZ = 1.0.
10833      *
10834      * Starting with Windows 7 the behavior among driver versions is not
10835      * consistent. The SetViewport call is accepted on all drivers. Some
10836      * drivers(older nvidia ones) refuse to draw and return an error. Newer
10837      * nvidia drivers draw, but use the actual values in the viewport and only
10838      * display the upper left part on the surface.
10839      */
10840     memset(&vp, 0, sizeof(vp));
10841     vp.X = 0;
10842     vp.Y = 0;
10843     vp.Width = 10000;
10844     vp.Height = 10000;
10845     vp.MinZ = 0.0;
10846     vp.MaxZ = 0.0;
10847     hr = IDirect3DDevice9_SetViewport(device, &vp);
10848     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10849
10850     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10851     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10852     hr = IDirect3DDevice9_BeginScene(device);
10853     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10854     if(SUCCEEDED(hr))
10855     {
10856         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10857         ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "DrawPrimitiveUP failed (%08x)\n", hr);
10858         draw_failed = FAILED(hr);
10859         hr = IDirect3DDevice9_EndScene(device);
10860         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10861     }
10862
10863     if(!draw_failed)
10864     {
10865         color = getPixelColor(device, 158, 118);
10866         ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10867         color = getPixelColor(device, 162, 118);
10868         ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10869         color = getPixelColor(device, 158, 122);
10870         ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10871         color = getPixelColor(device, 162, 122);
10872         ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (162,122) has color %08x\n", color);
10873
10874         color = getPixelColor(device, 478, 358);
10875         ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (478,358 has color %08x\n", color);
10876         color = getPixelColor(device, 482, 358);
10877         ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10878         color = getPixelColor(device, 478, 362);
10879         ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10880         color = getPixelColor(device, 482, 362);
10881         ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10882     }
10883
10884     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10885     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10886
10887     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10888     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10889 }
10890
10891 /* This test tests depth clamping / clipping behaviour:
10892  *   - With software vertex processing, depth values are clamped to the
10893  *     minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
10894  *     when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
10895  *     same as regular vertices here.
10896  *   - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
10897  *     Normal vertices are always clipped. Pretransformed vertices are
10898  *     clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
10899  *   - The viewport's MinZ/MaxZ is irrelevant for this.
10900  */
10901 static void depth_clamp_test(IDirect3DDevice9 *device)
10902 {
10903     const struct tvertex quad1[] =
10904     {
10905         {  0.0f,   0.0f,  5.0f, 1.0f, 0xff002b7f},
10906         {640.0f,   0.0f,  5.0f, 1.0f, 0xff002b7f},
10907         {  0.0f, 480.0f,  5.0f, 1.0f, 0xff002b7f},
10908         {640.0f, 480.0f,  5.0f, 1.0f, 0xff002b7f},
10909     };
10910     const struct tvertex quad2[] =
10911     {
10912         {  0.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
10913         {640.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
10914         {  0.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
10915         {640.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
10916     };
10917     const struct tvertex quad3[] =
10918     {
10919         {112.0f, 108.0f,  5.0f, 1.0f, 0xffffffff},
10920         {208.0f, 108.0f,  5.0f, 1.0f, 0xffffffff},
10921         {112.0f, 204.0f,  5.0f, 1.0f, 0xffffffff},
10922         {208.0f, 204.0f,  5.0f, 1.0f, 0xffffffff},
10923     };
10924     const struct tvertex quad4[] =
10925     {
10926         { 42.0f,  41.0f, 10.0f, 1.0f, 0xffffffff},
10927         {112.0f,  41.0f, 10.0f, 1.0f, 0xffffffff},
10928         { 42.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
10929         {112.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
10930     };
10931     const struct vertex quad5[] =
10932     {
10933         { -0.5f,   0.5f, 10.0f,       0xff14f914},
10934         {  0.5f,   0.5f, 10.0f,       0xff14f914},
10935         { -0.5f,  -0.5f, 10.0f,       0xff14f914},
10936         {  0.5f,  -0.5f, 10.0f,       0xff14f914},
10937     };
10938     const struct vertex quad6[] =
10939     {
10940         { -1.0f,   0.5f, 10.0f,      0xfff91414},
10941         {  1.0f,   0.5f, 10.0f,      0xfff91414},
10942         { -1.0f,  0.25f, 10.0f,      0xfff91414},
10943         {  1.0f,  0.25f, 10.0f,      0xfff91414},
10944     };
10945
10946     D3DVIEWPORT9 vp;
10947     D3DCOLOR color;
10948     D3DCAPS9 caps;
10949     HRESULT hr;
10950
10951     vp.X = 0;
10952     vp.Y = 0;
10953     vp.Width = 640;
10954     vp.Height = 480;
10955     vp.MinZ = 0.0;
10956     vp.MaxZ = 7.5;
10957
10958     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10959     ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
10960
10961     hr = IDirect3DDevice9_SetViewport(device, &vp);
10962     if(FAILED(hr))
10963     {
10964         /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
10965          * the tests because the 7.5 is just intended to show that it doesn't have
10966          * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
10967          * viewport and continue.
10968          */
10969         ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
10970         vp.MaxZ = 1.0;
10971         hr = IDirect3DDevice9_SetViewport(device, &vp);
10972     }
10973     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10974
10975     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
10976     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10977
10978     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10979     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10980     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10981     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10982     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10983     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10984     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10985     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10986
10987     hr = IDirect3DDevice9_BeginScene(device);
10988     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10989
10990     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10991     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10992
10993     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10994     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10995     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10996     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10997
10998     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10999     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11000
11001     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11002     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11003     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
11004     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11005
11006     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
11007     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11008
11009     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11010     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11011
11012     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
11013     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11014
11015     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
11016     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11017
11018     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
11019     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11020
11021     hr = IDirect3DDevice9_EndScene(device);
11022     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11023
11024     if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
11025     {
11026         color = getPixelColor(device, 75, 75);
11027         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11028         color = getPixelColor(device, 150, 150);
11029         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11030         color = getPixelColor(device, 320, 240);
11031         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11032         color = getPixelColor(device, 320, 330);
11033         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11034         color = getPixelColor(device, 320, 330);
11035         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11036     }
11037     else
11038     {
11039         color = getPixelColor(device, 75, 75);
11040         ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
11041         color = getPixelColor(device, 150, 150);
11042         ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
11043         color = getPixelColor(device, 320, 240);
11044         ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
11045         color = getPixelColor(device, 320, 330);
11046         ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11047         color = getPixelColor(device, 320, 330);
11048         ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11049     }
11050
11051     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11052     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11053
11054     vp.MinZ = 0.0;
11055     vp.MaxZ = 1.0;
11056     hr = IDirect3DDevice9_SetViewport(device, &vp);
11057     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11058 }
11059
11060 static void depth_bounds_test(IDirect3DDevice9 *device)
11061 {
11062     const struct tvertex quad1[] =
11063     {
11064         {    0,    0, 0.0f, 1, 0xfff9e814},
11065         {  640,    0, 0.0f, 1, 0xfff9e814},
11066         {    0,  480, 1.0f, 1, 0xfff9e814},
11067         {  640,  480, 1.0f, 1, 0xfff9e814},
11068     };
11069     const struct tvertex quad2[] =
11070     {
11071         {    0,    0,  0.6f, 1, 0xff002b7f},
11072         {  640,    0,  0.6f, 1, 0xff002b7f},
11073         {    0,  480,  0.6f, 1, 0xff002b7f},
11074         {  640,  480,  0.6f, 1, 0xff002b7f},
11075     };
11076     const struct tvertex quad3[] =
11077     {
11078         {    0,  100, 0.6f, 1, 0xfff91414},
11079         {  640,  100, 0.6f, 1, 0xfff91414},
11080         {    0,  160, 0.6f, 1, 0xfff91414},
11081         {  640,  160, 0.6f, 1, 0xfff91414},
11082     };
11083
11084     union {
11085         DWORD d;
11086         float f;
11087     } tmpvalue;
11088
11089     IDirect3D9 *d3d = NULL;
11090     IDirect3DSurface9 *offscreen_surface = NULL;
11091     D3DCOLOR color;
11092     HRESULT hr;
11093
11094     IDirect3DDevice9_GetDirect3D(device, &d3d);
11095     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11096             0,  D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK) {
11097         skip("No NVDB (depth bounds test) support\n");
11098         IDirect3D9_Release(d3d);
11099         return;
11100     }
11101     IDirect3D9_Release(d3d);
11102
11103     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
11104             MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
11105     ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
11106     if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
11107
11108     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
11109     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11110
11111     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11112     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11113     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
11114     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11115     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11116     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11117     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11118     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11119
11120
11121     hr = IDirect3DDevice9_BeginScene(device);
11122     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11123
11124     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
11125     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11126
11127     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11128     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11129
11130     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
11131     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11132
11133     tmpvalue.f = 0.625;
11134     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
11135     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11136
11137     tmpvalue.f = 0.75;
11138     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
11139     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11140
11141     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11142     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11143
11144     tmpvalue.f = 0.75;
11145     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
11146     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11147
11148     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11149     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11150
11151     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
11152     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11153
11154     hr = IDirect3DDevice9_EndScene(device);
11155     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11156
11157     color = getPixelColor(device, 150, 130);
11158     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11159     color = getPixelColor(device, 150, 200);
11160     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11161     color = getPixelColor(device, 150, 300-5);
11162     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11163     color = getPixelColor(device, 150, 300+5);
11164     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
11165     color = getPixelColor(device, 150, 330);
11166     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
11167     color = getPixelColor(device, 150, 360-5);
11168     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
11169     color = getPixelColor(device, 150, 360+5);
11170     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11171
11172     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11173     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11174 }
11175
11176 static void depth_buffer_test(IDirect3DDevice9 *device)
11177 {
11178     static const struct vertex quad1[] =
11179     {
11180         { -1.0,  1.0, 0.33f, 0xff00ff00},
11181         {  1.0,  1.0, 0.33f, 0xff00ff00},
11182         { -1.0, -1.0, 0.33f, 0xff00ff00},
11183         {  1.0, -1.0, 0.33f, 0xff00ff00},
11184     };
11185     static const struct vertex quad2[] =
11186     {
11187         { -1.0,  1.0, 0.50f, 0xffff00ff},
11188         {  1.0,  1.0, 0.50f, 0xffff00ff},
11189         { -1.0, -1.0, 0.50f, 0xffff00ff},
11190         {  1.0, -1.0, 0.50f, 0xffff00ff},
11191     };
11192     static const struct vertex quad3[] =
11193     {
11194         { -1.0,  1.0, 0.66f, 0xffff0000},
11195         {  1.0,  1.0, 0.66f, 0xffff0000},
11196         { -1.0, -1.0, 0.66f, 0xffff0000},
11197         {  1.0, -1.0, 0.66f, 0xffff0000},
11198     };
11199     static const DWORD expected_colors[4][4] =
11200     {
11201         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11202         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11203         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
11204         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
11205     };
11206
11207     IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
11208     unsigned int i, j;
11209     D3DVIEWPORT9 vp;
11210     D3DCOLOR color;
11211     HRESULT hr;
11212
11213     vp.X = 0;
11214     vp.Y = 0;
11215     vp.Width = 640;
11216     vp.Height = 480;
11217     vp.MinZ = 0.0;
11218     vp.MaxZ = 1.0;
11219
11220     hr = IDirect3DDevice9_SetViewport(device, &vp);
11221     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11222
11223     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11224     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11225     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11226     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11227     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11228     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11229     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11230     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11231     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11232     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11233
11234     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11235     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11236     hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
11237             D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
11238     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11239     hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
11240             D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
11241     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11242     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11243             D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
11244     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11245
11246     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
11247     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11248     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
11249     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11250
11251     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11252     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11253     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11254     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11255
11256     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11257     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11258     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11259     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11260
11261     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11262     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11263     hr = IDirect3DDevice9_BeginScene(device);
11264     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11265     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11266     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11267     hr = IDirect3DDevice9_EndScene(device);
11268     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11269
11270     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11271     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11272     IDirect3DSurface9_Release(backbuffer);
11273     IDirect3DSurface9_Release(rt3);
11274     IDirect3DSurface9_Release(rt2);
11275     IDirect3DSurface9_Release(rt1);
11276
11277     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11278     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11279
11280     hr = IDirect3DDevice9_BeginScene(device);
11281     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11282     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11283     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11284     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11285     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11286     hr = IDirect3DDevice9_EndScene(device);
11287     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11288
11289     for (i = 0; i < 4; ++i)
11290     {
11291         for (j = 0; j < 4; ++j)
11292         {
11293             unsigned int x = 80 * ((2 * j) + 1);
11294             unsigned int y = 60 * ((2 * i) + 1);
11295             color = getPixelColor(device, x, y);
11296             ok(color_match(color, expected_colors[i][j], 0),
11297                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11298         }
11299     }
11300
11301     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11302     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11303 }
11304
11305 /* Test that partial depth copies work the way they're supposed to. The clear
11306  * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
11307  * the following draw should only copy back the part that was modified. */
11308 static void depth_buffer2_test(IDirect3DDevice9 *device)
11309 {
11310     static const struct vertex quad[] =
11311     {
11312         { -1.0,  1.0, 0.66f, 0xffff0000},
11313         {  1.0,  1.0, 0.66f, 0xffff0000},
11314         { -1.0, -1.0, 0.66f, 0xffff0000},
11315         {  1.0, -1.0, 0.66f, 0xffff0000},
11316     };
11317
11318     IDirect3DSurface9 *backbuffer, *rt1, *rt2;
11319     unsigned int i, j;
11320     D3DVIEWPORT9 vp;
11321     D3DCOLOR color;
11322     HRESULT hr;
11323
11324     vp.X = 0;
11325     vp.Y = 0;
11326     vp.Width = 640;
11327     vp.Height = 480;
11328     vp.MinZ = 0.0;
11329     vp.MaxZ = 1.0;
11330
11331     hr = IDirect3DDevice9_SetViewport(device, &vp);
11332     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11333
11334     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11335     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11336     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11337     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11338     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11339     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11340     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11341     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11342     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11343     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11344
11345     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11346             D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
11347     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11348     hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
11349             D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
11350     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11351     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11352     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11353
11354     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11355     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11356     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11357     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11358
11359     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11360     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11361     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
11362     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11363
11364     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11365     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11366     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11367     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11368
11369     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11370     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11371     IDirect3DSurface9_Release(backbuffer);
11372     IDirect3DSurface9_Release(rt2);
11373     IDirect3DSurface9_Release(rt1);
11374
11375     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11376     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11377
11378     hr = IDirect3DDevice9_BeginScene(device);
11379     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11380     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11381     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11382     hr = IDirect3DDevice9_EndScene(device);
11383     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11384
11385     for (i = 0; i < 4; ++i)
11386     {
11387         for (j = 0; j < 4; ++j)
11388         {
11389             unsigned int x = 80 * ((2 * j) + 1);
11390             unsigned int y = 60 * ((2 * i) + 1);
11391             color = getPixelColor(device, x, y);
11392             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
11393                     "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
11394         }
11395     }
11396
11397     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11398     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11399 }
11400
11401 static void depth_blit_test(IDirect3DDevice9 *device)
11402 {
11403     static const struct vertex quad1[] =
11404     {
11405         { -1.0,  1.0, 0.50f, 0xff00ff00},
11406         {  1.0,  1.0, 0.50f, 0xff00ff00},
11407         { -1.0, -1.0, 0.50f, 0xff00ff00},
11408         {  1.0, -1.0, 0.50f, 0xff00ff00},
11409     };
11410     static const struct vertex quad2[] =
11411     {
11412         { -1.0,  1.0, 0.66f, 0xff0000ff},
11413         {  1.0,  1.0, 0.66f, 0xff0000ff},
11414         { -1.0, -1.0, 0.66f, 0xff0000ff},
11415         {  1.0, -1.0, 0.66f, 0xff0000ff},
11416     };
11417     static const DWORD expected_colors[4][4] =
11418     {
11419         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11420         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11421         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
11422         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
11423     };
11424
11425     IDirect3DSurface9 *backbuffer, *ds1, *ds2, *ds3;
11426     RECT src_rect, dst_rect;
11427     unsigned int i, j;
11428     D3DVIEWPORT9 vp;
11429     D3DCOLOR color;
11430     HRESULT hr;
11431
11432     vp.X = 0;
11433     vp.Y = 0;
11434     vp.Width = 640;
11435     vp.Height = 480;
11436     vp.MinZ = 0.0;
11437     vp.MaxZ = 1.0;
11438
11439     hr = IDirect3DDevice9_SetViewport(device, &vp);
11440     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11441
11442     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11443     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11444     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
11445     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11446     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
11447     ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
11448     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
11449     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11450     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 320, 240, D3DFMT_D24S8, 0, 0, FALSE, &ds3, NULL);
11451     ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
11452
11453     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11454     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11455     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11456     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11457     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11458     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11459     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11460     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11461
11462     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11463     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11464     SetRect(&dst_rect, 0, 0, 480, 360);
11465     hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
11466     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11467     SetRect(&dst_rect, 0, 0, 320, 240);
11468     hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
11469     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11470
11471     /* Partial blit. */
11472     SetRect(&src_rect, 0, 0, 320, 240);
11473     SetRect(&dst_rect, 0, 0, 320, 240);
11474     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11475     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11476     /* Flipped. */
11477     SetRect(&src_rect, 0, 0, 640, 480);
11478     SetRect(&dst_rect, 0, 480, 640, 0);
11479     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11480     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11481     /* Full, explicit. */
11482     SetRect(&src_rect, 0, 0, 640, 480);
11483     SetRect(&dst_rect, 0, 0, 640, 480);
11484     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11485     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11486     /* Filtered blit. */
11487     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
11488     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11489     /* Depth -> color blit.*/
11490     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
11491     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11492     IDirect3DSurface9_Release(backbuffer);
11493     /* Full surface, different sizes */
11494     hr = IDirect3DDevice9_StretchRect(device, ds3, NULL, ds1, NULL, D3DTEXF_POINT);
11495     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11496     hr = IDirect3DDevice9_StretchRect(device, ds1, NULL, ds3, NULL, D3DTEXF_POINT);
11497     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11498
11499     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
11500     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11501     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
11502     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11503     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
11504     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11505     IDirect3DSurface9_Release(ds3);
11506     IDirect3DSurface9_Release(ds2);
11507     IDirect3DSurface9_Release(ds1);
11508
11509     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11510     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11511     hr = IDirect3DDevice9_BeginScene(device);
11512     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11513     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11514     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11515     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11516     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11517     hr = IDirect3DDevice9_EndScene(device);
11518     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11519
11520     for (i = 0; i < 4; ++i)
11521     {
11522         for (j = 0; j < 4; ++j)
11523         {
11524             unsigned int x = 80 * ((2 * j) + 1);
11525             unsigned int y = 60 * ((2 * i) + 1);
11526             color = getPixelColor(device, x, y);
11527             ok(color_match(color, expected_colors[i][j], 0),
11528                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11529         }
11530     }
11531
11532     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11533     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11534 }
11535
11536 static void intz_test(IDirect3DDevice9 *device)
11537 {
11538     static const DWORD ps_code[] =
11539     {
11540         0xffff0200,                                                             /* ps_2_0                       */
11541         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
11542         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
11543         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
11544         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
11545         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
11546         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
11547         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
11548         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
11549         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov oC0, r1                  */
11550         0x0000ffff,                                                             /* end                          */
11551     };
11552     struct
11553     {
11554         float x, y, z;
11555         float s, t, p, q;
11556     }
11557     quad[] =
11558     {
11559         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11560         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11561         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11562         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11563     },
11564     half_quad_1[] =
11565     {
11566         { -1.0f,  0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11567         {  1.0f,  0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11568         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11569         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11570     },
11571     half_quad_2[] =
11572     {
11573         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11574         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11575         { -1.0f,  0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11576         {  1.0f,  0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11577     };
11578     struct
11579     {
11580         UINT x, y;
11581         D3DCOLOR color;
11582     }
11583     expected_colors[] =
11584     {
11585         { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11586         {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11587         {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11588         {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11589         { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11590         {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11591         {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11592         {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11593     };
11594
11595     IDirect3DSurface9 *original_ds, *original_rt, *rt;
11596     IDirect3DTexture9 *texture;
11597     IDirect3DPixelShader9 *ps;
11598     IDirect3DSurface9 *ds;
11599     IDirect3D9 *d3d9;
11600     D3DCAPS9 caps;
11601     HRESULT hr;
11602     UINT i;
11603
11604     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11605     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11606     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11607     {
11608         skip("No pixel shader 2.0 support, skipping INTZ test.\n");
11609         return;
11610     }
11611     if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
11612     {
11613         skip("No unconditional NP2 texture support, skipping INTZ test.\n");
11614         return;
11615     }
11616
11617     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11618     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11619
11620     hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11621             D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
11622     if (FAILED(hr))
11623     {
11624         skip("No INTZ support, skipping INTZ test.\n");
11625         return;
11626     }
11627
11628     IDirect3D9_Release(d3d9);
11629
11630     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11631     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11632     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11633     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11634
11635     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
11636             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11637     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11638     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11639             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11640     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11641     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11642     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11643
11644     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11645     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11646     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11647     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11648     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11649     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11650     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11651     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11652     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11653     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11654
11655     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11656     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11657     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11658     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11659     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11660     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11661     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11662     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11663     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11664     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11665
11666     /* Render offscreen, using the INTZ texture as depth buffer */
11667     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11668     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11669     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11670     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11671     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11672     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11673     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11674     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11675
11676     /* Setup the depth/stencil surface. */
11677     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11678     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11679
11680     hr = IDirect3DDevice9_BeginScene(device);
11681     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11682     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11683     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11684     hr = IDirect3DDevice9_EndScene(device);
11685     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11686
11687     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11688     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11689     IDirect3DSurface9_Release(ds);
11690     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11691     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11692     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11693     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11694     hr = IDirect3DDevice9_SetPixelShader(device, ps);
11695     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11696
11697     /* Read the depth values back. */
11698     hr = IDirect3DDevice9_BeginScene(device);
11699     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11700     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11701     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11702     hr = IDirect3DDevice9_EndScene(device);
11703     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11704
11705     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11706     {
11707         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11708         ok(color_match(color, expected_colors[i].color, 1),
11709                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11710                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11711     }
11712
11713     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11714     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11715
11716     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11717     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11718     IDirect3DTexture9_Release(texture);
11719
11720     /* Render onscreen while using the INTZ texture as depth buffer */
11721     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
11722             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11723     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11724     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11725     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11726     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11727     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11728     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11729
11730     /* Setup the depth/stencil surface. */
11731     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11732     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11733
11734     hr = IDirect3DDevice9_BeginScene(device);
11735     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11736     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11737     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11738     hr = IDirect3DDevice9_EndScene(device);
11739     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11740
11741     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11742     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11743     IDirect3DSurface9_Release(ds);
11744     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11745     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11746     hr = IDirect3DDevice9_SetPixelShader(device, ps);
11747     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11748
11749     /* Read the depth values back. */
11750     hr = IDirect3DDevice9_BeginScene(device);
11751     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11752     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11753     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11754     hr = IDirect3DDevice9_EndScene(device);
11755     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11756
11757     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11758     {
11759         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11760         ok(color_match(color, expected_colors[i].color, 1),
11761                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11762                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11763     }
11764
11765     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11766     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11767
11768     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11769     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11770     IDirect3DTexture9_Release(texture);
11771
11772     /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
11773     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
11774             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11775     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11776     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11777
11778     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11779     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11780     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11781     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11782     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11783     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11784
11785     /* Setup the depth/stencil surface. */
11786     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11787     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11788
11789     hr = IDirect3DDevice9_BeginScene(device);
11790     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11791     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
11792     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11793     hr = IDirect3DDevice9_EndScene(device);
11794     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11795
11796     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11797     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11798
11799     hr = IDirect3DDevice9_BeginScene(device);
11800     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11801     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
11802     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11803     hr = IDirect3DDevice9_EndScene(device);
11804     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11805
11806     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11807     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11808     IDirect3DSurface9_Release(ds);
11809     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11810     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11811     hr = IDirect3DDevice9_SetPixelShader(device, ps);
11812     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11813
11814     /* Read the depth values back. */
11815     hr = IDirect3DDevice9_BeginScene(device);
11816     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11817     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11818     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11819     hr = IDirect3DDevice9_EndScene(device);
11820     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11821
11822     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11823     {
11824         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11825         ok(color_match(color, expected_colors[i].color, 1),
11826                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11827                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11828     }
11829
11830     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11831     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11832
11833     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11834     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11835     IDirect3DSurface9_Release(original_ds);
11836     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11837     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11838     IDirect3DTexture9_Release(texture);
11839     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11840     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11841     IDirect3DPixelShader9_Release(ps);
11842
11843     IDirect3DSurface9_Release(original_rt);
11844     IDirect3DSurface9_Release(rt);
11845 }
11846
11847 static void shadow_test(IDirect3DDevice9 *device)
11848 {
11849     static const DWORD ps_code[] =
11850     {
11851         0xffff0200,                                                             /* ps_2_0                       */
11852         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
11853         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
11854         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
11855         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
11856         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
11857         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
11858         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
11859         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
11860         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov 0C0, r1                  */
11861         0x0000ffff,                                                             /* end                          */
11862     };
11863     struct
11864     {
11865         D3DFORMAT format;
11866         const char *name;
11867     }
11868     formats[] =
11869     {
11870         {D3DFMT_D16_LOCKABLE,   "D3DFMT_D16_LOCKABLE"},
11871         {D3DFMT_D32,            "D3DFMT_D32"},
11872         {D3DFMT_D15S1,          "D3DFMT_D15S1"},
11873         {D3DFMT_D24S8,          "D3DFMT_D24S8"},
11874         {D3DFMT_D24X8,          "D3DFMT_D24X8"},
11875         {D3DFMT_D24X4S4,        "D3DFMT_D24X4S4"},
11876         {D3DFMT_D16,            "D3DFMT_D16"},
11877         {D3DFMT_D32F_LOCKABLE,  "D3DFMT_D32F_LOCKABLE"},
11878         {D3DFMT_D24FS8,         "D3DFMT_D24FS8"},
11879     };
11880     struct
11881     {
11882         float x, y, z;
11883         float s, t, p, q;
11884     }
11885     quad[] =
11886     {
11887         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
11888         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
11889         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
11890         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
11891     };
11892     struct
11893     {
11894         UINT x, y;
11895         D3DCOLOR color;
11896     }
11897     expected_colors[] =
11898     {
11899         {400,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11900         {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11901         {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11902         {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11903         {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11904         { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11905         { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11906         {240,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11907     };
11908
11909     IDirect3DSurface9 *original_ds, *original_rt, *rt;
11910     IDirect3DPixelShader9 *ps;
11911     IDirect3D9 *d3d9;
11912     D3DCAPS9 caps;
11913     HRESULT hr;
11914     UINT i;
11915
11916     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11917     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11918     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11919     {
11920         skip("No pixel shader 2.0 support, skipping shadow test.\n");
11921         return;
11922     }
11923
11924     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11925     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11926     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11927     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11928     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11929     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11930
11931     hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
11932             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11933     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11934     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11935     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11936
11937     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11938     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11939     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11940     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11941     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11942     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11943     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11944     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11945     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11946     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11947
11948     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11949     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11950     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11951     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11952     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11953     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11954     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11955     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11956     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11957     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11958
11959     for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
11960     {
11961         D3DFORMAT format = formats[i].format;
11962         IDirect3DTexture9 *texture;
11963         IDirect3DSurface9 *ds;
11964         unsigned int j;
11965
11966         hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11967                 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
11968         if (FAILED(hr)) continue;
11969
11970         hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
11971                 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
11972         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11973
11974         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11975         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11976
11977         hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11978         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11979
11980         hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11981         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11982
11983         IDirect3DDevice9_SetPixelShader(device, NULL);
11984         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11985
11986         /* Setup the depth/stencil surface. */
11987         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11988         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11989
11990         hr = IDirect3DDevice9_BeginScene(device);
11991         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11992         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11993         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11994         hr = IDirect3DDevice9_EndScene(device);
11995         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11996
11997         hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11998         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11999         IDirect3DSurface9_Release(ds);
12000
12001         hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12002         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12003
12004         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
12005         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12006
12007         hr = IDirect3DDevice9_SetPixelShader(device, ps);
12008         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12009
12010         /* Do the actual shadow mapping. */
12011         hr = IDirect3DDevice9_BeginScene(device);
12012         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12013         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12014         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12015         hr = IDirect3DDevice9_EndScene(device);
12016         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12017
12018         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12019         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12020         IDirect3DTexture9_Release(texture);
12021
12022         for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
12023         {
12024             D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
12025             ok(color_match(color, expected_colors[j].color, 0),
12026                     "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
12027                     expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
12028                     formats[i].name, color);
12029         }
12030
12031         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12032         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12033     }
12034
12035     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12036     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12037     IDirect3DPixelShader9_Release(ps);
12038
12039     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
12040     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12041     IDirect3DSurface9_Release(original_ds);
12042
12043     IDirect3DSurface9_Release(original_rt);
12044     IDirect3DSurface9_Release(rt);
12045
12046     IDirect3D9_Release(d3d9);
12047 }
12048
12049 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
12050 {
12051     const struct vertex quad1[] =
12052     {
12053         {-1.0f, -1.0f, 0.0f, 0xfff9e814},
12054         { 1.0f, -1.0f, 0.0f, 0xfff9e814},
12055         {-1.0f,  1.0f, 0.0f, 0xfff9e814},
12056         { 1.0f,  1.0f, 0.0f, 0xfff9e814},
12057     };
12058     const struct vertex quad2[] =
12059     {
12060         {-1.0f, -1.0f, 0.0f, 0xff002b7f},
12061         { 1.0f, -1.0f, 0.0f, 0xff002b7f},
12062         {-1.0f,  1.0f, 0.0f, 0xff002b7f},
12063         { 1.0f,  1.0f, 0.0f, 0xff002b7f},
12064     };
12065     D3DCOLOR color;
12066     HRESULT hr;
12067
12068     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
12069     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12070
12071     hr = IDirect3DDevice9_BeginScene(device);
12072     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12073
12074     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12075     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12076
12077     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
12078     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12079     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
12080     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12081
12082     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
12083     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12084     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
12085     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12086
12087     hr = IDirect3DDevice9_EndScene(device);
12088     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12089
12090     color = getPixelColor(device, 1, 240);
12091     ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
12092     color = getPixelColor(device, 638, 240);
12093     ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
12094
12095     color = getPixelColor(device, 1, 241);
12096     ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
12097     color = getPixelColor(device, 638, 241);
12098     ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
12099 }
12100
12101 static void clip_planes_test(IDirect3DDevice9 *device)
12102 {
12103     const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
12104
12105     const DWORD shader_code[] = {
12106         0xfffe0200, /* vs_2_0 */
12107         0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
12108         0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
12109         0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
12110         0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
12111         0x0000ffff /* end */
12112     };
12113     IDirect3DVertexShader9 *shader;
12114
12115     IDirect3DTexture9 *offscreen = NULL;
12116     IDirect3DSurface9 *offscreen_surface, *original_rt;
12117     HRESULT hr;
12118
12119     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
12120     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
12121
12122     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12123     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12124     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
12125     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12126     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12127     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12128     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
12129     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12130
12131     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12132     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
12133     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12134     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
12135
12136     IDirect3DDevice9_SetClipPlane(device, 0, plane0);
12137
12138     clip_planes(device, "Onscreen FFP");
12139
12140     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
12141     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12142     hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
12143     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12144     hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
12145     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12146
12147     clip_planes(device, "Offscreen FFP");
12148
12149     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12150     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12151
12152     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
12153     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
12154     IDirect3DDevice9_SetVertexShader(device, shader);
12155     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
12156
12157     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12158     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12159
12160     clip_planes(device, "Onscreen vertex shader");
12161
12162     hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
12163     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12164
12165     clip_planes(device, "Offscreen vertex shader");
12166
12167     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12168     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12169
12170     IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
12171     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12172     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
12173     IDirect3DVertexShader9_Release(shader);
12174     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12175     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12176     IDirect3DSurface9_Release(original_rt);
12177     IDirect3DSurface9_Release(offscreen_surface);
12178     IDirect3DTexture9_Release(offscreen);
12179 }
12180
12181 static void fp_special_test(IDirect3DDevice9 *device)
12182 {
12183     static const DWORD vs_header[] =
12184     {
12185         0xfffe0200,                                                             /* vs_2_0                       */
12186         0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0   */
12187         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
12188         0x0200001f, 0x80000005, 0x900f0001,                                     /* dcl_texcoord0 v1             */
12189     };
12190
12191     static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001};         /* log r0.x, v1.x               */
12192     static const DWORD vs_pow[] =
12193             {0x03000020, 0x80010000, 0x90000001, 0x90000001};                   /* pow r0.x, v1.x, v1.x         */
12194     static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001};         /* nrm r0.xyz, v1.x             */
12195     static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001};        /* rcp r0.x, v1.x               */
12196     static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001};        /* rcp r0.x, -v1.x              */
12197     static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001};        /* rsq r0.x, v1.x               */
12198     static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001};        /* rsq r0.x, -v1.x              */
12199     static const DWORD vs_lit[] = {0x02000010, 0x800f0000, 0x90000001,          /* lit r0, v1.xxxx              */
12200             0x02000001, 0x80010000, 0x80aa0000};                                /* mov r0.x, v0.z               */
12201
12202     static const DWORD vs_footer[] =
12203     {
12204         0x03000005, 0x80020000, 0x80000000, 0xa0ff0000,                         /* mul r0.y, r0.x, c0.w         */
12205         0x0300000d, 0x80040000, 0x80000000, 0x80550000,                         /* sge r0.z, r0.x, r0.y         */
12206         0x0300000d, 0x80020000, 0x80e40000, 0x80000000,                         /* sge r0.y, r0, r0.x           */
12207         0x03000005, 0x80040000, 0x80550000, 0x80e40000,                         /* mul r0.z, r0.y, r0           */
12208         0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000,                         /* max r0.w, -r0.z, r0.z        */
12209         0x0300000c, 0x80020000, 0x80000000, 0x80000000,                         /* slt r0.y, r0.x, r0.x         */
12210         0x03000002, 0x80040000, 0x80550000, 0x80550000,                         /* add r0.z, r0.y, r0.y         */
12211         0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000,                         /* slt r0.y, c0.x, r0.w         */
12212         0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000,                         /* max r0.w, -r0.z, r0.z        */
12213         0x03000002, 0x80040000, 0x81550000, 0xa0e40000,                         /* add r0.z, -r0.y, c0          */
12214         0x0300000c, 0x80080000, 0xa0000000, 0x80e40000,                         /* slt r0.w, c0.x, r0           */
12215         0x03000005, 0x80040000, 0x80ff0000, 0x80e40000,                         /* mul r0.z, r0.w, r0           */
12216         0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000,             /* mad r0.y, r0.z, c0, r0       */
12217         0x02000001, 0xe0030000, 0x80e40000,                                     /* mov oT0.xy, r0               */
12218         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
12219         0x0000ffff,                                                             /* end                          */
12220     };
12221
12222     static const struct
12223     {
12224         const char *name;
12225         const DWORD *ops;
12226         DWORD size;
12227         D3DCOLOR r600;
12228         D3DCOLOR nv40;
12229         D3DCOLOR nv50;
12230     }
12231     vs_body[] =
12232     {
12233         /* The basic ideas here are:
12234          *     2.0 * +/-INF == +/-INF
12235          *     NAN != NAN
12236          *
12237          * The vertex shader value is written to the red component, with 0.0
12238          * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
12239          * result in 0x00. The pixel shader value is written to the green
12240          * component, but here 0.0 also results in 0x00. The actual value is
12241          * written to the blue component.
12242          *
12243          * There are considerable differences between graphics cards in how
12244          * these are handled, but pow and nrm never generate INF or NAN. */
12245         {"log",     vs_log,     sizeof(vs_log),     0x00000000, 0x00ff0000, 0x00ff7f00},
12246         {"pow",     vs_pow,     sizeof(vs_pow),     0x000000ff, 0x0000ff00, 0x000000ff},
12247         {"nrm",     vs_nrm,     sizeof(vs_nrm),     0x00ff0000, 0x0000ff00, 0x00ff0000},
12248         {"rcp1",    vs_rcp1,    sizeof(vs_rcp1),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
12249         {"rcp2",    vs_rcp2,    sizeof(vs_rcp2),    0x00000000, 0x00ff0000, 0x00ff7f00},
12250         {"rsq1",    vs_rsq1,    sizeof(vs_rsq1),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
12251         {"rsq2",    vs_rsq2,    sizeof(vs_rsq2),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
12252         {"lit",     vs_lit,     sizeof(vs_lit),     0x00ff0000, 0x00ff0000, 0x00ff0000},
12253     };
12254
12255     static const DWORD ps_code[] =
12256     {
12257         0xffff0200,                                                             /* ps_2_0                       */
12258         0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0   */
12259         0x0200001f, 0x80000000, 0xb0030000,                                     /* dcl t0.xy                    */
12260         0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000,                         /* max r1.x, t0, c0             */
12261         0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000,                         /* min r0.x, t0, c0             */
12262         0x03000002, 0x80010000, 0x80e40000, 0x81e40001,                         /* add r0.x, r0, -r1            */
12263         0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000,             /* mad r1.x, t0, c0.w. -t0      */
12264         0x02000023, 0x80010002, 0x80e40001,                                     /* abs r2.x, r1                 */
12265         0x02000023, 0x80010000, 0x80e40000,                                     /* abs r0.x, r0                 */
12266         0x02000023, 0x80010001, 0xb0e40000,                                     /* abs r1.x, t0                 */
12267         0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000,             /* cmp r2.x, -r2, c0.z, c0      */
12268         0x02000023, 0x80010002, 0x80e40002,                                     /* abs r2.x, r2                 */
12269         0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000,             /* cmp r1.x, -r1, c0.z, c0      */
12270         0x02000023, 0x80010001, 0x80e40001,                                     /* abs r1.x, r1                 */
12271         0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000,             /* cmp r3.x, -r2, c0.z, c0      */
12272         0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000,             /* cmp r2.x, -r1, c0.z, c0      */
12273         0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000,             /* cmp r0.x, -r0, c0.y, c0      */
12274         0x03000005, 0x80010002, 0x80e40002, 0x80e40003,                         /* mul r2.x, r2, r3             */
12275         0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000,             /* cmp r0.x, -r2, c0.z, r0      */
12276         0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000,             /* cmp r0.y, -r1.x, r0.x, c0.x  */
12277         0x02000001, 0x80050000, 0xb0c90000,                                     /* mov r0.xz, t0.yzxw           */
12278         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.w, c0.z               */
12279         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
12280         0x0000ffff,                                                             /* end                          */
12281     };
12282
12283     struct
12284     {
12285         float x, y, z;
12286         float s;
12287     }
12288     quad[] =
12289     {
12290         { -1.0f,  1.0f, 0.0f, 0.0f},
12291         {  1.0f,  1.0f, 1.0f, 0.0f},
12292         { -1.0f, -1.0f, 0.0f, 0.0f},
12293         {  1.0f, -1.0f, 1.0f, 0.0f},
12294     };
12295
12296     IDirect3DPixelShader9 *ps;
12297     UINT body_size = 0;
12298     DWORD *vs_code;
12299     D3DCAPS9 caps;
12300     HRESULT hr;
12301     UINT i;
12302
12303     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12304     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
12305     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
12306     {
12307         skip("No shader model 2.0 support, skipping floating point specials test.\n");
12308         return;
12309     }
12310
12311     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
12312     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12313
12314     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12315     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
12316     IDirect3DDevice9_SetPixelShader(device, ps);
12317     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12318
12319     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12320     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12321
12322     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
12323     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12324
12325     for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
12326     {
12327         if (vs_body[i].size > body_size) body_size = vs_body[i].size;
12328     }
12329
12330     vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
12331     memcpy(vs_code, vs_header, sizeof(vs_header));
12332
12333     for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
12334     {
12335         DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
12336         IDirect3DVertexShader9 *vs;
12337         D3DCOLOR color;
12338
12339         memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
12340         offset += vs_body[i].size / sizeof(*vs_body[i].ops);
12341         memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
12342
12343         hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
12344         ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
12345         IDirect3DDevice9_SetVertexShader(device, vs);
12346         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
12347
12348         hr = IDirect3DDevice9_BeginScene(device);
12349         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12350         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12351         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12352         hr = IDirect3DDevice9_EndScene(device);
12353         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12354
12355         color = getPixelColor(device, 320, 240);
12356         ok(color_match(color, vs_body[i].r600, 1)
12357                 || color_match(color, vs_body[i].nv40, 1)
12358                 || color_match(color, vs_body[i].nv50, 1),
12359                 "Expected color 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
12360                 vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
12361
12362         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12363         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12364
12365         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12366         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
12367         IDirect3DVertexShader9_Release(vs);
12368     }
12369
12370     HeapFree(GetProcessHeap(), 0, vs_code);
12371
12372     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12373     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12374     IDirect3DPixelShader9_Release(ps);
12375 }
12376
12377 static void srgbwrite_format_test(IDirect3DDevice9 *device)
12378 {
12379     IDirect3D9 *d3d;
12380     IDirect3DSurface9 *rt, *backbuffer;
12381     IDirect3DTexture9 *texture;
12382     HRESULT hr;
12383     int i;
12384     DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
12385     static const struct
12386     {
12387         D3DFORMAT fmt;
12388         const char *name;
12389     }
12390     formats[] =
12391     {
12392         { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
12393         { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
12394         { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
12395         { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
12396         { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
12397     };
12398     static const struct
12399     {
12400         float x, y, z;
12401         float u, v;
12402     }
12403     quad[] =
12404     {
12405         {-1.0f,  -1.0f,  0.1f,   0.0f,   0.0f},
12406         {-1.0f,   1.0f,  0.1f,   1.0f,   0.0f},
12407         { 1.0f,  -1.0f,  0.1f,   0.0f,   1.0f},
12408         { 1.0f,   1.0f,  0.1f,   1.0f,   1.0f}
12409     };
12410
12411     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
12412     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12413     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
12414     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12415     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
12416     ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
12417     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12418     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12419     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12420     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12421
12422     for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
12423     {
12424         if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12425                 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
12426         {
12427             skip("Format %s not supported as render target, skipping test.\n",
12428                     formats[i].name);
12429             continue;
12430         }
12431
12432         hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET, formats[i].fmt,
12433                                             D3DPOOL_DEFAULT, &texture, NULL);
12434         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12435         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
12436         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12437
12438         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
12439         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12440         hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12441         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12442         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
12443         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12444
12445         hr = IDirect3DDevice9_BeginScene(device);
12446         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12447         if(SUCCEEDED(hr))
12448         {
12449             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
12450             ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12451             hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
12452             ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12453             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12454             ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
12455
12456             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
12457             ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12458             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
12459             ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12460             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
12461             ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12462             hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12463             ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12464             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12465             ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
12466             hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12467             ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12468
12469             hr = IDirect3DDevice9_EndScene(device);
12470             ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12471         }
12472
12473         IDirect3DSurface9_Release(rt);
12474         IDirect3DTexture9_Release(texture);
12475
12476         color = getPixelColor(device, 360, 240);
12477         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12478                                     D3DUSAGE_QUERY_SRGBWRITE,
12479                                     D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
12480         {
12481             /* Big slop for R5G6B5 */
12482             ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
12483                 formats[i].name, color_srgb, color);
12484         }
12485         else
12486         {
12487             /* Big slop for R5G6B5 */
12488             ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
12489                 formats[i].name, color_rgb, color);
12490         }
12491
12492         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12493         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12494     }
12495
12496     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
12497     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12498
12499     IDirect3D9_Release(d3d);
12500     IDirect3DSurface9_Release(backbuffer);
12501 }
12502
12503 static void ds_size_test(IDirect3DDevice9 *device)
12504 {
12505     IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
12506     HRESULT hr;
12507     DWORD num_passes;
12508     struct
12509     {
12510         float x, y, z;
12511     }
12512     quad[] =
12513     {
12514         {-1.0,  -1.0,   0.0 },
12515         {-1.0,   1.0,   0.0 },
12516         { 1.0,  -1.0,   0.0 },
12517         { 1.0,   1.0,   0.0 }
12518     };
12519
12520     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
12521     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12522     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
12523     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#x.\n", hr);
12524     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
12525     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
12526
12527     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
12528     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12529     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
12530     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12531     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12532     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12533     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12534     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12535     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12536     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12537     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
12538     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#x.\n", hr);
12539     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12540     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12541     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
12542     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12543     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12544     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12545
12546     /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
12547      * but does not change the surface's contents. */
12548     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
12549     ok(SUCCEEDED(hr), "Target clear failed, hr %#x.\n", hr);
12550     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
12551     ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#x.\n", hr);
12552     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
12553     ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#x.\n", hr);
12554
12555     /* Nvidia does not clear the surface(The color is still 0x000000ff), AMD does(the color is 0x00ff0000) */
12556
12557     /* Turning on any depth-related state results in a ValidateDevice failure */
12558     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12559     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12560     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12561     ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12562         "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12563     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12564     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12565     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12566     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12567     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12568     ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12569         "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12570
12571     /* Try to draw with the device in an invalid state */
12572     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12573     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12574     hr = IDirect3DDevice9_BeginScene(device);
12575     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12576     if(SUCCEEDED(hr))
12577     {
12578         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12579         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12580         hr = IDirect3DDevice9_EndScene(device);
12581         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12582
12583         /* Don't check the resulting draw unless we find an app that needs it. On nvidia ValidateDevice
12584          * returns CONFLICTINGRENDERSTATE, so the result is undefined. On AMD d3d seems to assume the
12585          * stored Z buffer value is 0.0 for all pixels, even those that are covered by the depth buffer */
12586     }
12587
12588     hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12589     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12590     hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
12591     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12592     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12593     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12594
12595     IDirect3DSurface9_Release(readback);
12596     IDirect3DSurface9_Release(ds);
12597     IDirect3DSurface9_Release(rt);
12598     IDirect3DSurface9_Release(old_rt);
12599     IDirect3DSurface9_Release(old_ds);
12600 }
12601
12602 static void unbound_sampler_test(IDirect3DDevice9 *device)
12603 {
12604     HRESULT hr;
12605     IDirect3DPixelShader9 *ps, *ps_cube, *ps_volume;
12606     IDirect3DSurface9 *rt, *old_rt;
12607     DWORD color;
12608
12609     static const DWORD ps_code[] =
12610     {
12611         0xffff0200,                                     /* ps_2_0           */
12612         0x0200001f, 0x90000000, 0xa00f0800,             /* dcl_2d s0        */
12613         0x0200001f, 0x80000000, 0xb00f0000,             /* dcl t0           */
12614         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12615         0x02000001, 0x800f0800, 0x80e40000,             /* mov oC0, r0      */
12616         0x0000ffff,                                     /* end              */
12617     };
12618     static const DWORD ps_code_cube[] =
12619     {
12620         0xffff0200,                                     /* ps_2_0           */
12621         0x0200001f, 0x98000000, 0xa00f0800,             /* dcl_cube s0      */
12622         0x0200001f, 0x80000000, 0xb00f0000,             /* dcl t0           */
12623         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12624         0x02000001, 0x800f0800, 0x80e40000,             /* mov oC0, r0      */
12625         0x0000ffff,                                     /* end              */
12626     };
12627     static const DWORD ps_code_volume[] =
12628     {
12629         0xffff0200,                                     /* ps_2_0           */
12630         0x0200001f, 0xa0000000, 0xa00f0800,             /* dcl_volume s0    */
12631         0x0200001f, 0x80000000, 0xb00f0000,             /* dcl t0           */
12632         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12633         0x02000001, 0x800f0800, 0x80e40000,             /* mov oC0, r0      */
12634         0x0000ffff,                                     /* end              */
12635     };
12636
12637     static const struct
12638     {
12639         float x, y, z;
12640         float u, v;
12641     }
12642     quad[] =
12643     {
12644         {-1.0f,  -1.0f,  0.1f,   0.0f,   0.0f},
12645         {-1.0f,   1.0f,  0.1f,   1.0f,   0.0f},
12646         { 1.0f,  -1.0f,  0.1f,   0.0f,   1.0f},
12647         { 1.0f,   1.0f,  0.1f,   1.0f,   1.0f}
12648     };
12649
12650     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12651     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStage failed, %#x.\n", hr);
12652
12653     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12654     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12655     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_cube, &ps_cube);
12656     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12657     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_volume, &ps_volume);
12658     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12659
12660     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
12661     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12662
12663     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12664     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12665
12666     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12667     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12668
12669     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 );
12670     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12671
12672     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x56ffffff, 0, 0);
12673     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
12674
12675     hr = IDirect3DDevice9_SetPixelShader(device, ps);
12676     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12677
12678     hr = IDirect3DDevice9_BeginScene(device);
12679     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12680     if(SUCCEEDED(hr))
12681     {
12682         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12683         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12684
12685         hr = IDirect3DDevice9_EndScene(device);
12686         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12687     }
12688
12689     color = getPixelColorFromSurface(rt, 32, 32);
12690     ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12691
12692     /* Now try with a cube texture */
12693     hr = IDirect3DDevice9_SetPixelShader(device, ps_cube);
12694     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12695
12696     hr = IDirect3DDevice9_BeginScene(device);
12697     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12698     if (SUCCEEDED(hr))
12699     {
12700         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12701         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12702
12703         hr = IDirect3DDevice9_EndScene(device);
12704         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12705     }
12706
12707     color = getPixelColorFromSurface(rt, 32, 32);
12708     ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12709
12710     /* And then with a volume texture */
12711     hr = IDirect3DDevice9_SetPixelShader(device, ps_volume);
12712     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12713
12714     hr = IDirect3DDevice9_BeginScene(device);
12715     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12716     if (SUCCEEDED(hr))
12717     {
12718         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12719         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12720
12721         hr = IDirect3DDevice9_EndScene(device);
12722         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12723     }
12724
12725     color = getPixelColorFromSurface(rt, 32, 32);
12726     ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12727
12728     hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12729     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12730
12731     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12732     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12733
12734     IDirect3DSurface9_Release(rt);
12735     IDirect3DSurface9_Release(old_rt);
12736     IDirect3DPixelShader9_Release(ps);
12737     IDirect3DPixelShader9_Release(ps_cube);
12738     IDirect3DPixelShader9_Release(ps_volume);
12739 }
12740
12741 static void update_surface_test(IDirect3DDevice9 *device)
12742 {
12743     static const BYTE blocks[][8] =
12744     {
12745         {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, /* White */
12746         {0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Red */
12747         {0xe0, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00}, /* Yellow */
12748         {0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Green */
12749         {0xff, 0x07, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Cyan */
12750         {0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Blue */
12751         {0x1f, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Magenta */
12752     };
12753     static const struct
12754     {
12755         UINT x, y;
12756         D3DCOLOR color;
12757     }
12758     expected_colors[] =
12759     {
12760         { 18, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0xff)},
12761         { 57, 240, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff)},
12762         {109, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0xff)},
12763         {184, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
12764         {290, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
12765         {440, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
12766         {584, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
12767     };
12768     static const struct
12769     {
12770         float x, y, z, w;
12771         float u, v;
12772     }
12773     tri[] =
12774     {
12775         {  0.0f, 480.0f, 0.0f,  1.0f,   0.0f, 0.0f},
12776         {  0.0f,   0.0f, 0.0f,  1.0f,   0.0f, 1.0f},
12777         {640.0f, 240.0f, 0.0f, 10.0f, 100.0f, 0.5f},
12778     };
12779     static const RECT rect_2x2 = {0, 0, 2, 2};
12780     static const struct
12781     {
12782         UINT src_level;
12783         UINT dst_level;
12784         const RECT *r;
12785         HRESULT hr;
12786     }
12787     block_size_tests[] =
12788     {
12789         {1, 0, NULL,      D3D_OK},
12790         {0, 1, NULL,      D3DERR_INVALIDCALL},
12791         {5, 4, NULL,      D3DERR_INVALIDCALL},
12792         {4, 5, NULL,      D3DERR_INVALIDCALL},
12793         {4, 5, &rect_2x2, D3DERR_INVALIDCALL},
12794         {5, 5, &rect_2x2, D3D_OK},
12795     };
12796
12797     IDirect3DSurface9 *src_surface, *dst_surface;
12798     IDirect3DTexture9 *src_tex, *dst_tex;
12799     IDirect3D9 *d3d;
12800     UINT count, i;
12801     HRESULT hr;
12802
12803     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
12804     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12805
12806     hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
12807             D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1);
12808     IDirect3D9_Release(d3d);
12809     if (FAILED(hr))
12810     {
12811         skip("DXT1 not supported, skipping test.\n");
12812         return;
12813     }
12814
12815     IDirect3D9_Release(d3d);
12816
12817     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &src_tex, NULL);
12818     ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12819     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &dst_tex, NULL);
12820     ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12821
12822     count = IDirect3DTexture9_GetLevelCount(src_tex);
12823     ok(count == 7, "Got level count %u, expected 7.\n", count);
12824
12825     for (i = 0; i < count; ++i)
12826     {
12827         UINT row_count, block_count, x, y;
12828         D3DSURFACE_DESC desc;
12829         BYTE *row, *block;
12830         D3DLOCKED_RECT r;
12831
12832         hr = IDirect3DTexture9_GetLevelDesc(src_tex, i, &desc);
12833         ok(SUCCEEDED(hr), "Failed to get level desc, hr %#x.\n", hr);
12834
12835         hr = IDirect3DTexture9_LockRect(src_tex, i, &r, NULL, 0);
12836         ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
12837
12838         row_count = ((desc.Height + 3) & ~3) / 4;
12839         block_count = ((desc.Width + 3) & ~3) / 4;
12840         row = r.pBits;
12841
12842         for (y = 0; y < row_count; ++y)
12843         {
12844             block = row;
12845             for (x = 0; x < block_count; ++x)
12846             {
12847                 memcpy(block, blocks[i], sizeof(blocks[i]));
12848                 block += sizeof(blocks[i]);
12849             }
12850             row += r.Pitch;
12851         }
12852
12853         hr = IDirect3DTexture9_UnlockRect(src_tex, i);
12854         ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
12855     }
12856
12857     for (i = 0; i < sizeof(block_size_tests) / sizeof(*block_size_tests); ++i)
12858     {
12859         hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, block_size_tests[i].src_level, &src_surface);
12860         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12861         hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, block_size_tests[i].dst_level, &dst_surface);
12862         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12863
12864         hr = IDirect3DDevice9_UpdateSurface(device, src_surface, block_size_tests[i].r, dst_surface, NULL);
12865         ok(hr == block_size_tests[i].hr, "Update surface returned %#x for test %u, expected %#x.\n",
12866                 hr, i, block_size_tests[i].hr);
12867
12868         IDirect3DSurface9_Release(dst_surface);
12869         IDirect3DSurface9_Release(src_surface);
12870     }
12871
12872     for (i = 0; i < count; ++i)
12873     {
12874         hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, i, &src_surface);
12875         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12876         hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, i, &dst_surface);
12877         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12878
12879         hr = IDirect3DDevice9_UpdateSurface(device, src_surface, NULL, dst_surface, NULL);
12880         ok(SUCCEEDED(hr), "Failed to update surface at level %u, hr %#x.\n", i, hr);
12881
12882         IDirect3DSurface9_Release(dst_surface);
12883         IDirect3DSurface9_Release(src_surface);
12884     }
12885
12886     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12887     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12888     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
12889     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12890     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
12891     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12892     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)dst_tex);
12893     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12894     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12895     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12896     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12897     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12898
12899     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
12900     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12901
12902     hr = IDirect3DDevice9_BeginScene(device);
12903     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12904     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 1, tri, sizeof(*tri));
12905     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12906     hr = IDirect3DDevice9_EndScene(device);
12907     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12908
12909     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
12910     {
12911         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
12912         ok(color_match(color, expected_colors[i].color, 0),
12913                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
12914                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
12915     }
12916
12917     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12918     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12919
12920     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12921     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12922     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
12923     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12924     IDirect3DTexture9_Release(dst_tex);
12925     IDirect3DTexture9_Release(src_tex);
12926 }
12927
12928 static void multisample_get_rtdata_test(IDirect3DDevice9 *device)
12929 {
12930     IDirect3DSurface9 *original_ds, *original_rt, *rt, *readback;
12931     IDirect3D9 *d3d9;
12932     HRESULT hr;
12933
12934     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
12935     ok(SUCCEEDED(hr), "Failed to get d3d9 interface, hr %#x.\n", hr);
12936     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
12937             D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
12938     IDirect3D9_Release(d3d9);
12939     if (FAILED(hr))
12940     {
12941         skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled CopyRects test.\n");
12942         return;
12943     }
12944
12945     hr = IDirect3DDevice9_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
12946             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
12947     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
12948     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_A8R8G8B8,
12949             D3DPOOL_SYSTEMMEM, &readback, NULL);
12950     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
12951
12952     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
12953     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
12954     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
12955     ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
12956
12957     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12958     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
12959     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
12960     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
12961
12962     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
12963     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
12964     hr = IDirect3DDevice9_GetRenderTargetData(device, rt, readback);
12965     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
12966
12967     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
12968     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
12969     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12970     ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
12971
12972     IDirect3DSurface9_Release(original_ds);
12973     IDirect3DSurface9_Release(original_rt);
12974     IDirect3DSurface9_Release(readback);
12975     IDirect3DSurface9_Release(rt);
12976 }
12977
12978 static void multisampled_depth_buffer_test(IDirect3D9 *d3d9)
12979 {
12980     IDirect3DDevice9 *device = 0;
12981     IDirect3DSurface9 *original_rt, *rt, *readback, *ds, *original_ds;
12982     D3DCAPS9 caps;
12983     HRESULT hr;
12984     D3DPRESENT_PARAMETERS present_parameters;
12985     unsigned int i;
12986     static const struct
12987     {
12988         float x, y, z;
12989         D3DCOLOR color;
12990     }
12991     quad_1[] =
12992     {
12993         { -1.0f,  1.0f, 0.0f, 0xffff0000},
12994         {  1.0f,  1.0f, 1.0f, 0xffff0000},
12995         { -1.0f, -1.0f, 0.0f, 0xffff0000},
12996         {  1.0f, -1.0f, 1.0f, 0xffff0000},
12997     },
12998     quad_2[] =
12999     {
13000         { -1.0f,  1.0f, 1.0f, 0xff0000ff},
13001         {  1.0f,  1.0f, 0.0f, 0xff0000ff},
13002         { -1.0f, -1.0f, 1.0f, 0xff0000ff},
13003         {  1.0f, -1.0f, 0.0f, 0xff0000ff},
13004     };
13005     static const struct
13006     {
13007         UINT x, y;
13008         D3DCOLOR color;
13009     }
13010     expected_colors[] =
13011     {
13012         { 80, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13013         {240, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13014         {400, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13015         {560, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13016         { 80, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13017         {240, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13018         {400, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13019         {560, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13020     };
13021
13022     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13023             D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13024     if (FAILED(hr))
13025     {
13026         skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled depth buffer test.\n");
13027         return;
13028     }
13029     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13030             D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13031     if (FAILED(hr))
13032     {
13033         skip("Multisampling not supported for D3DFMT_D24S8, skipping multisampled depth buffer test.\n");
13034         return;
13035     }
13036
13037     ZeroMemory(&present_parameters, sizeof(present_parameters));
13038     present_parameters.Windowed = TRUE;
13039     present_parameters.hDeviceWindow = create_window();
13040     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13041     present_parameters.BackBufferWidth = 640;
13042     present_parameters.BackBufferHeight = 480;
13043     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13044     present_parameters.EnableAutoDepthStencil = TRUE;
13045     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13046     present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
13047
13048     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13049             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
13050             &present_parameters, &device);
13051     ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13052
13053     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13054     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
13055     if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
13056     {
13057         skip("No unconditional NP2 texture support, skipping multisampled depth buffer test.\n");
13058         goto cleanup;
13059     }
13060
13061     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13062             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13063     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13064     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13065             D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13066     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13067
13068     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13069     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13070     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
13071     ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13072
13073     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13074     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13075     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13076     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13077     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13078     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13079     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13080     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13081     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13082     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13083
13084     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13085     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13086
13087     /* Render onscreen and then offscreen */
13088     hr = IDirect3DDevice9_BeginScene(device);
13089     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13090     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
13091     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13092     hr = IDirect3DDevice9_EndScene(device);
13093     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13094
13095     hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, rt, NULL, D3DTEXF_POINT);
13096     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13097     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13098     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13099
13100     hr = IDirect3DDevice9_BeginScene(device);
13101     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13102     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13103     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13104     hr = IDirect3DDevice9_EndScene(device);
13105     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13106
13107     hr = IDirect3DDevice9_StretchRect(device, rt, NULL, readback, NULL, D3DTEXF_POINT);
13108     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13109
13110     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13111     {
13112         D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13113         ok(color_match(color, expected_colors[i].color, 1),
13114                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13115                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13116     }
13117
13118     hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
13119     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13120     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13121     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13122
13123     /* Render offscreen and then onscreen */
13124     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13125     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13126     IDirect3DSurface9_Release(ds);
13127     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13128             D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
13129     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13130     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13131
13132     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13133     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13134
13135     hr = IDirect3DDevice9_BeginScene(device);
13136     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13137     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
13138     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13139     hr = IDirect3DDevice9_EndScene(device);
13140     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13141
13142     hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
13143     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13144     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13145     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13146
13147     hr = IDirect3DDevice9_BeginScene(device);
13148     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13149     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13150     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13151     hr = IDirect3DDevice9_EndScene(device);
13152     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13153
13154     hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
13155     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13156
13157     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13158     {
13159         D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13160         ok(color_match(color, expected_colors[i].color, 1),
13161                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13162                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13163     }
13164
13165     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13166     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13167
13168     IDirect3DSurface9_Release(ds);
13169     IDirect3DSurface9_Release(readback);
13170     IDirect3DSurface9_Release(rt);
13171     IDirect3DSurface9_Release(original_rt);
13172     cleanup_device(device);
13173
13174     ZeroMemory(&present_parameters, sizeof(present_parameters));
13175     present_parameters.Windowed = TRUE;
13176     present_parameters.hDeviceWindow = create_window();
13177     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13178     present_parameters.BackBufferWidth = 640;
13179     present_parameters.BackBufferHeight = 480;
13180     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13181     present_parameters.EnableAutoDepthStencil = TRUE;
13182     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13183     present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
13184
13185     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13186             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
13187             &present_parameters, &device);
13188     ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13189
13190     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
13191     ok(SUCCEEDED(hr), "Failed to clear depth buffer, hr %#x.\n", hr);
13192
13193     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13194             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13195     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13196     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13197             D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13198     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13199     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13200             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
13201     ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
13202
13203     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13204     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13205     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
13206     ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13207     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13208     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13209     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13210     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13211
13212     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13213     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13214     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13215     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13216     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13217     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13218     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13219     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13220     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13221     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13222
13223     /* Render to a multisampled offscreen frame buffer and then blit to
13224      * the onscreen (not multisampled) frame buffer. */
13225     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13226     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13227
13228     hr = IDirect3DDevice9_BeginScene(device);
13229     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13230     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
13231     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13232     hr = IDirect3DDevice9_EndScene(device);
13233     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13234
13235     hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
13236     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13237     hr = IDirect3DDevice9_StretchRect(device, ds, NULL, original_ds, NULL, D3DTEXF_POINT);
13238     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13239
13240     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13241     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13242     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
13243     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13244
13245     hr = IDirect3DDevice9_BeginScene(device);
13246     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13247     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13248     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13249     hr = IDirect3DDevice9_EndScene(device);
13250     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13251
13252     hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
13253     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13254
13255     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13256     {
13257         D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13258         if (i % 4 < 2)
13259             todo_wine ok(color_match(color, expected_colors[i].color, 1),
13260                     "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13261                     expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13262         else
13263             ok(color_match(color, expected_colors[i].color, 1),
13264                     "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13265                     expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13266     }
13267
13268     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13269     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13270
13271     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13272     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13273     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13274     ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
13275
13276     IDirect3DSurface9_Release(original_ds);
13277     IDirect3DSurface9_Release(original_rt);
13278     IDirect3DSurface9_Release(ds);
13279     IDirect3DSurface9_Release(readback);
13280     IDirect3DSurface9_Release(rt);
13281 cleanup:
13282     cleanup_device(device);
13283 }
13284
13285 static void resz_test(IDirect3D9 *d3d9)
13286 {
13287     IDirect3DDevice9 *device = 0;
13288     IDirect3DSurface9 *rt, *original_rt, *ds, *readback, *intz_ds;
13289     D3DCAPS9 caps;
13290     HRESULT hr;
13291     D3DPRESENT_PARAMETERS present_parameters;
13292     unsigned int i;
13293     static const DWORD ps_code[] =
13294     {
13295         0xffff0200,                                                             /* ps_2_0                       */
13296         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
13297         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
13298         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
13299         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
13300         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
13301         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
13302         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
13303         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
13304         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov oC0, r1                  */
13305         0x0000ffff,                                                             /* end                          */
13306     };
13307     struct
13308     {
13309         float x, y, z;
13310         float s, t, p, q;
13311     }
13312     quad[] =
13313     {
13314         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
13315         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
13316         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
13317         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
13318     };
13319     struct
13320     {
13321         UINT x, y;
13322         D3DCOLOR color;
13323     }
13324     expected_colors[] =
13325     {
13326         { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
13327         {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
13328         {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
13329         {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
13330         { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
13331         {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
13332         {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
13333         {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
13334     };
13335     IDirect3DTexture9 *texture;
13336     IDirect3DPixelShader9 *ps;
13337     DWORD value;
13338
13339     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13340             D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13341     if (FAILED(hr))
13342     {
13343         skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
13344         return;
13345     }
13346     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13347             D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13348     if (FAILED(hr))
13349     {
13350         skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
13351         return;
13352     }
13353
13354     hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
13355             D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
13356     if (FAILED(hr))
13357     {
13358         skip("No INTZ support, skipping RESZ test.\n");
13359         return;
13360     }
13361
13362     hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
13363             D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'));
13364     if (FAILED(hr))
13365     {
13366         skip("No RESZ support, skipping RESZ test.\n");
13367         return;
13368     }
13369
13370     ZeroMemory(&present_parameters, sizeof(present_parameters));
13371     present_parameters.Windowed = TRUE;
13372     present_parameters.hDeviceWindow = create_window();
13373     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13374     present_parameters.BackBufferWidth = 640;
13375     present_parameters.BackBufferHeight = 480;
13376     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13377     present_parameters.EnableAutoDepthStencil = FALSE;
13378     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13379     present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
13380
13381     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13382             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
13383     ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13384
13385     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13386     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
13387     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
13388     {
13389         skip("No pixel shader 2.0 support, skipping INTZ test.\n");
13390         cleanup_device(device);
13391         return;
13392     }
13393     if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
13394     {
13395         skip("No unconditional NP2 texture support, skipping INTZ test.\n");
13396         cleanup_device(device);
13397         return;
13398     }
13399
13400     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13401     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13402
13403     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13404             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13405     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13406     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13407             D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
13408     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13409             D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13410     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13411
13412     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
13413             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
13414     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
13415     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
13416     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13417     hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
13418     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13419     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
13420     ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
13421     IDirect3DSurface9_Release(intz_ds);
13422     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13423     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
13424
13425     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
13426     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13427     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13428     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13429     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13430     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13431     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13432     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13433     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13434     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13435
13436     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
13437     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13438     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
13439     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13440     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
13441     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13442     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
13443     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13444     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
13445     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13446
13447     /* Render offscreen (multisampled), blit the depth buffer
13448      * into the INTZ texture and then check its contents */
13449     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13450     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13451     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13452     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13453     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13454     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13455
13456     hr = IDirect3DDevice9_BeginScene(device);
13457     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13458     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13459     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13460
13461     /* The destination depth texture has to be bound to sampler 0 */
13462     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13463     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13464
13465     /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
13466     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
13467     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13468     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13469     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13470     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
13471     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13472     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13473     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13474     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13475     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13476     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13477     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13478     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
13479     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13480
13481     /* The actual multisampled depth buffer resolve happens here */
13482     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13483     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13484     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
13485     ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
13486
13487     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13488     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13489     hr = IDirect3DDevice9_SetPixelShader(device, ps);
13490     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13491
13492     /* Read the depth values back */
13493     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13494     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13495     hr = IDirect3DDevice9_EndScene(device);
13496     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13497
13498     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13499     {
13500         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13501         ok(color_match(color, expected_colors[i].color, 1),
13502                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13503                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13504     }
13505
13506     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13507     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13508
13509     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13510     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13511     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13512     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13513     IDirect3DSurface9_Release(ds);
13514     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13515     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13516     IDirect3DTexture9_Release(texture);
13517     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13518     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13519     IDirect3DPixelShader9_Release(ps);
13520     IDirect3DSurface9_Release(readback);
13521     IDirect3DSurface9_Release(original_rt);
13522     IDirect3DSurface9_Release(rt);
13523     cleanup_device(device);
13524
13525
13526     ZeroMemory(&present_parameters, sizeof(present_parameters));
13527     present_parameters.Windowed = TRUE;
13528     present_parameters.hDeviceWindow = create_window();
13529     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13530     present_parameters.BackBufferWidth = 640;
13531     present_parameters.BackBufferHeight = 480;
13532     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13533     present_parameters.EnableAutoDepthStencil = TRUE;
13534     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13535     present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
13536
13537     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13538             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
13539     ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13540
13541     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13542     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13543     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
13544     ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13545     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13546             D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13547     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13548     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
13549             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
13550     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
13551     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
13552     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13553     hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
13554     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13555     hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
13556     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13557     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
13558     ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
13559     IDirect3DSurface9_Release(intz_ds);
13560     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13561     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
13562
13563     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
13564     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13565     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13566     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13567     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13568     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13569     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13570     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13571     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13572     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13573
13574     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
13575     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13576     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
13577     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13578     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
13579     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13580     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
13581     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13582     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
13583     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13584
13585     /* Render onscreen, blit the depth buffer into the INTZ texture
13586      * and then check its contents */
13587     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13588     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13589     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13590     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13591     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13592     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13593
13594     hr = IDirect3DDevice9_BeginScene(device);
13595     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13596     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13597     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13598     hr = IDirect3DDevice9_EndScene(device);
13599     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13600
13601     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13602     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13603
13604     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
13605     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13606     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13607     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13608     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
13609     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13610     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13611     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13612     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13613     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13614     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13615     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13616     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
13617     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13618
13619     /* The actual multisampled depth buffer resolve happens here */
13620     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13621     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13622     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
13623     ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
13624
13625     hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
13626     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13627     hr = IDirect3DDevice9_SetPixelShader(device, ps);
13628     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13629
13630     /* Read the depth values back */
13631     hr = IDirect3DDevice9_BeginScene(device);
13632     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13633     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13634     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13635     hr = IDirect3DDevice9_EndScene(device);
13636     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13637
13638     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13639     {
13640         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13641         ok(color_match(color, expected_colors[i].color, 1),
13642                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13643                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13644     }
13645
13646     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13647     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13648
13649
13650     /* Test edge cases - try with no texture at all */
13651     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13652     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13653     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13654     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13655
13656     hr = IDirect3DDevice9_BeginScene(device);
13657     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13658     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13659     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13660     hr = IDirect3DDevice9_EndScene(device);
13661     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13662
13663     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13664     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13665
13666     /* With a non-multisampled depth buffer */
13667     IDirect3DSurface9_Release(ds);
13668     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13669             D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
13670
13671     hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
13672     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13673     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13674     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13675     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13676     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13677
13678     hr = IDirect3DDevice9_BeginScene(device);
13679     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13680     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13681     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13682
13683     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13684     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13685
13686     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
13687     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13688     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13689     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13690     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
13691     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13692     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13693     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13694     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13695     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13696     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13697     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13698     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
13699     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13700     hr = IDirect3DDevice9_EndScene(device);
13701     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13702
13703     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13704     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13705
13706     hr = IDirect3DDevice9_SetPixelShader(device, ps);
13707     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13708
13709     /* Read the depth values back. */
13710     hr = IDirect3DDevice9_BeginScene(device);
13711     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13712     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13713     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13714     hr = IDirect3DDevice9_EndScene(device);
13715     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13716
13717     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13718     {
13719         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13720         ok(color_match(color, expected_colors[i].color, 1),
13721                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13722                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13723     }
13724
13725     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13726     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13727
13728     /* Without a current depth-stencil buffer set */
13729     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13730     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13731     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13732     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13733
13734     hr = IDirect3DDevice9_BeginScene(device);
13735     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13736     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13737     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13738     hr = IDirect3DDevice9_EndScene(device);
13739     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13740
13741     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13742     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13743
13744     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13745     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13746     IDirect3DSurface9_Release(ds);
13747     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13748     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13749     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13750     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13751     IDirect3DTexture9_Release(texture);
13752     IDirect3DPixelShader9_Release(ps);
13753     IDirect3DSurface9_Release(readback);
13754     IDirect3DSurface9_Release(original_rt);
13755     cleanup_device(device);
13756 }
13757
13758 START_TEST(visual)
13759 {
13760     IDirect3D9 *d3d9;
13761     IDirect3DDevice9 *device_ptr;
13762     D3DCAPS9 caps;
13763     HRESULT hr;
13764     DWORD color;
13765
13766     d3d9_handle = LoadLibraryA("d3d9.dll");
13767     if (!d3d9_handle)
13768     {
13769         skip("Could not load d3d9.dll\n");
13770         return;
13771     }
13772
13773     device_ptr = init_d3d9();
13774     if (!device_ptr)
13775     {
13776         skip("Creating the device failed\n");
13777         return;
13778     }
13779
13780     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
13781
13782     /* Check for the reliability of the returned data */
13783     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
13784     if(FAILED(hr))
13785     {
13786         skip("Clear failed, can't assure correctness of the test results, skipping\n");
13787         goto cleanup;
13788     }
13789
13790     color = getPixelColor(device_ptr, 1, 1);
13791     if(color !=0x00ff0000)
13792     {
13793         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
13794         goto cleanup;
13795     }
13796     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
13797
13798     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
13799     if(FAILED(hr))
13800     {
13801         skip("Clear failed, can't assure correctness of the test results, skipping\n");
13802         goto cleanup;
13803     }
13804
13805     color = getPixelColor(device_ptr, 639, 479);
13806     if(color != 0x0000ddee)
13807     {
13808         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
13809         goto cleanup;
13810     }
13811     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
13812
13813     /* Now execute the real tests */
13814     depth_clamp_test(device_ptr);
13815     stretchrect_test(device_ptr);
13816     lighting_test(device_ptr);
13817     clear_test(device_ptr);
13818     color_fill_test(device_ptr);
13819     fog_test(device_ptr);
13820     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
13821     {
13822         test_cube_wrap(device_ptr);
13823     } else {
13824         skip("No cube texture support\n");
13825     }
13826     z_range_test(device_ptr);
13827     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
13828     {
13829         maxmip_test(device_ptr);
13830     }
13831     else
13832     {
13833         skip("No mipmap support\n");
13834     }
13835     offscreen_test(device_ptr);
13836     ds_size_test(device_ptr);
13837     alpha_test(device_ptr);
13838     shademode_test(device_ptr);
13839     srgbtexture_test(device_ptr);
13840     release_buffer_test(device_ptr);
13841     float_texture_test(device_ptr);
13842     g16r16_texture_test(device_ptr);
13843     pixelshader_blending_test(device_ptr);
13844     texture_transform_flags_test(device_ptr);
13845     autogen_mipmap_test(device_ptr);
13846     fixed_function_decl_test(device_ptr);
13847     conditional_np2_repeat_test(device_ptr);
13848     fixed_function_bumpmap_test(device_ptr);
13849     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
13850         stencil_cull_test(device_ptr);
13851     } else {
13852         skip("No two sided stencil support\n");
13853     }
13854     pointsize_test(device_ptr);
13855     tssargtemp_test(device_ptr);
13856     np2_stretch_rect_test(device_ptr);
13857     yuv_color_test(device_ptr);
13858     zwriteenable_test(device_ptr);
13859     alphatest_test(device_ptr);
13860     viewport_test(device_ptr);
13861
13862     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
13863     {
13864         test_constant_clamp_vs(device_ptr);
13865         test_compare_instructions(device_ptr);
13866     }
13867     else skip("No vs_1_1 support\n");
13868
13869     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
13870     {
13871         test_mova(device_ptr);
13872         loop_index_test(device_ptr);
13873         sincos_test(device_ptr);
13874         sgn_test(device_ptr);
13875         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
13876             test_vshader_input(device_ptr);
13877             test_vshader_float16(device_ptr);
13878             stream_test(device_ptr);
13879         } else {
13880             skip("No vs_3_0 support\n");
13881         }
13882     }
13883     else skip("No vs_2_0 support\n");
13884
13885     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
13886     {
13887         fog_with_shader_test(device_ptr);
13888     }
13889     else skip("No vs_1_1 and ps_1_1 support\n");
13890
13891     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
13892     {
13893         texbem_test(device_ptr);
13894         texdepth_test(device_ptr);
13895         texkill_test(device_ptr);
13896         x8l8v8u8_test(device_ptr);
13897         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
13898             constant_clamp_ps_test(device_ptr);
13899             cnd_test(device_ptr);
13900             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
13901                 dp2add_ps_test(device_ptr);
13902                 unbound_sampler_test(device_ptr);
13903                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0) && caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
13904                     nested_loop_test(device_ptr);
13905                     pretransformed_varying_test(device_ptr);
13906                     vFace_register_test(device_ptr);
13907                     vpos_register_test(device_ptr);
13908                     multiple_rendertargets_test(device_ptr);
13909                 } else {
13910                     skip("No ps_3_0 or vs_3_0 support\n");
13911                 }
13912             } else {
13913                 skip("No ps_2_0 support\n");
13914             }
13915         }
13916     }
13917     else skip("No ps_1_1 support\n");
13918
13919     texop_test(device_ptr);
13920     texop_range_test(device_ptr);
13921     alphareplicate_test(device_ptr);
13922     dp3_alpha_test(device_ptr);
13923     depth_buffer_test(device_ptr);
13924     depth_buffer2_test(device_ptr);
13925     depth_blit_test(device_ptr);
13926     intz_test(device_ptr);
13927     shadow_test(device_ptr);
13928     fp_special_test(device_ptr);
13929     depth_bounds_test(device_ptr);
13930     srgbwrite_format_test(device_ptr);
13931     clip_planes_test(device_ptr);
13932     update_surface_test(device_ptr);
13933     multisample_get_rtdata_test(device_ptr);
13934
13935     hr = IDirect3DDevice9_GetDirect3D(device_ptr, &d3d9);
13936     ok(SUCCEEDED(hr), "Failed to get d3d9 interface, hr %#x.\n", hr);
13937     cleanup_device(device_ptr);
13938     device_ptr = NULL;
13939
13940     multisampled_depth_buffer_test(d3d9);
13941     resz_test(d3d9);
13942
13943     IDirect3D9_Release(d3d9);
13944
13945 cleanup:
13946     cleanup_device(device_ptr);
13947 }