1 /*
2  * Tests for the D3DX9 texture functions
3  *
4  * Copyright 2009 Tony Wasserka
5  * Copyright 2010 Owen Rudge for CodeWeavers
6  * Copyright 2010 Matteo Bruni for CodeWeavers
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  */
22 
23 #define COBJMACROS
24 #include "wine/test.h"
25 #include "d3dx9tex.h"
26 #include "resources.h"
27 
28 static int has_2d_dxt3, has_2d_dxt5, has_cube_dxt5, has_3d_dxt3;
29 
30 /* 2x2 16-bit dds, no mipmaps */
31 static const unsigned char dds_16bit[] = {
32 0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x08,0x00,0x02,0x00,0x00,0x00,
33 0x02,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
34 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
35 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
36 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
37 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x7c,0x00,0x00,
38 0xe0,0x03,0x00,0x00,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,
39 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
40 0xff,0x7f,0xff,0x7f,0xff,0x7f,0xff,0x7f
41 };
42 
43 /* 2x2 24-bit dds, 2 mipmaps */
44 static const unsigned char dds_24bit[] = {
45 0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x0a,0x00,0x02,0x00,0x00,0x00,
46 0x02,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
47 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
48 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
49 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
50 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0xff,0x00,
51 0x00,0xff,0x00,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x40,0x00,
52 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
53 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
54 };
55 
56 /* 4x4 cube map dds */
57 static const unsigned char dds_cube_map[] = {
58 0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x08,0x00,0x04,0x00,0x00,0x00,
59 0x04,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
60 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
61 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
62 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
63 0x04,0x00,0x00,0x00,0x44,0x58,0x54,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
64 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x00,0x00,
65 0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
66 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50,
67 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x51,
68 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x52,
69 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x53,
70 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x54,
71 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x55
72 };
73 
74 /* 4x4x2 volume map dds, 2 mipmaps */
75 static const unsigned char dds_volume_map[] = {
76 0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x8a,0x00,0x04,0x00,0x00,0x00,
77 0x04,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
78 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
79 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
80 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
81 0x04,0x00,0x00,0x00,0x44,0x58,0x54,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
82 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x40,0x00,
83 0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
84 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50,
85 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50,
86 0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x2f,0x7e,0xcf,0x79,0x01,0x54,0x5c,0x5c,
87 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x84,0xef,0x7b,0xaa,0xab,0xab,0xab
88 };
89 
90 static const unsigned char png_grayscale[] =
91 {
92     0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49,
93     0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00,
94     0x00, 0x00, 0x00, 0x3a, 0x7e, 0x9b, 0x55, 0x00, 0x00, 0x00, 0x0a, 0x49, 0x44,
95     0x41, 0x54, 0x08, 0xd7, 0x63, 0xf8, 0x0f, 0x00, 0x01, 0x01, 0x01, 0x00, 0x1b,
96     0xb6, 0xee, 0x56, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42,
97     0x60, 0x82
98 };
99 
100 #define ADMITTED_ERROR 0.0001f
101 
102 static inline float relative_error(float expected, float got)
103 {
104     return expected == 0.0f ? fabs(expected - got) : fabs(1.0f - got / expected);
105 }
106 
107 #define expect_vec4(expected, got) expect_vec4_(__LINE__, expected, got)
108 static inline void expect_vec4_(unsigned int line, const D3DXVECTOR4 *expected, const D3DXVECTOR4 *got)
109 {
110     ok_(__FILE__, line)(relative_error(expected->x, got->x) < ADMITTED_ERROR
111         && relative_error(expected->y, got->y) < ADMITTED_ERROR
112         && relative_error(expected->z, got->z) < ADMITTED_ERROR
113         && relative_error(expected->w, got->w) < ADMITTED_ERROR,
114         "Expected (%f, %f, %f, %f), got (%f, %f, %f, %f)\n",
115         expected->x, expected->y, expected->z, expected->w,
116         got->x, got->y, got->z, got->w);
117 }
118 
119 static BOOL compare_color(DWORD c1, DWORD c2, BYTE max_diff)
120 {
121     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff)
122         return FALSE;
123     c1 >>= 8; c2 >>= 8;
124     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff)
125         return FALSE;
126     c1 >>= 8; c2 >>= 8;
127     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff)
128         return FALSE;
129     c1 >>= 8; c2 >>= 8;
130     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff)
131         return FALSE;
132     return TRUE;
133 }
134 
135 static BOOL is_autogenmipmap_supported(IDirect3DDevice9 *device, D3DRESOURCETYPE resource_type)
136 {
137     HRESULT hr;
138     D3DCAPS9 caps;
139     IDirect3D9 *d3d9;
140     D3DDISPLAYMODE mode;
141     D3DDEVICE_CREATION_PARAMETERS params;
142 
143     IDirect3DDevice9_GetDeviceCaps(device, &caps);
144     IDirect3DDevice9_GetDirect3D(device, &d3d9);
145     IDirect3DDevice9_GetCreationParameters(device, &params);
146     IDirect3DDevice9_GetDisplayMode(device, 0, &mode);
147 
148     if (!(caps.Caps2 & D3DCAPS2_CANAUTOGENMIPMAP))
149         return FALSE;
150 
151     hr = IDirect3D9_CheckDeviceFormat(d3d9, params.AdapterOrdinal, params.DeviceType,
152         mode.Format, D3DUSAGE_AUTOGENMIPMAP, resource_type, D3DFMT_A8R8G8B8);
153 
154     IDirect3D9_Release(d3d9);
155     return hr == D3D_OK;
156 }
157 
158 static void test_D3DXCheckTextureRequirements(IDirect3DDevice9 *device)
159 {
160     UINT width, height, mipmaps;
161     D3DFORMAT format, expected;
162     D3DCAPS9 caps;
163     HRESULT hr;
164     IDirect3D9 *d3d;
165     D3DDEVICE_CREATION_PARAMETERS params;
166     D3DDISPLAYMODE mode;
167 
168     IDirect3DDevice9_GetDeviceCaps(device, &caps);
169 
170     /* general tests */
171     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
172     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
173 
174     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DX_DEFAULT, NULL, D3DPOOL_DEFAULT);
175     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
176 
177     hr = D3DXCheckTextureRequirements(NULL, NULL, NULL, NULL, D3DX_DEFAULT, NULL, D3DPOOL_DEFAULT);
178     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
179 
180     /* width & height */
181     width = height = D3DX_DEFAULT;
182     hr = D3DXCheckTextureRequirements(device, &width, &height, NULL, 0, NULL, D3DPOOL_DEFAULT);
183     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
184     ok(width == 256, "Returned width %d, expected %d\n", width, 256);
185     ok(height == 256, "Returned height %d, expected %d\n", height, 256);
186 
187     width = D3DX_DEFAULT;
188     hr = D3DXCheckTextureRequirements(device, &width, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
189     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
190     ok(width == 256, "Returned width %d, expected %d\n", width, 256);
191 
192     if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
193         skip("Hardware only supports pow2 textures\n");
194     else
195     {
196         width = 62;
197         hr = D3DXCheckTextureRequirements(device, &width, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
198         ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
199         ok(width == 62, "Returned width %d, expected %d\n", width, 62);
200 
201         width = D3DX_DEFAULT; height = 63;
202         hr = D3DXCheckTextureRequirements(device, &width, &height, NULL, 0, NULL, D3DPOOL_DEFAULT);
203         ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
204         ok(width == height, "Returned width %d, expected %d\n", width, height);
205         ok(height == 63, "Returned height %d, expected %d\n", height, 63);
206     }
207 
208     width = D3DX_DEFAULT; height = 0;
209     hr = D3DXCheckTextureRequirements(device, &width, &height, NULL, 0, NULL, D3DPOOL_DEFAULT);
210     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
211     ok(width == 1, "Returned width %d, expected %d\n", width, 1);
212     ok(height == 1, "Returned height %d, expected %d\n", height, 1);
213 
214     width = 0; height = 0;
215     hr = D3DXCheckTextureRequirements(device, &width, &height, NULL, 0, NULL, D3DPOOL_DEFAULT);
216     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
217     ok(width == 1, "Returned width %d, expected %d\n", width, 1);
218     ok(height == 1, "Returned height %d, expected %d\n", height, 1);
219 
220     width = 0;
221     hr = D3DXCheckTextureRequirements(device, &width, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
222     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
223     ok(width == 1, "Returned width %d, expected %d\n", width, 1);
224 
225     width = 0xFFFFFFFE;
226     hr = D3DXCheckTextureRequirements(device, &width, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
227     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
228     ok(width == caps.MaxTextureWidth, "Returned width %d, expected %d\n", width, caps.MaxTextureWidth);
229 
230     width = caps.MaxTextureWidth-1;
231     hr = D3DXCheckTextureRequirements(device, &width, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
232     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
233     if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
234         ok(width == caps.MaxTextureWidth, "Returned width %d, expected %d\n", width, caps.MaxTextureWidth);
235     else
236         ok(width == caps.MaxTextureWidth-1, "Returned width %d, expected %d\n", width, caps.MaxTextureWidth-1);
237 
238     /* mipmaps */
239     width = 64; height = 63;
240     mipmaps = 9;
241     hr = D3DXCheckTextureRequirements(device, &width, &height, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
242     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
243     ok(mipmaps == 7, "Returned mipmaps %d, expected %d\n", mipmaps, 7);
244 
245     if (!(caps.TextureCaps & D3DPTEXTURECAPS_POW2))
246     {
247         width = 284; height = 137;
248         mipmaps = 20;
249         hr = D3DXCheckTextureRequirements(device, &width, &height, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
250         ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
251         ok(mipmaps == 9, "Returned mipmaps %d, expected %d\n", mipmaps, 9);
252 
253         width = height = 63;
254         mipmaps = 9;
255         hr = D3DXCheckTextureRequirements(device, &width, &height, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
256         ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
257         ok(mipmaps == 6, "Returned mipmaps %d, expected %d\n", mipmaps, 6);
258     }
259     else
260         skip("Skipping some tests, npot2 textures unsupported\n");
261 
262     mipmaps = 20;
263     hr = D3DXCheckTextureRequirements(device, NULL, NULL, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
264     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
265     ok(mipmaps == 9, "Returned mipmaps %d, expected %d\n", mipmaps, 9);
266 
267     mipmaps = 0;
268     hr = D3DXCheckTextureRequirements(device, NULL, NULL, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
269     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
270     ok(mipmaps == 9, "Returned mipmaps %d, expected %d\n", mipmaps, 9);
271 
272     /* mipmaps when D3DUSAGE_AUTOGENMIPMAP is set */
273     if (is_autogenmipmap_supported(device, D3DRTYPE_TEXTURE))
274     {
275         mipmaps = 0;
276         hr = D3DXCheckTextureRequirements(device, NULL, NULL, &mipmaps, D3DUSAGE_AUTOGENMIPMAP, NULL, D3DPOOL_DEFAULT);
277         ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
278         ok(mipmaps == 0, "Returned mipmaps %d, expected %d\n", mipmaps, 0);
279         mipmaps = 1;
280         hr = D3DXCheckTextureRequirements(device, NULL, NULL, &mipmaps, D3DUSAGE_AUTOGENMIPMAP, NULL, D3DPOOL_DEFAULT);
281         ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
282         ok(mipmaps == 1, "Returned mipmaps %d, expected %d\n", mipmaps, 1);
283         mipmaps = 2;
284         hr = D3DXCheckTextureRequirements(device, NULL, NULL, &mipmaps, D3DUSAGE_AUTOGENMIPMAP, NULL, D3DPOOL_DEFAULT);
285         ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
286         ok(mipmaps == 0, "Returned mipmaps %d, expected %d\n", mipmaps, 0);
287         mipmaps = 6;
288         hr = D3DXCheckTextureRequirements(device, NULL, NULL, &mipmaps, D3DUSAGE_AUTOGENMIPMAP, NULL, D3DPOOL_DEFAULT);
289         ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
290         ok(mipmaps == 0, "Returned mipmaps %d, expected %d\n", mipmaps, 0);
291     }
292     else
293         skip("No D3DUSAGE_AUTOGENMIPMAP support for textures\n");
294 
295     /* usage */
296     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DUSAGE_WRITEONLY, NULL, D3DPOOL_DEFAULT);
297     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckTextureRequirements succeeded, but should've failed.\n");
298     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DUSAGE_DONOTCLIP, NULL, D3DPOOL_DEFAULT);
299     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckTextureRequirements succeeded, but should've failed.\n");
300     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DUSAGE_POINTS, NULL, D3DPOOL_DEFAULT);
301     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckTextureRequirements succeeded, but should've failed.\n");
302     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DUSAGE_RTPATCHES, NULL, D3DPOOL_DEFAULT);
303     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckTextureRequirements succeeded, but should've failed.\n");
304     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DUSAGE_NPATCHES, NULL, D3DPOOL_DEFAULT);
305     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckTextureRequirements succeeded, but should've failed.\n");
306 
307     /* format */
308     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
309     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
310 
311     format = D3DFMT_UNKNOWN;
312     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
313     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
314     ok(format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_A8R8G8B8);
315 
316     format = D3DX_DEFAULT;
317     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
318     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
319     ok(format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_A8R8G8B8);
320 
321     format = D3DFMT_R8G8B8;
322     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
323     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
324     ok(format == D3DFMT_X8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_X8R8G8B8);
325 
326     IDirect3DDevice9_GetDirect3D(device, &d3d);
327     IDirect3DDevice9_GetCreationParameters(device, &params);
328     IDirect3DDevice9_GetDisplayMode(device, 0, &mode);
329 
330     if (SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType,
331                                                mode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_R3G3B2)))
332         expected = D3DFMT_R3G3B2;
333     else if (SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType,
334                                                     mode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_X4R4G4B4)))
335         expected = D3DFMT_X4R4G4B4;
336     else if (SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType,
337                                                     mode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_X1R5G5B5)))
338         expected = D3DFMT_X1R5G5B5;
339     else
340         expected = D3DFMT_R5G6B5;
341 
342     format = D3DFMT_R3G3B2;
343     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
344     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
345     ok(format == expected, "Returned format %u, expected %u\n", format, expected);
346 
347     if(SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType,
348                                               mode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_A8R3G3B2)))
349         expected = D3DFMT_A8R3G3B2;
350     else
351         expected = D3DFMT_A8R8G8B8;
352 
353     format = D3DFMT_A8R3G3B2;
354     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
355     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
356     ok(format == expected, "Returned format %u, expected %u\n", format, expected);
357 
358     if(SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType,
359                                               mode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_P8)))
360         expected = D3DFMT_P8;
361     else
362         expected = D3DFMT_A8R8G8B8;
363 
364     format = D3DFMT_P8;
365     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
366     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
367     ok(format == expected, "Returned format %u, expected %u\n", format, expected);
368 
369     if(SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType,
370             mode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, D3DFMT_L8)))
371         expected = D3DFMT_L8;
372     else
373         expected = D3DFMT_X8R8G8B8;
374 
375     format = D3DFMT_L8;
376     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DUSAGE_RENDERTARGET, &format, D3DPOOL_DEFAULT);
377     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
378     ok(format == expected, "Returned format %u, expected %u\n", format, expected);
379 
380     if(SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType,
381             mode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, D3DFMT_L16)))
382         expected = D3DFMT_L16;
383     else
384         expected = D3DFMT_A16B16G16R16;
385 
386     format = D3DFMT_L16;
387     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DUSAGE_RENDERTARGET, &format, D3DPOOL_DEFAULT);
388     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
389     ok(format == expected, "Returned format %u, expected %u\n", format, expected);
390 
391     /* Block-based texture formats and size < block size. */
392     if (has_2d_dxt5)
393     {
394         format = D3DFMT_DXT5;
395         width = 2; height = 2;
396         mipmaps = 1;
397         hr = D3DXCheckTextureRequirements(device, &width, &height, &mipmaps, 0, &format, D3DPOOL_DEFAULT);
398         ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
399         ok(width == 4, "Returned width %d, expected %d\n", width, 4);
400         ok(height == 4, "Returned height %d, expected %d\n", height, 4);
401         ok(mipmaps == 1, "Returned mipmaps %d, expected %d\n", mipmaps, 1);
402         ok(format == D3DFMT_DXT5, "Returned format %u, expected %u\n", format, D3DFMT_DXT5);
403 
404         format = D3DFMT_DXT5;
405         width = 5; height = 5;
406         mipmaps = 1;
407         hr = D3DXCheckTextureRequirements(device, &width, &height, &mipmaps, 0, &format, D3DPOOL_DEFAULT);
408         ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
409         ok(width == 8, "Returned width %d, expected %d\n", width, 8);
410         ok(height == 8, "Returned height %d, expected %d\n", height, 8);
411         ok(mipmaps == 1, "Returned mipmaps %d, expected %d\n", mipmaps, 1);
412         ok(format == D3DFMT_DXT5, "Returned format %u, expected %u\n", format, D3DFMT_DXT5);
413     }
414     else
415     {
416         skip("D3DFMT_DXT5 textures are not supported, skipping a test.\n");
417     }
418 
419     IDirect3D9_Release(d3d);
420 }
421 
422 static void test_D3DXCheckCubeTextureRequirements(IDirect3DDevice9 *device)
423 {
424     UINT size, mipmaps, expected;
425     D3DFORMAT format;
426     D3DCAPS9 caps;
427     HRESULT hr;
428 
429     IDirect3DDevice9_GetDeviceCaps(device, &caps);
430 
431     if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP))
432     {
433         skip("No cube textures support\n");
434         return;
435     }
436 
437     /* general tests */
438     hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
439     ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
440 
441     hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, D3DX_DEFAULT, NULL, D3DPOOL_DEFAULT);
442     ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
443 
444     hr = D3DXCheckCubeTextureRequirements(NULL, NULL, NULL, D3DX_DEFAULT, NULL, D3DPOOL_DEFAULT);
445     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
446 
447     /* size */
448     size = D3DX_DEFAULT;
449     hr = D3DXCheckCubeTextureRequirements(device, &size, NULL, 0, NULL, D3DPOOL_DEFAULT);
450     ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
451     ok(size == 256, "Returned size %d, expected %d\n", size, 256);
452 
453     /* mipmaps */
454     size = 64;
455     mipmaps = 9;
456     hr = D3DXCheckCubeTextureRequirements(device, &size, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
457     ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
458     ok(mipmaps == 7, "Returned mipmaps %d, expected %d\n", mipmaps, 7);
459 
460     size = 284;
461     mipmaps = 20;
462     expected = caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2 ? 10 : 9;
463     expected = caps.TextureCaps & D3DPTEXTURECAPS_MIPCUBEMAP ? expected : 1;
464     hr = D3DXCheckCubeTextureRequirements(device, &size, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
465     ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
466     ok(mipmaps == expected, "Returned mipmaps %d, expected %d\n", mipmaps, expected);
467 
468     size = 63;
469     mipmaps = 9;
470     expected = caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2 ? 7 : 6;
471     expected = caps.TextureCaps & D3DPTEXTURECAPS_MIPCUBEMAP ? expected : 1;
472     hr = D3DXCheckCubeTextureRequirements(device, &size, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
473     ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
474     ok(mipmaps == expected, "Returned mipmaps %d, expected %d\n", mipmaps, expected);
475 
476     mipmaps = 0;
477     hr = D3DXCheckCubeTextureRequirements(device, NULL, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
478     ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
479     ok(mipmaps == 9, "Returned mipmaps %d, expected %d\n", mipmaps, 9);
480 
481     if (is_autogenmipmap_supported(device, D3DRTYPE_CUBETEXTURE))
482     {
483         mipmaps = 3;
484         hr = D3DXCheckCubeTextureRequirements(device, NULL,  &mipmaps, D3DUSAGE_AUTOGENMIPMAP, NULL, D3DPOOL_DEFAULT);
485         ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
486         ok(mipmaps == 0, "Returned mipmaps %d, expected %d\n", mipmaps, 0);
487     }
488     else
489         skip("No D3DUSAGE_AUTOGENMIPMAP support for cube textures\n");
490 
491     /* usage */
492     hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, D3DUSAGE_WRITEONLY, NULL, D3DPOOL_DEFAULT);
493     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckCubeTextureRequirements succeeded, but should've failed.\n");
494     hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, D3DUSAGE_DONOTCLIP, NULL, D3DPOOL_DEFAULT);
495     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckCubeTextureRequirements succeeded, but should've failed.\n");
496     hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, D3DUSAGE_POINTS, NULL, D3DPOOL_DEFAULT);
497     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckCubeTextureRequirements succeeded, but should've failed.\n");
498     hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, D3DUSAGE_RTPATCHES, NULL, D3DPOOL_DEFAULT);
499     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckCubeTextureRequirements succeeded, but should've failed.\n");
500     hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, D3DUSAGE_NPATCHES, NULL, D3DPOOL_DEFAULT);
501     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckCubeTextureRequirements succeeded, but should've failed.\n");
502 
503     /* format */
504     hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
505     ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
506 
507     format = D3DFMT_UNKNOWN;
508     hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
509     ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
510     ok(format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_A8R8G8B8);
511 
512     format = D3DX_DEFAULT;
513     hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
514     ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
515     ok(format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_A8R8G8B8);
516 
517     format = D3DFMT_R8G8B8;
518     hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
519     ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
520     ok(format == D3DFMT_X8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_X8R8G8B8);
521 }
522 
523 static void test_D3DXCheckVolumeTextureRequirements(IDirect3DDevice9 *device)
524 {
525     UINT width, height, depth, mipmaps, expected;
526     D3DFORMAT format;
527     D3DCAPS9 caps;
528     HRESULT hr;
529 
530     IDirect3DDevice9_GetDeviceCaps(device, &caps);
531 
532     if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP) || (caps.MaxVolumeExtent < 256))
533     {
534         skip("Limited or no volume textures support.\n");
535         return;
536     }
537 
538     /* general tests */
539     hr = D3DXCheckVolumeTextureRequirements(device, NULL, NULL, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
540     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
541 
542     hr = D3DXCheckVolumeTextureRequirements(device, NULL, NULL, NULL, NULL, D3DX_DEFAULT, NULL, D3DPOOL_DEFAULT);
543     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
544 
545     hr = D3DXCheckVolumeTextureRequirements(NULL, NULL, NULL, NULL, NULL, D3DX_DEFAULT, NULL, D3DPOOL_DEFAULT);
546     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
547 
548     /* width, height, depth */
549     width = height = depth = D3DX_DEFAULT;
550     hr = D3DXCheckVolumeTextureRequirements(device, &width, &height, &depth, NULL, 0, NULL, D3DPOOL_DEFAULT);
551     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
552     ok(width == 256, "Returned width %d, expected %d\n", width, 256);
553     ok(height == 256, "Returned height %d, expected %d\n", height, 256);
554     ok(depth == 1, "Returned depth %d, expected %d\n", depth, 1);
555 
556     width = D3DX_DEFAULT;
557     hr = D3DXCheckVolumeTextureRequirements(device, &width, NULL, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
558     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
559     ok(width == 256, "Returned width %d, expected %d\n", width, 256);
560 
561     width = D3DX_DEFAULT; height = 0; depth = 0;
562     hr = D3DXCheckVolumeTextureRequirements(device, &width, &height, &depth, NULL, 0, NULL, D3DPOOL_DEFAULT);
563     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
564     ok(width == 1, "Returned width %d, expected %d\n", width, 1);
565     ok(height == 1, "Returned height %d, expected %d\n", height, 1);
566     ok(depth == 1, "Returned height %d, expected %d\n", depth, 1);
567 
568     width = 0; height = 0; depth = 0;
569     hr = D3DXCheckVolumeTextureRequirements(device, &width, &height, &depth, NULL, 0, NULL, D3DPOOL_DEFAULT);
570     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
571     ok(width == 1, "Returned width %d, expected %d\n", width, 1);
572     ok(height == 1, "Returned height %d, expected %d\n", height, 1);
573     ok(depth == 1, "Returned height %d, expected %d\n", depth, 1);
574 
575     width = 0;
576     hr = D3DXCheckVolumeTextureRequirements(device, &width, NULL, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
577     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
578     ok(width == 1, "Returned width %d, expected %d\n", width, 1);
579 
580     width = 0xFFFFFFFE;
581     hr = D3DXCheckVolumeTextureRequirements(device, &width, NULL, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
582     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
583     ok(width == caps.MaxVolumeExtent, "Returned width %d, expected %d\n", width, caps.MaxVolumeExtent);
584 
585     /* format */
586     hr = D3DXCheckVolumeTextureRequirements(device, NULL, NULL, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
587     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
588 
589     format = D3DFMT_UNKNOWN;
590     hr = D3DXCheckVolumeTextureRequirements(device, NULL, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
591     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
592     ok(format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_A8R8G8B8);
593 
594     format = D3DX_DEFAULT;
595     hr = D3DXCheckVolumeTextureRequirements(device, NULL, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
596     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
597     ok(format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_A8R8G8B8);
598 
599     format = D3DFMT_R8G8B8;
600     hr = D3DXCheckVolumeTextureRequirements(device, NULL, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
601     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
602     ok(format == D3DFMT_X8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_X8R8G8B8);
603 
604     format = D3DFMT_DXT3;
605     hr = D3DXCheckVolumeTextureRequirements(device, NULL, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
606     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
607     if (has_3d_dxt3)
608         ok(format == D3DFMT_DXT3, "Returned format %u, expected %u\n", format, D3DFMT_DXT3);
609     else
610         todo_wine ok(format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_A8R8G8B8);
611 
612     /* mipmaps */
613     if (!(caps.TextureCaps & D3DPTEXTURECAPS_MIPVOLUMEMAP))
614     {
615         skip("No volume textures mipmapping support\n");
616         return;
617     }
618 
619     width = height = depth = 64;
620     mipmaps = 9;
621     hr = D3DXCheckVolumeTextureRequirements(device, &width, &height, &depth, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
622     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
623     ok(mipmaps == 7, "Returned mipmaps %d, expected %d\n", mipmaps, 7);
624 
625     width = 284;
626     height = 143;
627     depth = 55;
628     mipmaps = 20;
629     expected = (caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP_POW2 && caps.MaxVolumeExtent >= 512) ? 10 : 9;
630     hr = D3DXCheckVolumeTextureRequirements(device, &width, &height, &depth, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
631     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
632     ok(mipmaps == expected, "Returned mipmaps %d, expected %d\n", mipmaps, expected);
633 
634     mipmaps = 0;
635     hr = D3DXCheckVolumeTextureRequirements(device, NULL, NULL, NULL, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
636     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
637     ok(mipmaps == 9, "Returned mipmaps %d, expected %d\n", mipmaps, 9);
638 
639     /* D3DUSAGE_AUTOGENMIPMAP is never supported for volume textures. */
640     ok(!is_autogenmipmap_supported(device, D3DRTYPE_VOLUMETEXTURE),
641             "D3DUSAGE_AUTOGENMIPMAP is unexpectedly supported on volume textures.\n");
642 }
643 
644 static void test_D3DXCreateTexture(IDirect3DDevice9 *device)
645 {
646     IDirect3DTexture9 *texture;
647     D3DSURFACE_DESC desc;
648     D3DCAPS9 caps;
649     UINT mipmaps;
650     HRESULT hr;
651 
652     IDirect3DDevice9_GetDeviceCaps(device, &caps);
653 
654     hr = D3DXCreateTexture(NULL, 0, 0, 0, 0, D3DX_DEFAULT, D3DPOOL_DEFAULT, NULL);
655     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
656 
657     /* width and height tests */
658 
659     hr = D3DXCreateTexture(device, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, 0, D3DPOOL_DEFAULT, &texture);
660     ok(hr == D3D_OK, "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3D_OK);
661 
662     if (texture)
663     {
664         hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
665         ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
666         ok(desc.Format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", desc.Format, D3DFMT_A8R8G8B8);
667 
668         ok(desc.Width == 256, "Returned width %d, expected %d\n", desc.Width, 256);
669         ok(desc.Height == 256, "Returned height %d, expected %d\n", desc.Height, 256);
670 
671         IDirect3DTexture9_Release(texture);
672     }
673 
674 
675     hr = D3DXCreateTexture(device, 0, 0, 0, 0, 0, D3DPOOL_DEFAULT, &texture);
676     ok(hr == D3D_OK, "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3D_OK);
677 
678     if (texture)
679     {
680         hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
681         ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
682         ok(desc.Format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", desc.Format, D3DFMT_A8R8G8B8);
683 
684         ok(desc.Width == 1, "Returned width %d, expected %d\n", desc.Width, 1);
685         ok(desc.Height == 1, "Returned height %d, expected %d\n", desc.Height, 1);
686 
687         IDirect3DTexture9_Release(texture);
688     }
689 
690 
691     if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
692         skip("Hardware only supports pow2 textures\n");
693     else
694     {
695         hr = D3DXCreateTexture(device, D3DX_DEFAULT, 63, 0, 0, 0, D3DPOOL_DEFAULT, &texture);
696         ok((hr == D3D_OK) ||
697            /* may not work with conditional NPOT */
698            ((hr != D3D_OK) && (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)),
699            "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3D_OK);
700 
701         if (texture)
702         {
703             hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
704             ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
705             ok(desc.Format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", desc.Format, D3DFMT_A8R8G8B8);
706 
707             /* Conditional NPOT may create a texture with different dimensions, so allow those
708                situations instead of returning a fail */
709 
710             ok(desc.Width == 63 ||
711                (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL),
712                "Returned width %d, expected %d\n", desc.Width, 63);
713 
714             ok(desc.Height == 63 ||
715                (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL),
716                "Returned height %d, expected %d\n", desc.Height, 63);
717 
718             IDirect3DTexture9_Release(texture);
719         }
720     }
721 
722     /* mipmaps */
723 
724     hr = D3DXCreateTexture(device, 64, 63, 9, 0, 0, D3DPOOL_DEFAULT, &texture);
725     ok(hr == D3D_OK, "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3D_OK);
726 
727     if (texture)
728     {
729         mipmaps = IDirect3DTexture9_GetLevelCount(texture);
730         ok(mipmaps == 7, "Returned mipmaps %d, expected %d\n", mipmaps, 7);
731 
732         IDirect3DTexture9_Release(texture);
733     }
734 
735 
736     hr = D3DXCreateTexture(device, 284, 137, 9, 0, 0, D3DPOOL_DEFAULT, &texture);
737     ok(hr == D3D_OK, "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3D_OK);
738 
739     if (texture)
740     {
741         mipmaps = IDirect3DTexture9_GetLevelCount(texture);
742         ok(mipmaps == 9, "Returned mipmaps %d, expected %d\n", mipmaps, 9);
743 
744         IDirect3DTexture9_Release(texture);
745     }
746 
747 
748     hr = D3DXCreateTexture(device, 0, 0, 20, 0, 0, D3DPOOL_DEFAULT, &texture);
749     ok(hr == D3D_OK, "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3D_OK);
750 
751     if (texture)
752     {
753         mipmaps = IDirect3DTexture9_GetLevelCount(texture);
754         ok(mipmaps == 1, "Returned mipmaps %d, expected %d\n", mipmaps, 1);
755 
756         IDirect3DTexture9_Release(texture);
757     }
758 
759 
760     hr = D3DXCreateTexture(device, 64, 64, 1, 0, 0, D3DPOOL_DEFAULT, &texture);
761     ok(hr == D3D_OK, "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3D_OK);
762 
763     if (texture)
764     {
765         mipmaps = IDirect3DTexture9_GetLevelCount(texture);
766         ok(mipmaps == 1, "Returned mipmaps %d, expected %d\n", mipmaps, 1);
767 
768         IDirect3DTexture9_Release(texture);
769     }
770 
771     /* usage */
772 
773     hr = D3DXCreateTexture(device, 0, 0, 0, D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &texture);
774     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTexture succeeded, but should have failed.\n");
775     hr = D3DXCreateTexture(device, 0, 0, 0, D3DUSAGE_DONOTCLIP, 0, D3DPOOL_DEFAULT, &texture);
776     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTexture succeeded, but should have failed.\n");
777     hr = D3DXCreateTexture(device, 0, 0, 0, D3DUSAGE_POINTS, 0, D3DPOOL_DEFAULT, &texture);
778     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTexture succeeded, but should have failed.\n");
779     hr = D3DXCreateTexture(device, 0, 0, 0, D3DUSAGE_RTPATCHES, 0, D3DPOOL_DEFAULT, &texture);
780     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTexture succeeded, but should have failed.\n");
781     hr = D3DXCreateTexture(device, 0, 0, 0, D3DUSAGE_NPATCHES, 0, D3DPOOL_DEFAULT, &texture);
782     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTexture succeeded, but should have failed.\n");
783 
784     /* format */
785 
786     hr = D3DXCreateTexture(device, 0, 0, 0, 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, &texture);
787     ok(hr == D3D_OK, "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3D_OK);
788 
789     if (texture)
790     {
791         hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
792         ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
793         ok(desc.Format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", desc.Format, D3DFMT_A8R8G8B8);
794 
795         IDirect3DTexture9_Release(texture);
796     }
797 
798 
799     hr = D3DXCreateTexture(device, 0, 0, 0, 0, 0, D3DPOOL_DEFAULT, &texture);
800     ok(hr == D3D_OK, "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3D_OK);
801 
802     if (texture)
803     {
804         hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
805         ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
806         ok(desc.Format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", desc.Format, D3DFMT_A8R8G8B8);
807 
808         IDirect3DTexture9_Release(texture);
809     }
810 
811     /* D3DXCreateTextureFromResource */
812     hr = D3DXCreateTextureFromResourceA(device, NULL, MAKEINTRESOURCEA(IDB_BITMAP_1x1), &texture);
813     ok(hr == D3D_OK, "D3DXCreateTextureFromResource returned %#x, expected %#x\n", hr, D3D_OK);
814     if (SUCCEEDED(hr)) IDirect3DTexture9_Release(texture);
815 
816     hr = D3DXCreateTextureFromResourceA(device, NULL, MAKEINTRESOURCEA(IDD_BITMAPDATA_1x1), &texture);
817     ok(hr == D3D_OK, "D3DXCreateTextureFromResource returned %#x, expected %#x\n", hr, D3D_OK);
818     if (SUCCEEDED(hr)) IDirect3DTexture9_Release(texture);
819 
820     hr = D3DXCreateTextureFromResourceA(device, NULL, MAKEINTRESOURCEA(IDS_STRING), &texture);
821     ok(hr == D3DXERR_INVALIDDATA, "D3DXCreateTextureFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
822 
823     hr = D3DXCreateTextureFromResourceA(NULL, NULL, MAKEINTRESOURCEA(IDD_BITMAPDATA_1x1), &texture);
824     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTextureFromResource returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
825 
826     hr = D3DXCreateTextureFromResourceA(device, NULL, NULL, &texture);
827     ok(hr == D3DXERR_INVALIDDATA, "D3DXCreateTextureFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
828 
829     hr = D3DXCreateTextureFromResourceA(device, NULL, MAKEINTRESOURCEA(IDD_BITMAPDATA_1x1), NULL);
830     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTextureFromResource returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
831 
832 
833     /* D3DXCreateTextureFromResourceEx */
834     hr = D3DXCreateTextureFromResourceExA(device, NULL, MAKEINTRESOURCEA(IDD_BITMAPDATA_1x1), D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texture);
835     ok(hr == D3D_OK, "D3DXCreateTextureFromResourceEx returned %#x, expected %#x\n", hr, D3D_OK);
836     if (SUCCEEDED(hr)) IDirect3DTexture9_Release(texture);
837 
838     hr = D3DXCreateTextureFromResourceExA(device, NULL, MAKEINTRESOURCEA(IDS_STRING), D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texture);
839     ok(hr == D3DXERR_INVALIDDATA, "D3DXCreateTextureFromResourceEx returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
840 
841     hr = D3DXCreateTextureFromResourceExA(NULL, NULL, MAKEINTRESOURCEA(IDD_BITMAPDATA_1x1), D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texture);
842     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTextureFromResourceEx returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
843 
844     hr = D3DXCreateTextureFromResourceExA(device, NULL, NULL, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texture);
845     ok(hr == D3DXERR_INVALIDDATA, "D3DXCreateTextureFromResourceEx returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
846 
847     hr = D3DXCreateTextureFromResourceExA(device, NULL, MAKEINTRESOURCEA(IDD_BITMAPDATA_1x1), D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, NULL);
848     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTextureFromResourceEx returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
849 }
850 
851 static void test_D3DXFilterTexture(IDirect3DDevice9 *device)
852 {
853     IDirect3DTexture9 *tex;
854     IDirect3DCubeTexture9 *cubetex;
855     IDirect3DVolumeTexture9 *voltex;
856     HRESULT hr;
857 
858     hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 5, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex, NULL);
859 
860     if (SUCCEEDED(hr))
861     {
862         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, D3DX_DEFAULT, D3DX_FILTER_NONE);
863         ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
864 
865         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_NONE);
866         ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
867 
868         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_BOX + 1); /* Invalid filter */
869         ok(hr == D3DERR_INVALIDCALL, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
870 
871         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 5, D3DX_FILTER_NONE); /* Invalid miplevel */
872         ok(hr == D3DERR_INVALIDCALL, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
873 
874         IDirect3DTexture9_Release(tex);
875     }
876     else
877         skip("Failed to create texture\n");
878 
879     hr = D3DXFilterTexture(NULL, NULL, 0, D3DX_FILTER_NONE);
880     ok(hr == D3DERR_INVALIDCALL, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
881 
882     /* Test different pools */
883     hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &tex, NULL);
884 
885     if (SUCCEEDED(hr))
886     {
887         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_NONE);
888         ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
889         IDirect3DTexture9_Release(tex);
890     }
891     else
892         skip("Failed to create texture\n");
893 
894     hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &tex, NULL);
895 
896     if (SUCCEEDED(hr))
897     {
898         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_NONE);
899         ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
900         IDirect3DTexture9_Release(tex);
901     }
902     else
903         skip("Failed to create texture\n");
904 
905     hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex, NULL);
906     if (SUCCEEDED(hr))
907     {
908         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_POINT);
909         ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
910         IDirect3DTexture9_Release(tex);
911     }
912     else
913         skip("Failed to create texture\n");
914 
915     hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 0, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex, NULL);
916     if (SUCCEEDED(hr))
917     {
918         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_POINT);
919         ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
920         IDirect3DTexture9_Release(tex);
921     }
922     else
923         skip("Failed to create texture\n");
924 
925     /* Cube texture test */
926     hr = IDirect3DDevice9_CreateCubeTexture(device, 256, 5, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &cubetex, NULL);
927 
928     if (SUCCEEDED(hr))
929     {
930         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) cubetex, NULL, 0, D3DX_FILTER_NONE);
931         ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
932 
933         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) cubetex, NULL, 0, D3DX_FILTER_BOX + 1); /* Invalid filter */
934         ok(hr == D3DERR_INVALIDCALL, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
935 
936         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) cubetex, NULL, 5, D3DX_FILTER_NONE); /* Invalid miplevel */
937         ok(hr == D3DERR_INVALIDCALL, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
938         IDirect3DCubeTexture9_Release(cubetex);
939     }
940     else
941         skip("Failed to create texture\n");
942 
943     /* Volume texture test */
944     hr = IDirect3DDevice9_CreateVolumeTexture(device, 256, 256, 4, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &voltex, NULL);
945     if (SUCCEEDED(hr))
946     {
947         DWORD level_count = IDirect3DVolumeTexture9_GetLevelCount(voltex);
948 
949         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) voltex, NULL, 0, D3DX_FILTER_NONE);
950         ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
951 
952         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) voltex, NULL, 0, D3DX_DEFAULT);
953         ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
954 
955         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) voltex, NULL, 0, D3DX_FILTER_BOX);
956         ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
957 
958         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) voltex, NULL, level_count - 1, D3DX_DEFAULT);
959         ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
960 
961         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) voltex, NULL, level_count, D3DX_DEFAULT);
962         ok(hr == D3DERR_INVALIDCALL, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
963 
964         IDirect3DVolumeTexture9_Release(voltex);
965     }
966     else
967         skip("Failed to create volume texture\n");
968 
969     /* Test textures with D3DUSAGE_AUTOGENMIPMAP usage */
970     if (!is_autogenmipmap_supported(device, D3DRTYPE_TEXTURE))
971     {
972         skip("No D3DUSAGE_AUTOGENMIPMAP supported for textures\n");
973         return;
974     }
975 
976     hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 0, D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex, NULL);
977     if (SUCCEEDED(hr))
978     {
979         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_NONE);
980         ok(hr == D3D_OK, "D3dXFilteTexture returned %#x, expected %#x\n", hr, D3D_OK);
981         IDirect3DTexture9_Release(tex);
982     }
983     else
984         skip("Failed to create texture\n");
985 
986     hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex, NULL);
987     if (SUCCEEDED(hr))
988     {
989         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_NONE);
990         ok(hr == D3D_OK, "D3dXFilteTexture returned %#x, expected %#x\n", hr, D3D_OK);
991         IDirect3DTexture9_Release(tex);
992     }
993     else
994         skip("Failed to create texture\n");
995 }
996 
997 static BOOL color_match(const DWORD *value, const DWORD *expected)
998 {
999     int i;
1000 
1001     for (i = 0; i < 4; i++)
1002     {
1003         DWORD diff = value[i] > expected[i] ? value[i] - expected[i] : expected[i] - value[i];
1004         if (diff > 1) return FALSE;
1005     }
1006     return TRUE;
1007 }
1008 
1009 static void WINAPI fillfunc(D3DXVECTOR4 *value, const D3DXVECTOR2 *texcoord,
1010                             const D3DXVECTOR2 *texelsize, void *data)
1011 {
1012     value->x = texcoord->x;
1013     value->y = texcoord->y;
1014     value->z = texelsize->x;
1015     value->w = 1.0f;
1016 }
1017 
1018 static void test_D3DXFillTexture(IDirect3DDevice9 *device)
1019 {
1020     static const struct
1021     {
1022         DWORD usage;
1023         D3DPOOL pool;
1024     }
1025     test_access_types[] =
1026     {
1027         {0,  D3DPOOL_MANAGED},
1028         {0,  D3DPOOL_DEFAULT},
1029         {D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT},
1030     };
1031 
1032     IDirect3DTexture9 *tex;
1033     HRESULT hr;
1034     D3DLOCKED_RECT lock_rect;
1035     DWORD x, y, m;
1036     DWORD v[4], e[4];
1037     DWORD value, expected, size, pitch;
1038     unsigned int i;
1039 
1040     for (i = 0; i < ARRAY_SIZE(test_access_types); ++i)
1041     {
1042         size = 4;
1043         hr = IDirect3DDevice9_CreateTexture(device, size, size, 0, test_access_types[i].usage,
1044                 D3DFMT_A8R8G8B8, test_access_types[i].pool, &tex, NULL);
1045         ok(hr == D3D_OK, "Unexpected hr %#x, i %u.\n", hr, i);
1046 
1047         hr = D3DXFillTexture(tex, fillfunc, NULL);
1048         ok(hr == D3D_OK, "Unexpected hr %#x, i %u.\n", hr, i);
1049 
1050         for (m = 0; m < 3; m++)
1051         {
1052             IDirect3DSurface9 *src_surface, *temp_surface;
1053 
1054             hr = IDirect3DTexture9_GetSurfaceLevel(tex, m, &src_surface);
1055             ok(hr == D3D_OK, "Unexpected hr %#x, i %u, m %u.\n", hr, i, m);
1056             temp_surface = src_surface;
1057 
1058             if (FAILED(hr = IDirect3DSurface9_LockRect(src_surface, &lock_rect, NULL, D3DLOCK_READONLY)))
1059             {
1060                 hr = IDirect3DDevice9_CreateRenderTarget(device, size, size,
1061                         D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &temp_surface, NULL);
1062                 ok(hr == D3D_OK, "Unexpected hr %#x, i %u, m %u.\n", hr, i, m);
1063                 hr = IDirect3DDevice9_StretchRect(device, src_surface, NULL, temp_surface, NULL, D3DTEXF_NONE);
1064                 ok(hr == D3D_OK, "Unexpected hr %#x, i %u, m %u.\n", hr, i, m);
1065                 hr = IDirect3DSurface9_LockRect(temp_surface, &lock_rect, NULL, D3DLOCK_READONLY);
1066                 ok(hr == D3D_OK, "Unexpected hr %#x, i %u, m %u.\n", hr, i, m);
1067             }
1068 
1069             pitch = lock_rect.Pitch / sizeof(DWORD);
1070             for (y = 0; y < size; y++)
1071             {
1072                 for (x = 0; x < size; x++)
1073                 {
1074                     value = ((DWORD *)lock_rect.pBits)[y * pitch + x];
1075                     v[0] = (value >> 24) & 0xff;
1076                     v[1] = (value >> 16) & 0xff;
1077                     v[2] = (value >> 8) & 0xff;
1078                     v[3] = value & 0xff;
1079 
1080                     e[0] = 0xff;
1081                     e[1] = (x + 0.5f) / size * 255.0f + 0.5f;
1082                     e[2] = (y + 0.5f) / size * 255.0f + 0.5f;
1083                     e[3] = 255.0f / size + 0.5f;
1084                     expected = e[0] << 24 | e[1] << 16 | e[2] << 8 | e[3];
1085 
1086                     ok(color_match(v, e),
1087                             "Texel at (%u, %u) doesn't match: %#x, expected %#x, i %u, m %u.\n",
1088                             x, y, value, expected, i, m);
1089                 }
1090             }
1091             IDirect3DSurface9_UnlockRect(temp_surface);
1092             if (temp_surface != src_surface)
1093                 IDirect3DSurface9_Release(temp_surface);
1094             IDirect3DSurface9_Release(src_surface);
1095             size >>= 1;
1096         }
1097         IDirect3DTexture9_Release(tex);
1098     }
1099 
1100     hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, D3DUSAGE_DEPTHSTENCIL,
1101             D3DFMT_D16_LOCKABLE, D3DPOOL_DEFAULT, &tex, NULL);
1102     if (hr == D3D_OK)
1103     {
1104         hr = D3DXFillTexture(tex, fillfunc, NULL);
1105         todo_wine ok(hr == D3D_OK, "Unexpected hr %#x.\n", hr);
1106         IDirect3DTexture9_Release(tex);
1107     }
1108 
1109     hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, D3DUSAGE_DEPTHSTENCIL,
1110             D3DFMT_D16, D3DPOOL_DEFAULT, &tex, NULL);
1111     if (hr == D3D_OK)
1112     {
1113         hr = D3DXFillTexture(tex, fillfunc, NULL);
1114         ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#x.\n", hr);
1115         IDirect3DTexture9_Release(tex);
1116     }
1117 
1118     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_A1R5G5B5,
1119                                         D3DPOOL_MANAGED, &tex, NULL);
1120 
1121     if (SUCCEEDED(hr))
1122     {
1123         hr = D3DXFillTexture(tex, fillfunc, NULL);
1124         ok(hr == D3D_OK, "D3DXFillTexture returned %#x, expected %#x\n", hr, D3D_OK);
1125 
1126         hr = IDirect3DTexture9_LockRect(tex, 0, &lock_rect, NULL, D3DLOCK_READONLY);
1127         ok(hr == D3D_OK, "Couldn't lock the texture, error %#x\n", hr);
1128         if (SUCCEEDED(hr))
1129         {
1130             pitch = lock_rect.Pitch / sizeof(WORD);
1131             for (y = 0; y < 4; y++)
1132             {
1133                 for (x = 0; x < 4; x++)
1134                 {
1135                     value = ((WORD *)lock_rect.pBits)[y * pitch + x];
1136                     v[0] = value >> 15;
1137                     v[1] = value >> 10 & 0x1f;
1138                     v[2] = value >> 5 & 0x1f;
1139                     v[3] = value & 0x1f;
1140 
1141                     e[0] = 1;
1142                     e[1] = (x + 0.5f) / 4.0f * 31.0f + 0.5f;
1143                     e[2] = (y + 0.5f) / 4.0f * 31.0f + 0.5f;
1144                     e[3] = 8;
1145                     expected = e[0] << 15 | e[1] << 10 | e[2] << 5 | e[3];
1146 
1147                     ok(color_match(v, e),
1148                        "Texel at (%u, %u) doesn't match: %#x, expected %#x\n",
1149                        x, y, value, expected);
1150                 }
1151             }
1152             IDirect3DTexture9_UnlockRect(tex, 0);
1153         }
1154 
1155         IDirect3DTexture9_Release(tex);
1156     }
1157     else
1158         skip("Failed to create texture\n");
1159 
1160     /* test floating-point textures */
1161     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_A16B16G16R16F,
1162                                         D3DPOOL_MANAGED, &tex, NULL);
1163 
1164     if (SUCCEEDED(hr))
1165     {
1166         hr = D3DXFillTexture(tex, fillfunc, NULL);
1167         ok(hr == D3D_OK, "D3DXFillTexture returned %#x, expected %#x\n", hr, D3D_OK);
1168 
1169         hr = IDirect3DTexture9_LockRect(tex, 0, &lock_rect, NULL, D3DLOCK_READONLY);
1170         if (SUCCEEDED(hr))
1171         {
1172             pitch = lock_rect.Pitch / sizeof(WORD);
1173             for (y = 0; y < 4; y++)
1174             {
1175                 WORD *ptr = (WORD *)lock_rect.pBits + y * pitch;
1176                 for (x = 0; x < 4; x++)
1177                 {
1178                     D3DXVECTOR4 got, expected;
1179 
1180                     D3DXFloat16To32Array((FLOAT *)&got, (D3DXFLOAT16 *)ptr, 4);
1181                     ptr += 4;
1182 
1183                     expected.x = (x + 0.5f) / 4.0f;
1184                     expected.y = (y + 0.5f) / 4.0f;
1185                     expected.z = 1.0f / 4.0f;
1186                     expected.w = 1.0f;
1187 
1188                     expect_vec4(&expected, &got);
1189                 }
1190             }
1191 
1192             IDirect3DTexture9_UnlockRect(tex, 0);
1193         }
1194         else
1195             skip("Failed to lock texture\n");
1196 
1197         IDirect3DTexture9_Release(tex);
1198     }
1199     else
1200         skip("Failed to create D3DFMT_A16B16G16R16F texture\n");
1201 
1202     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_A32B32G32R32F,
1203                                         D3DPOOL_MANAGED, &tex, NULL);
1204 
1205     if (SUCCEEDED(hr))
1206     {
1207         hr = D3DXFillTexture(tex, fillfunc, NULL);
1208         ok(hr == D3D_OK, "D3DXFillTexture returned %#x, expected %#x\n", hr, D3D_OK);
1209 
1210         hr = IDirect3DTexture9_LockRect(tex, 0, &lock_rect, NULL, D3DLOCK_READONLY);
1211         if (SUCCEEDED(hr))
1212         {
1213             pitch = lock_rect.Pitch / sizeof(float);
1214             for (y = 0; y < 4; y++)
1215             {
1216                 float *ptr = (float *)lock_rect.pBits + y * pitch;
1217                 for (x = 0; x < 4; x++)
1218                 {
1219                     D3DXVECTOR4 got, expected;
1220 
1221                     got.x = *ptr++;
1222                     got.y = *ptr++;
1223                     got.z = *ptr++;
1224                     got.w = *ptr++;
1225 
1226                     expected.x = (x + 0.5f) / 4.0f;
1227                     expected.y = (y + 0.5f) / 4.0f;
1228                     expected.z = 1.0f / 4.0f;
1229                     expected.w = 1.0f;
1230 
1231                     expect_vec4(&expected, &got);
1232                 }
1233             }
1234 
1235             IDirect3DTexture9_UnlockRect(tex, 0);
1236         }
1237         else
1238             skip("Failed to lock texture\n");
1239 
1240         IDirect3DTexture9_Release(tex);
1241     }
1242     else
1243         skip("Failed to create D3DFMT_A32B32G32R32F texture\n");
1244 
1245     /* test a compressed texture */
1246     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_DXT1,
1247                                         D3DPOOL_MANAGED, &tex, NULL);
1248 
1249     if (SUCCEEDED(hr))
1250     {
1251         hr = D3DXFillTexture(tex, fillfunc, NULL);
1252         todo_wine ok(hr == D3D_OK, "D3DXFillTexture returned %#x, expected %#x\n", hr, D3D_OK);
1253 
1254         IDirect3DTexture9_Release(tex);
1255     }
1256     else
1257         skip("Failed to create D3DFMT_DXT1 texture\n");
1258 }
1259 
1260 static void WINAPI fillfunc_cube(D3DXVECTOR4 *value, const D3DXVECTOR3 *texcoord,
1261                                  const D3DXVECTOR3 *texelsize, void *data)
1262 {
1263     value->x = (texcoord->x + 1.0f) / 2.0f;
1264     value->y = (texcoord->y + 1.0f) / 2.0f;
1265     value->z = (texcoord->z + 1.0f) / 2.0f;
1266     value->w = texelsize->x;
1267 }
1268 
1269 enum cube_coord
1270 {
1271     XCOORD = 0,
1272     XCOORDINV = 1,
1273     YCOORD = 2,
1274     YCOORDINV = 3,
1275     ZERO = 4,
1276     ONE = 5
1277 };
1278 
1279 static float get_cube_coord(enum cube_coord coord, unsigned int x, unsigned int y, unsigned int size)
1280 {
1281     switch (coord)
1282     {
1283         case XCOORD:
1284             return x + 0.5f;
1285         case XCOORDINV:
1286             return size - x - 0.5f;
1287         case YCOORD:
1288             return y + 0.5f;
1289         case YCOORDINV:
1290             return size - y - 0.5f;
1291         case ZERO:
1292             return 0.0f;
1293         case ONE:
1294             return size;
1295         default:
1296            trace("Unexpected coordinate value\n");
1297            return 0.0f;
1298     }
1299 }
1300 
1301 static void test_D3DXFillCubeTexture(IDirect3DDevice9 *device)
1302 {
1303     IDirect3DCubeTexture9 *tex;
1304     HRESULT hr;
1305     D3DLOCKED_RECT lock_rect;
1306     DWORD x, y, f, m;
1307     DWORD v[4], e[4];
1308     DWORD value, expected, size, pitch;
1309     enum cube_coord coordmap[6][3] =
1310         {
1311             {ONE, YCOORDINV, XCOORDINV},
1312             {ZERO, YCOORDINV, XCOORD},
1313             {XCOORD, ONE, YCOORD},
1314             {XCOORD, ZERO, YCOORDINV},
1315             {XCOORD, YCOORDINV, ONE},
1316             {XCOORDINV, YCOORDINV, ZERO}
1317         };
1318 
1319     size = 4;
1320     hr = IDirect3DDevice9_CreateCubeTexture(device, size, 0, 0, D3DFMT_A8R8G8B8,
1321                                             D3DPOOL_MANAGED, &tex, NULL);
1322 
1323     if (SUCCEEDED(hr))
1324     {
1325         hr = D3DXFillCubeTexture(tex, fillfunc_cube, NULL);
1326         ok(hr == D3D_OK, "D3DXFillCubeTexture returned %#x, expected %#x\n", hr, D3D_OK);
1327 
1328         for (m = 0; m < 3; m++)
1329         {
1330             for (f = 0; f < 6; f++)
1331             {
1332                 hr = IDirect3DCubeTexture9_LockRect(tex, f, m, &lock_rect, NULL, D3DLOCK_READONLY);
1333                 ok(hr == D3D_OK, "Couldn't lock the texture, error %#x\n", hr);
1334                 if (SUCCEEDED(hr))
1335                 {
1336                     pitch = lock_rect.Pitch / sizeof(DWORD);
1337                     for (y = 0; y < size; y++)
1338                     {
1339                         for (x = 0; x < size; x++)
1340                         {
1341                             value = ((DWORD *)lock_rect.pBits)[y * pitch + x];
1342                             v[0] = (value >> 24) & 0xff;
1343                             v[1] = (value >> 16) & 0xff;
1344                             v[2] = (value >> 8) & 0xff;
1345                             v[3] = value & 0xff;
1346 
1347                             e[0] = (f == 0) || (f == 1) ?
1348                                 0 : (BYTE)(255.0f / size * 2.0f + 0.5f);
1349                             e[1] = get_cube_coord(coordmap[f][0], x, y, size) / size * 255.0f + 0.5f;
1350                             e[2] = get_cube_coord(coordmap[f][1], x, y, size) / size * 255.0f + 0.5f;
1351                             e[3] = get_cube_coord(coordmap[f][2], x, y, size) / size * 255.0f + 0.5f;
1352                             expected = e[0] << 24 | e[1] << 16 | e[2] << 8 | e[3];
1353 
1354                             ok(color_match(v, e),
1355                                "Texel at face %u (%u, %u) doesn't match: %#x, expected %#x\n",
1356                                f, x, y, value, expected);
1357                         }
1358                     }
1359                     IDirect3DCubeTexture9_UnlockRect(tex, f, m);
1360                 }
1361             }
1362             size >>= 1;
1363         }
1364 
1365         IDirect3DCubeTexture9_Release(tex);
1366     }
1367     else
1368         skip("Failed to create texture\n");
1369 
1370     hr = IDirect3DDevice9_CreateCubeTexture(device, 4, 1, 0, D3DFMT_A1R5G5B5,
1371                                             D3DPOOL_MANAGED, &tex, NULL);
1372 
1373     if (SUCCEEDED(hr))
1374     {
1375         hr = D3DXFillCubeTexture(tex, fillfunc_cube, NULL);
1376         ok(hr == D3D_OK, "D3DXFillTexture returned %#x, expected %#x\n", hr, D3D_OK);
1377         for (f = 0; f < 6; f++)
1378         {
1379             hr = IDirect3DCubeTexture9_LockRect(tex, f, 0, &lock_rect, NULL, D3DLOCK_READONLY);
1380             ok(hr == D3D_OK, "Couldn't lock the texture, error %#x\n", hr);
1381             if (SUCCEEDED(hr))
1382             {
1383                 pitch = lock_rect.Pitch / sizeof(WORD);
1384                 for (y = 0; y < 4; y++)
1385                 {
1386                     for (x = 0; x < 4; x++)
1387                     {
1388                         value = ((WORD *)lock_rect.pBits)[y * pitch + x];
1389                         v[0] = value >> 15;
1390                         v[1] = value >> 10 & 0x1f;
1391                         v[2] = value >> 5 & 0x1f;
1392                         v[3] = value & 0x1f;
1393 
1394                         e[0] = (f == 0) || (f == 1) ?
1395                             0 : (BYTE)(1.0f / size * 2.0f + 0.5f);
1396                         e[1] = get_cube_coord(coordmap[f][0], x, y, 4) / 4 * 31.0f + 0.5f;
1397                         e[2] = get_cube_coord(coordmap[f][1], x, y, 4) / 4 * 31.0f + 0.5f;
1398                         e[3] = get_cube_coord(coordmap[f][2], x, y, 4) / 4 * 31.0f + 0.5f;
1399                         expected = e[0] << 15 | e[1] << 10 | e[2] << 5 | e[3];
1400 
1401                         ok(color_match(v, e),
1402                            "Texel at face %u (%u, %u) doesn't match: %#x, expected %#x\n",
1403                            f, x, y, value, expected);
1404                     }
1405                 }
1406                 IDirect3DCubeTexture9_UnlockRect(tex, f, 0);
1407             }
1408         }
1409 
1410         IDirect3DCubeTexture9_Release(tex);
1411     }
1412     else
1413         skip("Failed to create texture\n");
1414 }
1415 
1416 static void WINAPI fillfunc_volume(D3DXVECTOR4 *value, const D3DXVECTOR3 *texcoord,
1417                                    const D3DXVECTOR3 *texelsize, void *data)
1418 {
1419     value->x = texcoord->x;
1420     value->y = texcoord->y;
1421     value->z = texcoord->z;
1422     value->w = texelsize->x;
1423 }
1424 
1425 static void test_D3DXFillVolumeTexture(IDirect3DDevice9 *device)
1426 {
1427     IDirect3DVolumeTexture9 *tex;
1428     HRESULT hr;
1429     D3DLOCKED_BOX lock_box;
1430     DWORD x, y, z, m;
1431     DWORD v[4], e[4];
1432     DWORD value, expected, size, row_pitch, slice_pitch;
1433 
1434     size = 4;
1435     hr = IDirect3DDevice9_CreateVolumeTexture(device, size, size, size, 0, 0, D3DFMT_A8R8G8B8,
1436             D3DPOOL_DEFAULT, &tex, NULL);
1437     ok(hr == D3D_OK, "Unexpected hr %#x.\n", hr);
1438     hr = D3DXFillVolumeTexture(tex, fillfunc_volume, NULL);
1439     ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#x.\n", hr);
1440     IDirect3DVolumeTexture9_Release(tex);
1441 
1442     hr = IDirect3DDevice9_CreateVolumeTexture(device, size, size, size, 0, 0, D3DFMT_A8R8G8B8,
1443             D3DPOOL_MANAGED, &tex, NULL);
1444     if (SUCCEEDED(hr))
1445     {
1446         hr = D3DXFillVolumeTexture(tex, fillfunc_volume, NULL);
1447         ok(hr == D3D_OK, "D3DXFillVolumeTexture returned %#x, expected %#x\n", hr, D3D_OK);
1448 
1449         for (m = 0; m < 3; m++)
1450         {
1451             hr = IDirect3DVolumeTexture9_LockBox(tex, m, &lock_box, NULL, D3DLOCK_READONLY);
1452             ok(hr == D3D_OK, "Couldn't lock the texture, error %#x\n", hr);
1453             if (SUCCEEDED(hr))
1454             {
1455                 row_pitch = lock_box.RowPitch / sizeof(DWORD);
1456                 slice_pitch = lock_box.SlicePitch / sizeof(DWORD);
1457                 for (z = 0; z < size; z++)
1458                 {
1459                     for (y = 0; y < size; y++)
1460                     {
1461                         for (x = 0; x < size; x++)
1462                         {
1463                             value = ((DWORD *)lock_box.pBits)[z * slice_pitch + y * row_pitch + x];
1464                             v[0] = (value >> 24) & 0xff;
1465                             v[1] = (value >> 16) & 0xff;
1466                             v[2] = (value >> 8) & 0xff;
1467                             v[3] = value & 0xff;
1468 
1469                             e[0] = 255.0f / size + 0.5f;
1470                             e[1] = (x + 0.5f) / size * 255.0f + 0.5f;
1471                             e[2] = (y + 0.5f) / size * 255.0f + 0.5f;
1472                             e[3] = (z + 0.5f) / size * 255.0f + 0.5f;
1473                             expected = e[0] << 24 | e[1] << 16 | e[2] << 8 | e[3];
1474 
1475                             ok(color_match(v, e),
1476                                "Texel at (%u, %u, %u) doesn't match: %#x, expected %#x\n",
1477                                x, y, z, value, expected);
1478                         }
1479                     }
1480                 }
1481                 IDirect3DVolumeTexture9_UnlockBox(tex, m);
1482             }
1483             size >>= 1;
1484         }
1485 
1486         IDirect3DVolumeTexture9_Release(tex);
1487     }
1488     else
1489         skip("Failed to create texture\n");
1490 
1491     hr = IDirect3DDevice9_CreateVolumeTexture(device, 4, 4, 4, 1, 0, D3DFMT_A1R5G5B5,
1492                                               D3DPOOL_MANAGED, &tex, NULL);
1493 
1494     if (SUCCEEDED(hr))
1495     {
1496         hr = D3DXFillVolumeTexture(tex, fillfunc_volume, NULL);
1497         ok(hr == D3D_OK, "D3DXFillTexture returned %#x, expected %#x\n", hr, D3D_OK);
1498         hr = IDirect3DVolumeTexture9_LockBox(tex, 0, &lock_box, NULL, D3DLOCK_READONLY);
1499         ok(hr == D3D_OK, "Couldn't lock the texture, error %#x\n", hr);
1500         if (SUCCEEDED(hr))
1501         {
1502             row_pitch = lock_box.RowPitch / sizeof(WORD);
1503             slice_pitch = lock_box.SlicePitch / sizeof(WORD);
1504             for (z = 0; z < 4; z++)
1505             {
1506                 for (y = 0; y < 4; y++)
1507                 {
1508                     for (x = 0; x < 4; x++)
1509                     {
1510                         value = ((WORD *)lock_box.pBits)[z * slice_pitch + y * row_pitch + x];
1511                         v[0] = value >> 15;
1512                         v[1] = value >> 10 & 0x1f;
1513                         v[2] = value >> 5 & 0x1f;
1514                         v[3] = value & 0x1f;
1515 
1516                         e[0] = 1;
1517                         e[1] = (x + 0.5f) / 4 * 31.0f + 0.5f;
1518                         e[2] = (y + 0.5f) / 4 * 31.0f + 0.5f;
1519                         e[3] = (z + 0.5f) / 4 * 31.0f + 0.5f;
1520                         expected = e[0] << 15 | e[1] << 10 | e[2] << 5 | e[3];
1521 
1522                         ok(color_match(v, e),
1523                            "Texel at (%u, %u, %u) doesn't match: %#x, expected %#x\n",
1524                            x, y, z, value, expected);
1525                     }
1526                 }
1527             }
1528             IDirect3DVolumeTexture9_UnlockBox(tex, 0);
1529         }
1530 
1531         IDirect3DVolumeTexture9_Release(tex);
1532     }
1533     else
1534         skip("Failed to create texture\n");
1535 }
1536 
1537 static void test_D3DXCreateTextureFromFileInMemory(IDirect3DDevice9 *device)
1538 {
1539     HRESULT hr;
1540     IDirect3DTexture9 *texture;
1541     D3DRESOURCETYPE type;
1542     D3DSURFACE_DESC desc;
1543     D3DLOCKED_RECT lock_rect;
1544     int i;
1545     DWORD level_count;
1546 
1547     hr = D3DXCreateTextureFromFileInMemory(device, dds_16bit, sizeof(dds_16bit), &texture);
1548     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
1549     if (SUCCEEDED(hr)) IDirect3DTexture9_Release(texture);
1550 
1551     hr = D3DXCreateTextureFromFileInMemory(device, dds_24bit, sizeof(dds_24bit), &texture);
1552     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
1553     if (SUCCEEDED(hr)) IDirect3DTexture9_Release(texture);
1554 
1555     hr = D3DXCreateTextureFromFileInMemory(device, dds_24bit, sizeof(dds_24bit) - 1, &texture);
1556     ok(hr == D3DXERR_INVALIDDATA, "D3DXCreateTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
1557 
1558     /* Check that D3DXCreateTextureFromFileInMemory accepts cube texture dds file (only first face texture is loaded) */
1559     hr = D3DXCreateTextureFromFileInMemory(device, dds_cube_map, sizeof(dds_cube_map), &texture);
1560     todo_wine_if (!has_2d_dxt5)
1561         ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemory returned %#x, expected %#x.\n", hr, D3D_OK);
1562     if (SUCCEEDED(hr))
1563     {
1564         type = IDirect3DTexture9_GetType(texture);
1565         ok(type == D3DRTYPE_TEXTURE, "IDirect3DTexture9_GetType returned %u, expected %u\n", type, D3DRTYPE_TEXTURE);
1566         hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
1567         ok(hr == D3D_OK, "IDirect3DTexture9_GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
1568         ok(desc.Width == 4, "Width is %u, expected 4\n", desc.Width);
1569         ok(desc.Height == 4, "Height is %u, expected 4\n", desc.Height);
1570         hr = IDirect3DTexture9_LockRect(texture, 0, &lock_rect, NULL, D3DLOCK_READONLY);
1571         ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %#x, expected %#x\n", hr, D3D_OK);
1572         if (SUCCEEDED(hr))
1573         {
1574             for (i = 0; i < 16; i++)
1575                 ok(((BYTE *)lock_rect.pBits)[i] == dds_cube_map[128 + i],
1576                         "Byte at index %u is 0x%02x, expected 0x%02x.\n",
1577                         i, ((BYTE *)lock_rect.pBits)[i], dds_cube_map[128 + i]);
1578             IDirect3DTexture9_UnlockRect(texture, 0);
1579         }
1580         IDirect3DTexture9_Release(texture);
1581 
1582     }
1583 
1584     /* Volume textures work too. */
1585     hr = D3DXCreateTextureFromFileInMemory(device, dds_volume_map, sizeof(dds_volume_map), &texture);
1586     todo_wine_if (!has_2d_dxt3)
1587         ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemory returned %#x, expected %#x.\n", hr, D3D_OK);
1588     if (SUCCEEDED(hr))
1589     {
1590         type = IDirect3DTexture9_GetType(texture);
1591         ok(type == D3DRTYPE_TEXTURE, "IDirect3DTexture9_GetType returned %u, expected %u.\n", type, D3DRTYPE_TEXTURE);
1592         level_count = IDirect3DBaseTexture9_GetLevelCount((IDirect3DBaseTexture9 *)texture);
1593         todo_wine ok(level_count == 3, "Texture has %u mip levels, 3 expected.\n", level_count);
1594         hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
1595         ok(hr == D3D_OK, "IDirect3DTexture9_GetLevelDesc returned %#x, expected %#x.\n", hr, D3D_OK);
1596         ok(desc.Width == 4, "Width is %u, expected 4.\n", desc.Width);
1597         ok(desc.Height == 4, "Height is %u, expected 4.\n", desc.Height);
1598 
1599         hr = IDirect3DTexture9_LockRect(texture, 0, &lock_rect, NULL, D3DLOCK_READONLY);
1600         ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %#x, expected %#x.\n", hr, D3D_OK);
1601         if (SUCCEEDED(hr))
1602         {
1603             for (i = 0; i < 16; ++i)
1604                 ok(((BYTE *)lock_rect.pBits)[i] == dds_volume_map[128 + i],
1605                         "Byte at index %u is 0x%02x, expected 0x%02x.\n",
1606                         i, ((BYTE *)lock_rect.pBits)[i], dds_volume_map[128 + i]);
1607             IDirect3DTexture9_UnlockRect(texture, 0);
1608         }
1609         /* The lower texture levels are apparently generated by filtering the level 0 surface
1610          * I.e. following levels from the file are ignored. */
1611         IDirect3DTexture9_Release(texture);
1612     }
1613 }
1614 
1615 static void test_D3DXCreateTextureFromFileInMemoryEx(IDirect3DDevice9 *device)
1616 {
1617     HRESULT hr;
1618     IDirect3DTexture9 *texture;
1619     unsigned int miplevels;
1620     IDirect3DSurface9 *surface;
1621     D3DSURFACE_DESC desc;
1622 
1623     hr = D3DXCreateTextureFromFileInMemoryEx(device, dds_16bit, sizeof(dds_16bit), D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT,
1624         0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texture);
1625     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x\n", hr, D3D_OK);
1626     IDirect3DTexture9_Release(texture);
1627 
1628     hr = D3DXCreateTextureFromFileInMemoryEx(device, dds_16bit, sizeof(dds_16bit), D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT,
1629         D3DUSAGE_DYNAMIC, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texture);
1630     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x\n", hr, D3D_OK);
1631     IDirect3DTexture9_Release(texture);
1632 
1633     hr = D3DXCreateTextureFromFileInMemoryEx(device, dds_24bit, sizeof(dds_24bit), D3DX_DEFAULT,
1634             D3DX_DEFAULT, D3DX_DEFAULT, D3DUSAGE_DYNAMIC, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT,
1635             D3DX_DEFAULT, D3DX_SKIP_DDS_MIP_LEVELS(1, D3DX_FILTER_POINT), 0, NULL, NULL, &texture);
1636     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x\n", hr, D3D_OK);
1637     miplevels = IDirect3DTexture9_GetLevelCount(texture);
1638     ok(miplevels == 1, "Got miplevels %u, expected %u.\n", miplevels, 1);
1639     IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1640     IDirect3DSurface9_GetDesc(surface, &desc);
1641     ok(desc.Width == 1 && desc.Height == 1,
1642             "Surface dimensions are %ux%u, expected 1x1.\n", desc.Width, desc.Height);
1643     IDirect3DSurface9_Release(surface);
1644     IDirect3DTexture9_Release(texture);
1645 
1646     if (!is_autogenmipmap_supported(device, D3DRTYPE_TEXTURE))
1647     {
1648         skip("No D3DUSAGE_AUTOGENMIPMAP support for textures\n");
1649         return;
1650     }
1651 
1652     hr = D3DXCreateTextureFromFileInMemoryEx(device, dds_16bit, sizeof(dds_16bit), D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT,
1653         D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texture);
1654     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x\n", hr, D3D_OK);
1655     IDirect3DTexture9_Release(texture);
1656 
1657     /* Checking for color key format overrides. */
1658     hr = D3DXCreateTextureFromFileInMemoryEx(device, dds_16bit, sizeof(dds_16bit),
1659             D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT,
1660             D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texture);
1661     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x.\n", hr, D3D_OK);
1662     IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1663     IDirect3DSurface9_GetDesc(surface, &desc);
1664     ok(desc.Format == D3DFMT_X1R5G5B5, "Returned format %u, expected %u.\n", desc.Format, D3DFMT_X1R5G5B5);
1665     IDirect3DSurface9_Release(surface);
1666     IDirect3DTexture9_Release(texture);
1667     hr = D3DXCreateTextureFromFileInMemoryEx(device, dds_16bit, sizeof(dds_16bit),
1668             D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT,
1669             D3DX_DEFAULT, D3DX_DEFAULT, 0xff000000, NULL, NULL, &texture);
1670     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x.\n", hr, D3D_OK);
1671     IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1672     IDirect3DSurface9_GetDesc(surface, &desc);
1673     ok(desc.Format == D3DFMT_A1R5G5B5, "Returned format %u, expected %u.\n", desc.Format, D3DFMT_A1R5G5B5);
1674     IDirect3DSurface9_Release(surface);
1675     IDirect3DTexture9_Release(texture);
1676     hr = D3DXCreateTextureFromFileInMemoryEx(device, dds_16bit, sizeof(dds_16bit),
1677             D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_X1R5G5B5, D3DPOOL_DEFAULT,
1678             D3DX_DEFAULT, D3DX_DEFAULT, 0xff000000, NULL, NULL, &texture);
1679     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x.\n", hr, D3D_OK);
1680     IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1681     IDirect3DSurface9_GetDesc(surface, &desc);
1682     ok(desc.Format == D3DFMT_X1R5G5B5, "Returned format %u, expected %u.\n", desc.Format, D3DFMT_X1R5G5B5);
1683     IDirect3DSurface9_Release(surface);
1684     IDirect3DTexture9_Release(texture);
1685 
1686     hr = D3DXCreateTextureFromFileInMemoryEx(device, dds_24bit, sizeof(dds_24bit),
1687             D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT,
1688             D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texture);
1689     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x.\n", hr, D3D_OK);
1690     IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1691     IDirect3DSurface9_GetDesc(surface, &desc);
1692     ok(desc.Format == D3DFMT_X8R8G8B8, "Returned format %u, expected %u.\n", desc.Format, D3DFMT_X8R8G8B8);
1693     IDirect3DSurface9_Release(surface);
1694     IDirect3DTexture9_Release(texture);
1695     hr = D3DXCreateTextureFromFileInMemoryEx(device, dds_24bit, sizeof(dds_24bit),
1696             D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT,
1697             D3DX_DEFAULT, D3DX_DEFAULT, 0xff000000, NULL, NULL, &texture);
1698     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x.\n", hr, D3D_OK);
1699     IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1700     IDirect3DSurface9_GetDesc(surface, &desc);
1701     ok(desc.Format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u.\n", desc.Format, D3DFMT_A8R8G8B8);
1702     IDirect3DSurface9_Release(surface);
1703     IDirect3DTexture9_Release(texture);
1704     hr = D3DXCreateTextureFromFileInMemoryEx(device, dds_24bit, sizeof(dds_24bit),
1705             D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT,
1706             D3DX_DEFAULT, D3DX_DEFAULT, 0xff000000, NULL, NULL, &texture);
1707     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x.\n", hr, D3D_OK);
1708     IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1709     IDirect3DSurface9_GetDesc(surface, &desc);
1710     ok(desc.Format == D3DFMT_X8R8G8B8, "Returned format %u, expected %u.\n", desc.Format, D3DFMT_X8R8G8B8);
1711     IDirect3DSurface9_Release(surface);
1712     IDirect3DTexture9_Release(texture);
1713 
1714     hr = D3DXCreateTextureFromFileInMemoryEx(device, png_grayscale, sizeof(png_grayscale),
1715             D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT,
1716             D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texture);
1717     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x.\n", hr, D3D_OK);
1718     IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1719     IDirect3DSurface9_GetDesc(surface, &desc);
1720     ok(desc.Format == D3DFMT_L8, "Returned format %u, expected %u.\n", desc.Format, D3DFMT_L8);
1721     IDirect3DSurface9_Release(surface);
1722     IDirect3DTexture9_Release(texture);
1723     hr = D3DXCreateTextureFromFileInMemoryEx(device, png_grayscale, sizeof(png_grayscale),
1724             D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT,
1725             D3DX_DEFAULT, D3DX_DEFAULT, 0xff000000, NULL, NULL, &texture);
1726     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x.\n", hr, D3D_OK);
1727     IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1728     IDirect3DSurface9_GetDesc(surface, &desc);
1729     ok(desc.Format == D3DFMT_A8L8, "Returned format %u, expected %u.\n", desc.Format, D3DFMT_A8L8);
1730     IDirect3DSurface9_Release(surface);
1731     IDirect3DTexture9_Release(texture);
1732     hr = D3DXCreateTextureFromFileInMemoryEx(device, png_grayscale, sizeof(png_grayscale),
1733             D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_L8, D3DPOOL_DEFAULT,
1734             D3DX_DEFAULT, D3DX_DEFAULT, 0xff000000, NULL, NULL, &texture);
1735     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x.\n", hr, D3D_OK);
1736     IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1737     IDirect3DSurface9_GetDesc(surface, &desc);
1738     ok(desc.Format == D3DFMT_L8, "Returned format %u, expected %u.\n", desc.Format, D3DFMT_L8);
1739     IDirect3DSurface9_Release(surface);
1740     IDirect3DTexture9_Release(texture);
1741 }
1742 
1743 static void test_D3DXCreateCubeTextureFromFileInMemory(IDirect3DDevice9 *device)
1744 {
1745     HRESULT hr;
1746     ULONG ref;
1747     DWORD levelcount;
1748     IDirect3DCubeTexture9 *cube_texture;
1749     D3DSURFACE_DESC surface_desc;
1750 
1751     hr = D3DXCreateCubeTextureFromFileInMemory(NULL, dds_cube_map, sizeof(dds_cube_map), &cube_texture);
1752     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateCubeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
1753 
1754     hr = D3DXCreateCubeTextureFromFileInMemory(device, NULL, sizeof(dds_cube_map), &cube_texture);
1755     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateCubeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
1756 
1757     hr = D3DXCreateCubeTextureFromFileInMemory(device, dds_cube_map, 0, &cube_texture);
1758     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateCubeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
1759 
1760     hr = D3DXCreateCubeTextureFromFileInMemory(device, dds_cube_map, sizeof(dds_cube_map), NULL);
1761     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateCubeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
1762 
1763     hr = D3DXCreateCubeTextureFromFileInMemory(device, dds_cube_map, sizeof(dds_cube_map), &cube_texture);
1764     if (SUCCEEDED(hr))
1765     {
1766         levelcount = IDirect3DCubeTexture9_GetLevelCount(cube_texture);
1767         todo_wine ok(levelcount == 3, "GetLevelCount returned %u, expected 3\n", levelcount);
1768 
1769         hr = IDirect3DCubeTexture9_GetLevelDesc(cube_texture, 0, &surface_desc);
1770         ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
1771         ok(surface_desc.Width == 4, "Got width %u, expected 4\n", surface_desc.Width);
1772         ok(surface_desc.Height == 4, "Got height %u, expected 4\n", surface_desc.Height);
1773 
1774         ref = IDirect3DCubeTexture9_Release(cube_texture);
1775         ok(ref == 0, "Invalid reference count. Got %u, expected 0\n", ref);
1776     } else skip("Couldn't create cube texture\n");
1777 }
1778 
1779 static void test_D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 *device)
1780 {
1781     HRESULT hr;
1782     IDirect3DCubeTexture9 *cube_texture;
1783 
1784     if (!is_autogenmipmap_supported(device, D3DRTYPE_CUBETEXTURE))
1785     {
1786         skip("No D3DUSAGE_AUTOGENMIPMAP support for cube textures\n");
1787         return;
1788     }
1789 
1790     hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, dds_cube_map, sizeof(dds_cube_map), D3DX_DEFAULT, D3DX_DEFAULT,
1791         D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &cube_texture);
1792     todo_wine_if (!has_cube_dxt5)
1793         ok(hr == D3D_OK, "D3DXCreateCubeTextureFromFileInMemoryEx returned %#x, expected %#x.\n", hr, D3D_OK);
1794     if (SUCCEEDED(hr)) IDirect3DCubeTexture9_Release(cube_texture);
1795 }
1796 
1797 static void test_D3DXCreateVolumeTextureFromFileInMemory(IDirect3DDevice9 *device)
1798 {
1799     HRESULT hr;
1800     ULONG ref;
1801     DWORD levelcount;
1802     IDirect3DVolumeTexture9 *volume_texture;
1803     D3DVOLUME_DESC volume_desc;
1804 
1805     hr = D3DXCreateVolumeTextureFromFileInMemory(NULL, dds_volume_map, sizeof(dds_volume_map), &volume_texture);
1806     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
1807 
1808     hr = D3DXCreateVolumeTextureFromFileInMemory(device, NULL, sizeof(dds_volume_map), &volume_texture);
1809     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
1810 
1811     hr = D3DXCreateVolumeTextureFromFileInMemory(device, dds_volume_map, 0, &volume_texture);
1812     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
1813 
1814     hr = D3DXCreateVolumeTextureFromFileInMemory(device, dds_volume_map, sizeof(dds_volume_map), NULL);
1815     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
1816 
1817     hr = D3DXCreateVolumeTextureFromFileInMemory(device, dds_volume_map, sizeof(dds_volume_map), &volume_texture);
1818     todo_wine_if (!has_3d_dxt3)
1819         ok(hr == D3D_OK, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
1820     if (SUCCEEDED(hr))
1821     {
1822         levelcount = IDirect3DVolumeTexture9_GetLevelCount(volume_texture);
1823         ok(levelcount == 3, "GetLevelCount returned %u, expected 3\n", levelcount);
1824 
1825         hr = IDirect3DVolumeTexture9_GetLevelDesc(volume_texture, 0, &volume_desc);
1826         ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
1827         ok(volume_desc.Width == 4, "Got width %u, expected 4\n", volume_desc.Width);
1828         ok(volume_desc.Height == 4, "Got height %u, expected 4\n", volume_desc.Height);
1829         ok(volume_desc.Depth == 2, "Got depth %u, expected 2\n", volume_desc.Depth);
1830         ok(volume_desc.Pool == D3DPOOL_MANAGED, "Got pool %u, expected D3DPOOL_MANAGED\n", volume_desc.Pool);
1831 
1832         hr = IDirect3DVolumeTexture9_GetLevelDesc(volume_texture, 1, &volume_desc);
1833         ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
1834         ok(volume_desc.Width == 2, "Got width %u, expected 2\n", volume_desc.Width);
1835         ok(volume_desc.Height == 2, "Got height %u, expected 2\n", volume_desc.Height);
1836         ok(volume_desc.Depth == 1, "Got depth %u, expected 1\n", volume_desc.Depth);
1837 
1838         ref = IDirect3DVolumeTexture9_Release(volume_texture);
1839         ok(ref == 0, "Invalid reference count. Got %u, expected 0\n", ref);
1840     }
1841 }
1842 
1843 /* fills positive x face with red color */
1844 static void WINAPI fill_cube_positive_x(D3DXVECTOR4 *out, const D3DXVECTOR3 *tex_coord, const D3DXVECTOR3 *texel_size, void *data)
1845 {
1846     memset(out, 0, sizeof(*out));
1847     if (tex_coord->x > 0 && fabs(tex_coord->x) > fabs(tex_coord->y) && fabs(tex_coord->x) > fabs(tex_coord->z))
1848         out->x = 1;
1849 }
1850 
1851 static void test_D3DXSaveTextureToFileInMemory(IDirect3DDevice9 *device)
1852 {
1853     HRESULT hr;
1854     IDirect3DTexture9 *texture;
1855     IDirect3DCubeTexture9 *cube_texture;
1856     IDirect3DVolumeTexture9 *volume_texture;
1857     ID3DXBuffer *buffer;
1858     void *buffer_pointer;
1859     DWORD buffer_size;
1860     D3DXIMAGE_INFO info;
1861     D3DXIMAGE_FILEFORMAT file_format;
1862 
1863     /* textures */
1864     hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
1865     if (FAILED(hr))
1866     {
1867         skip("Failed to create texture\n");
1868         return;
1869     }
1870 
1871     for (file_format = D3DXIFF_BMP; file_format <= D3DXIFF_JPG; file_format++)
1872     {
1873         hr = D3DXSaveTextureToFileInMemory(&buffer, file_format, (IDirect3DBaseTexture9 *)texture, NULL);
1874         ok(hr == D3D_OK, "D3DXSaveTextureToFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
1875         if (SUCCEEDED(hr))
1876         {
1877             buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer);
1878             buffer_size = ID3DXBuffer_GetBufferSize(buffer);
1879             hr = D3DXGetImageInfoFromFileInMemory(buffer_pointer, buffer_size, &info);
1880             ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
1881 
1882             ok(info.Width == 256, "Got width %u, expected %u\n", info.Width, 256);
1883             ok(info.Height == 256, "Got height %u, expected %u\n", info.Height, 256);
1884             ok(info.MipLevels == 1, "Got miplevels %u, expected %u\n", info.MipLevels, 1);
1885             ok(info.ResourceType == D3DRTYPE_TEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_TEXTURE);
1886             ok(info.ImageFileFormat == file_format, "Got file format %#x, expected %#x\n", info.ImageFileFormat, file_format);
1887             ID3DXBuffer_Release(buffer);
1888         }
1889     }
1890 
1891     todo_wine {
1892     hr = D3DXSaveTextureToFileInMemory(&buffer, D3DXIFF_DDS, (IDirect3DBaseTexture9 *)texture, NULL);
1893     ok(hr == D3D_OK, "D3DXSaveTextureToFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
1894     if (SUCCEEDED(hr))
1895     {
1896         buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer);
1897         buffer_size = ID3DXBuffer_GetBufferSize(buffer);
1898         hr = D3DXGetImageInfoFromFileInMemory(buffer_pointer, buffer_size, &info);
1899         ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
1900 
1901         ok(info.Width == 256, "Got width %u, expected %u\n", info.Width, 256);
1902         ok(info.Height == 256, "Got height %u, expected %u\n", info.Height, 256);
1903         ok(info.MipLevels == 9, "Got miplevels %u, expected %u\n", info.MipLevels, 9);
1904         ok(info.ResourceType == D3DRTYPE_TEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_TEXTURE);
1905         ok(info.ImageFileFormat == D3DXIFF_DDS, "Got file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_DDS);
1906         ID3DXBuffer_Release(buffer);
1907     }
1908     }
1909 
1910     IDirect3DTexture9_Release(texture);
1911 
1912     /* cube textures */
1913     hr = IDirect3DDevice9_CreateCubeTexture(device, 256, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &cube_texture, NULL);
1914     if (FAILED(hr))
1915     {
1916         skip("Failed to create cube texture\n");
1917         return;
1918     }
1919 
1920     hr = D3DXFillCubeTexture(cube_texture, fill_cube_positive_x, NULL);
1921     ok(hr == D3D_OK, "D3DXFillCubeTexture returned %#x, expected %#x\n", hr, D3D_OK);
1922 
1923     hr = D3DXSaveTextureToFileInMemory(&buffer, D3DXIFF_BMP, (IDirect3DBaseTexture9 *)cube_texture, NULL);
1924     ok(hr == D3D_OK, "D3DXSaveTextureToFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
1925     if (SUCCEEDED(hr))
1926     {
1927         IDirect3DSurface9 *surface;
1928 
1929         buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer);
1930         buffer_size = ID3DXBuffer_GetBufferSize(buffer);
1931         hr = D3DXGetImageInfoFromFileInMemory(buffer_pointer, buffer_size, &info);
1932         ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
1933 
1934         ok(info.Width == 256, "Got width %u, expected %u\n", info.Width, 256);
1935         ok(info.Height == 256, "Got height %u, expected %u\n", info.Height, 256);
1936         ok(info.MipLevels == 1, "Got miplevels %u, expected %u\n", info.MipLevels, 1);
1937         ok(info.ResourceType == D3DRTYPE_TEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_TEXTURE);
1938         ok(info.ImageFileFormat == D3DXIFF_BMP, "Got file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_BMP);
1939 
1940         /* positive x face is saved */
1941         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1942         if (SUCCEEDED(hr))
1943         {
1944             D3DLOCKED_RECT locked_rect;
1945 
1946             hr = D3DXLoadSurfaceFromFileInMemory(surface, NULL, NULL, buffer_pointer, buffer_size, NULL, D3DX_FILTER_NONE, 0, NULL);
1947             ok(hr == D3D_OK, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
1948 
1949             hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, D3DLOCK_READONLY);
1950             if (SUCCEEDED(hr))
1951             {
1952                 DWORD *color = locked_rect.pBits;
1953                 ok(*color == 0x00ff0000, "Got color %#x, expected %#x\n", *color, 0x00ff0000);
1954                 IDirect3DSurface9_UnlockRect(surface);
1955             }
1956 
1957             IDirect3DSurface9_Release(surface);
1958         } else skip("Failed to create surface\n");
1959 
1960         ID3DXBuffer_Release(buffer);
1961     }
1962 
1963     todo_wine {
1964     hr = D3DXSaveTextureToFileInMemory(&buffer, D3DXIFF_DDS, (IDirect3DBaseTexture9 *)cube_texture, NULL);
1965     ok(hr == D3D_OK, "D3DXSaveTextureToFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
1966     if (SUCCEEDED(hr))
1967     {
1968         buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer);
1969         buffer_size = ID3DXBuffer_GetBufferSize(buffer);
1970         hr = D3DXGetImageInfoFromFileInMemory(buffer_pointer, buffer_size, &info);
1971         ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
1972 
1973         ok(info.Width == 256, "Got width %u, expected %u\n", info.Width, 256);
1974         ok(info.Height == 256, "Got height %u, expected %u\n", info.Height, 256);
1975         ok(info.MipLevels == 9, "Got miplevels %u, expected %u\n", info.MipLevels, 9);
1976         ok(info.ResourceType == D3DRTYPE_CUBETEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_CUBETEXTURE);
1977         ok(info.ImageFileFormat == D3DXIFF_DDS, "Got file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_DDS);
1978         ID3DXBuffer_Release(buffer);
1979     }
1980     }
1981 
1982     IDirect3DCubeTexture9_Release(cube_texture);
1983 
1984     /* volume textures */
1985     hr = IDirect3DDevice9_CreateVolumeTexture(device, 256, 256, 256, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &volume_texture, NULL);
1986     if (FAILED(hr))
1987     {
1988         skip("Failed to create volume texture\n");
1989         return;
1990     }
1991 
1992     todo_wine {
1993     hr = D3DXSaveTextureToFileInMemory(&buffer, D3DXIFF_BMP, (IDirect3DBaseTexture9 *)volume_texture, NULL);
1994     ok(hr == D3D_OK, "D3DXSaveTextureToFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
1995     if (SUCCEEDED(hr))
1996     {
1997         buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer);
1998         buffer_size = ID3DXBuffer_GetBufferSize(buffer);
1999         hr = D3DXGetImageInfoFromFileInMemory(buffer_pointer, buffer_size, &info);
2000         ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
2001 
2002         ok(info.Width == 256, "Got width %u, expected %u\n", info.Width, 256);
2003         ok(info.Height == 256, "Got height %u, expected %u\n", info.Height, 256);
2004         ok(info.Depth == 1, "Got depth %u, expected %u\n", info.Depth, 1);
2005         ok(info.MipLevels == 1, "Got miplevels %u, expected %u\n", info.MipLevels, 1);
2006         ok(info.ResourceType == D3DRTYPE_TEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_TEXTURE);
2007         ok(info.ImageFileFormat == D3DXIFF_BMP, "Got file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_BMP);
2008         ID3DXBuffer_Release(buffer);
2009     }
2010 
2011     hr = D3DXSaveTextureToFileInMemory(&buffer, D3DXIFF_DDS, (IDirect3DBaseTexture9 *)volume_texture, NULL);
2012     ok(hr == D3D_OK, "D3DXSaveTextureToFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
2013     if (SUCCEEDED(hr))
2014     {
2015         buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer);
2016         buffer_size = ID3DXBuffer_GetBufferSize(buffer);
2017         hr = D3DXGetImageInfoFromFileInMemory(buffer_pointer, buffer_size, &info);
2018         ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
2019 
2020         ok(info.Width == 256, "Got width %u, expected %u\n", info.Width, 256);
2021         ok(info.Height == 256, "Got height %u, expected %u\n", info.Height, 256);
2022         ok(info.Depth == 256, "Got depth %u, expected %u\n", info.Depth, 256);
2023         ok(info.MipLevels == 9, "Got miplevels %u, expected %u\n", info.MipLevels, 9);
2024         ok(info.ResourceType == D3DRTYPE_VOLUMETEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_VOLUMETEXTURE);
2025         ok(info.ImageFileFormat == D3DXIFF_DDS, "Got file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_DDS);
2026         ID3DXBuffer_Release(buffer);
2027     }
2028     }
2029 
2030     IDirect3DVolumeTexture9_Release(volume_texture);
2031 }
2032 
2033 static void test_texture_shader(void)
2034 {
2035     static const DWORD shader_zero[] = {0x0};
2036     static const DWORD shader_invalid[] = {0xeeee0100};
2037     static const DWORD shader_empty[] = {0xfffe0200, 0x0000ffff};
2038 #if 0
2039 float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR
2040 {
2041     return float4(pos, 1.0);
2042 }
2043 #endif
2044     static const DWORD shader_code[] =
2045     {
2046         0x54580100, 0x0015fffe, 0x42415443, 0x0000001c, 0x0000001f, 0x54580100, 0x00000000, 0x00000000,
2047         0x00000100, 0x0000001c, 0x4d007874, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c,
2048         0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131, 0x000afffe,
2049         0x54494c43, 0x00000004, 0x00000000, 0x3ff00000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2050         0x00000000, 0x00000000, 0x0014fffe, 0x434c5846, 0x00000002, 0x10000003, 0x00000001, 0x00000000,
2051         0x00000003, 0x00000000, 0x00000000, 0x00000004, 0x00000000, 0x10000001, 0x00000001, 0x00000000,
2052         0x00000001, 0x00000000, 0x00000000, 0x00000004, 0x00000003, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff,
2053     };
2054     IDirect3DVolumeTexture9 *volume_texture;
2055     IDirect3DCubeTexture9 *cube_texture;
2056     D3DPRESENT_PARAMETERS d3dpp;
2057     IDirect3DTexture9 *texture;
2058     IDirect3DDevice9 *device;
2059     ID3DXTextureShader *tx;
2060     unsigned int x, y, z;
2061     ID3DXBuffer *buffer;
2062     unsigned int *data;
2063     D3DLOCKED_RECT lr;
2064     D3DLOCKED_BOX lb;
2065     IDirect3D9 *d3d;
2066     D3DCAPS9 caps;
2067     HRESULT hr;
2068     HWND wnd;
2069 
2070     hr = D3DXCreateTextureShader(NULL, NULL);
2071     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
2072 
2073     hr = D3DXCreateTextureShader(NULL, &tx);
2074     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
2075 
2076     hr = D3DXCreateTextureShader(shader_invalid, &tx);
2077     todo_wine ok(hr == D3DXERR_INVALIDDATA, "Got unexpected hr %#x.\n", hr);
2078 
2079     hr = D3DXCreateTextureShader(shader_zero, &tx);
2080     todo_wine ok(hr == D3DXERR_INVALIDDATA, "Got unexpected hr %#x.\n", hr);
2081 
2082     hr = D3DXCreateTextureShader(shader_empty, &tx);
2083     todo_wine ok(hr == D3DXERR_INVALIDDATA, "Got unexpected hr %#x.\n", hr);
2084 
2085     hr = D3DXCreateTextureShader(shader_code, &tx);
2086     ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
2087 
2088     hr = tx->lpVtbl->GetFunction(tx, &buffer);
2089     todo_wine ok(SUCCEEDED(hr), "Failed to get texture shader bytecode.\n");
2090     if (FAILED(hr))
2091     {
2092         skip("Texture shaders not supported, skipping further tests.\n");
2093         IUnknown_Release(tx);
2094         return;
2095     }
2096     ID3DXBuffer_Release(buffer);
2097 
2098     if (!(wnd = CreateWindowA("static", "d3dx9_test", WS_OVERLAPPEDWINDOW, 0, 0,
2099             640, 480, NULL, NULL, NULL, NULL)))
2100     {
2101         skip("Couldn't create application window.\n");
2102         IUnknown_Release(tx);
2103         return;
2104     }
2105     d3d = Direct3DCreate9(D3D_SDK_VERSION);
2106     if (!d3d)
2107     {
2108         skip("Couldn't create IDirect3D9 object.\n");
2109         DestroyWindow(wnd);
2110         IUnknown_Release(tx);
2111         return;
2112     }
2113 
2114     ZeroMemory(&d3dpp, sizeof(d3dpp));
2115     d3dpp.Windowed = TRUE;
2116     d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2117     hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, wnd,
2118             D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &device);
2119     if (FAILED(hr))
2120     {
2121         skip("Failed to create IDirect3DDevice9 object, hr %#x.\n", hr);
2122         IDirect3D9_Release(d3d);
2123         DestroyWindow(wnd);
2124         IUnknown_Release(tx);
2125         return;
2126     }
2127 
2128     IDirect3DDevice9_GetDeviceCaps(device, &caps);
2129 
2130     hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM,
2131             &texture, NULL);
2132     ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
2133 
2134     hr = D3DXFillTextureTX(texture, tx);
2135     ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
2136 
2137     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, D3DLOCK_READONLY);
2138     ok(SUCCEEDED(hr), "Locking texture failed, hr %#x.\n", hr);
2139     data = lr.pBits;
2140     for (y = 0; y < 256; ++y)
2141     {
2142         for (x = 0; x < 256; ++x)
2143         {
2144             unsigned int expected = 0xff000000 | x << 16 | y << 8;
2145             /* The third position coordinate is apparently undefined for 2D textures. */
2146             unsigned int color = data[y * lr.Pitch / sizeof(*data) + x] & 0xffffff00;
2147 
2148             ok(compare_color(color, expected, 1), "Unexpected color %08x at (%u, %u).\n", color, x, y);
2149         }
2150     }
2151     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2152     ok(SUCCEEDED(hr), "Unlocking texture failed, hr %#x.\n", hr);
2153 
2154     IDirect3DTexture9_Release(texture);
2155 
2156     if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP))
2157     {
2158         skip("Cube textures not supported, skipping tests.\n");
2159         goto cleanup;
2160     }
2161 
2162     hr = IDirect3DDevice9_CreateCubeTexture(device, 256, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM,
2163             &cube_texture, NULL);
2164     ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
2165 
2166     hr = D3DXFillCubeTextureTX(cube_texture, tx);
2167     ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
2168 
2169     for (z = 0; z < 6; ++z)
2170     {
2171         static const char * const mapping[6][3] =
2172         {
2173             {"-x", "-y", "1"},
2174             {"+x", "-y", "0"},
2175             {"+y", "1", "+x"},
2176             {"-y", "0", "+x"},
2177             {"1", "-y", "+x"},
2178             {"0", "-y", "-x"},
2179         };
2180 
2181         hr = IDirect3DCubeTexture9_LockRect(cube_texture, z, 0, &lr, NULL, D3DLOCK_READONLY);
2182         ok(SUCCEEDED(hr), "Locking texture failed, hr %#x.\n", hr);
2183         data = lr.pBits;
2184         for (y = 0; y < 256; ++y)
2185         {
2186             for (x = 0; x < 256; ++x)
2187             {
2188                 unsigned int color = data[y * lr.Pitch / sizeof(*data) + x];
2189                 unsigned int expected = 0xff000000;
2190                 unsigned int i;
2191 
2192                 for (i = 0; i < 3; ++i)
2193                 {
2194                     int component;
2195 
2196                     if (mapping[z][i][0] == '0')
2197                         component = 0;
2198                     else if (mapping[z][i][0] == '1')
2199                         component = 255;
2200                     else
2201                         component = mapping[z][i][1] == 'x' ? x * 2 - 255 : y * 2 - 255;
2202                     if (mapping[z][i][0] == '-')
2203                         component = -component;
2204                     expected |= max(component, 0) << i * 8;
2205                 }
2206                 ok(compare_color(color, expected, 1), "Unexpected color %08x at (%u, %u, %u).\n",
2207                         color, x, y, z);
2208             }
2209         }
2210         hr = IDirect3DCubeTexture9_UnlockRect(cube_texture, z, 0);
2211         ok(SUCCEEDED(hr), "Unlocking texture failed, hr %#x.\n", hr);
2212     }
2213 
2214     IDirect3DCubeTexture9_Release(cube_texture);
2215 
2216     if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP) || caps.MaxVolumeExtent < 64)
2217     {
2218         skip("Volume textures not supported, skipping test.\n");
2219         goto cleanup;
2220     }
2221     hr = IDirect3DDevice9_CreateVolumeTexture(device, 64, 64, 64, 1, 0, D3DFMT_A8R8G8B8,
2222             D3DPOOL_SYSTEMMEM, &volume_texture, NULL);
2223     ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
2224 
2225     hr = D3DXFillVolumeTextureTX(volume_texture, tx);
2226     ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
2227 
2228     hr = IDirect3DVolumeTexture9_LockBox(volume_texture, 0, &lb, NULL, D3DLOCK_READONLY);
2229     ok(SUCCEEDED(hr), "Locking texture failed, hr %#x.\n", hr);
2230     data = lb.pBits;
2231     for (z = 0; z < 64; ++z)
2232     {
2233         for (y = 0; y < 64; ++y)
2234         {
2235             for (x = 0; x < 64; ++x)
2236             {
2237                 unsigned int expected = 0xff000000 | ((x * 4 + 2) << 16) | ((y * 4 + 2) << 8) | (z * 4 + 2);
2238                 unsigned int color = data[z * lb.SlicePitch / sizeof(*data) + y * lb.RowPitch / sizeof(*data) + x];
2239 
2240                 ok(compare_color(color, expected, 1), "Unexpected color %08x at (%u, %u, %u).\n",
2241                         color, x, y, z);
2242             }
2243         }
2244     }
2245     hr = IDirect3DVolumeTexture9_UnlockBox(volume_texture, 0);
2246     ok(SUCCEEDED(hr), "Unlocking texture failed, hr %#x.\n", hr);
2247 
2248     IDirect3DVolumeTexture9_Release(volume_texture);
2249 
2250  cleanup:
2251     IDirect3DDevice9_Release(device);
2252     IDirect3D9_Release(d3d);
2253     DestroyWindow(wnd);
2254     IUnknown_Release(tx);
2255 }
2256 
2257 START_TEST(texture)
2258 {
2259     HWND wnd;
2260     IDirect3D9 *d3d;
2261     IDirect3DDevice9 *device;
2262     D3DPRESENT_PARAMETERS d3dpp;
2263     HRESULT hr;
2264     ULONG ref;
2265 
2266     if (!(wnd = CreateWindowA("static", "d3dx9_test", WS_OVERLAPPEDWINDOW, 0, 0,
2267             640, 480, NULL, NULL, NULL, NULL)))
2268     {
2269         skip("Couldn't create application window\n");
2270         return;
2271     }
2272     d3d = Direct3DCreate9(D3D_SDK_VERSION);
2273     if (!d3d) {
2274         skip("Couldn't create IDirect3D9 object\n");
2275         DestroyWindow(wnd);
2276         return;
2277     }
2278 
2279     ZeroMemory(&d3dpp, sizeof(d3dpp));
2280     d3dpp.Windowed   = TRUE;
2281     d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2282     hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, wnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &device);
2283     if (FAILED(hr)) {
2284         skip("Failed to create IDirect3DDevice9 object %#x\n", hr);
2285         IDirect3D9_Release(d3d);
2286         DestroyWindow(wnd);
2287         return;
2288     }
2289 
2290     /* Check whether DXTn textures are supported. */
2291     has_2d_dxt3 = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
2292             D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT3));
2293     hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
2294             D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT5);
2295     has_2d_dxt5 = SUCCEEDED(hr);
2296     hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
2297             D3DFMT_X8R8G8B8, 0, D3DRTYPE_CUBETEXTURE, D3DFMT_DXT5);
2298     has_cube_dxt5 = SUCCEEDED(hr);
2299     has_3d_dxt3 = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
2300             D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_DXT3));
2301 
2302     test_D3DXCheckTextureRequirements(device);
2303     test_D3DXCheckCubeTextureRequirements(device);
2304     test_D3DXCheckVolumeTextureRequirements(device);
2305     test_D3DXCreateTexture(device);
2306     test_D3DXFilterTexture(device);
2307     test_D3DXFillTexture(device);
2308     test_D3DXFillCubeTexture(device);
2309     test_D3DXFillVolumeTexture(device);
2310     test_D3DXCreateTextureFromFileInMemory(device);
2311     test_D3DXCreateTextureFromFileInMemoryEx(device);
2312     test_D3DXCreateCubeTextureFromFileInMemory(device);
2313     test_D3DXCreateCubeTextureFromFileInMemoryEx(device);
2314     test_D3DXCreateVolumeTextureFromFileInMemory(device);
2315     test_D3DXSaveTextureToFileInMemory(device);
2316 
2317     ref = IDirect3DDevice9_Release(device);
2318     ok(!ref, "Device has %u references left.\n", ref);
2319 
2320     IDirect3D9_Release(d3d);
2321     DestroyWindow(wnd);
2322 
2323     test_texture_shader();
2324 }
2325