quartz: Remove unused variables.
[wine] / dlls / d3dx9_36 / tests / texture.c
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 /* 2x2 16-bit dds, no mipmaps */
29 static const unsigned char dds_16bit[] = {
30 0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x08,0x00,0x02,0x00,0x00,0x00,
31 0x02,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
32 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
33 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
34 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
35 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x7c,0x00,0x00,
36 0xe0,0x03,0x00,0x00,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,
37 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
38 0xff,0x7f,0xff,0x7f,0xff,0x7f,0xff,0x7f
39 };
40
41 /* 2x2 24-bit dds, 2 mipmaps */
42 static const unsigned char dds_24bit[] = {
43 0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x0a,0x00,0x02,0x00,0x00,0x00,
44 0x02,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
45 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
46 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
47 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
48 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0xff,0x00,
49 0x00,0xff,0x00,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x40,0x00,
50 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
51 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
52 };
53
54 /* 4x4 cube map dds */
55 static const unsigned char dds_cube_map[] = {
56 0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x08,0x00,0x04,0x00,0x00,0x00,
57 0x04,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
58 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
59 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
60 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
61 0x04,0x00,0x00,0x00,0x44,0x58,0x54,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
62 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x00,0x00,
63 0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
64 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50,
65 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x51,
66 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x52,
67 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x53,
68 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x54,
69 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x55
70 };
71
72 /* 4x4x2 volume map dds, 2 mipmaps */
73 static const unsigned char dds_volume_map[] = {
74 0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x8a,0x00,0x04,0x00,0x00,0x00,
75 0x04,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
76 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
77 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
78 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
79 0x04,0x00,0x00,0x00,0x44,0x58,0x54,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
80 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x40,0x00,
81 0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
82 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50,
83 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50,
84 0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x2f,0x7e,0xcf,0x79,0x01,0x54,0x5c,0x5c,
85 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x84,0xef,0x7b,0xaa,0xab,0xab,0xab
86 };
87
88 #define ADMITTED_ERROR 0.0001f
89
90 static inline float relative_error(float expected, float got)
91 {
92     return expected == 0.0f ? fabs(expected - got) : fabs(1.0f - got / expected);
93 }
94
95 #define expect_vec4(expected, got) expect_vec4_(__LINE__, expected, got)
96 static inline void expect_vec4_(unsigned int line, const D3DXVECTOR4 *expected, const D3DXVECTOR4 *got)
97 {
98     ok_(__FILE__, line)(relative_error(expected->x, got->x) < ADMITTED_ERROR
99         && relative_error(expected->y, got->y) < ADMITTED_ERROR
100         && relative_error(expected->z, got->z) < ADMITTED_ERROR
101         && relative_error(expected->w, got->w) < ADMITTED_ERROR,
102         "Expected (%f, %f, %f, %f), got (%f, %f, %f, %f)\n",
103         expected->x, expected->y, expected->z, expected->w,
104         got->x, got->y, got->z, got->w);
105 }
106
107 static inline float float_16_to_32(unsigned short in)
108 {
109     unsigned short s = (in & 0x8000);
110     unsigned short e = (in & 0x7C00) >> 10;
111     unsigned short m = in & 0x3FF;
112     float sgn = (s ? -1.0f : 1.0f);
113
114     if (e == 0)
115     {
116         if (m == 0) return sgn * 0.0f; /* +0.0 or -0.0 */
117         else return sgn * powf(2, -14.0f) * (m / 1024.0f);
118     }
119     else
120     {
121         return sgn * powf(2, e - 15.0f) * (1.0f + (m / 1024.0f));
122     }
123 }
124
125 static BOOL is_autogenmipmap_supported(IDirect3DDevice9 *device, D3DRESOURCETYPE resource_type)
126 {
127     HRESULT hr;
128     D3DCAPS9 caps;
129     IDirect3D9 *d3d9;
130     D3DDISPLAYMODE mode;
131     D3DDEVICE_CREATION_PARAMETERS params;
132
133     IDirect3DDevice9_GetDeviceCaps(device, &caps);
134     IDirect3DDevice9_GetDirect3D(device, &d3d9);
135     IDirect3DDevice9_GetCreationParameters(device, &params);
136     IDirect3DDevice9_GetDisplayMode(device, 0, &mode);
137
138     if (!(caps.Caps2 & D3DCAPS2_CANAUTOGENMIPMAP))
139         return FALSE;
140
141     hr = IDirect3D9_CheckDeviceFormat(d3d9, params.AdapterOrdinal, params.DeviceType,
142         mode.Format, D3DUSAGE_AUTOGENMIPMAP, resource_type, D3DFMT_A8R8G8B8);
143
144     IDirect3D9_Release(d3d9);
145     return SUCCEEDED(hr);
146 }
147
148 static void test_D3DXCheckTextureRequirements(IDirect3DDevice9 *device)
149 {
150     UINT width, height, mipmaps;
151     D3DFORMAT format, expected;
152     D3DCAPS9 caps;
153     HRESULT hr;
154     IDirect3D9 *d3d;
155     D3DDEVICE_CREATION_PARAMETERS params;
156     D3DDISPLAYMODE mode;
157
158     IDirect3DDevice9_GetDeviceCaps(device, &caps);
159
160     /* general tests */
161     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
162     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
163
164     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DX_DEFAULT, NULL, D3DPOOL_DEFAULT);
165     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
166
167     hr = D3DXCheckTextureRequirements(NULL, NULL, NULL, NULL, D3DX_DEFAULT, NULL, D3DPOOL_DEFAULT);
168     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
169
170     /* width & height */
171     width = height = D3DX_DEFAULT;
172     hr = D3DXCheckTextureRequirements(device, &width, &height, NULL, 0, NULL, D3DPOOL_DEFAULT);
173     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
174     ok(width == 256, "Returned width %d, expected %d\n", width, 256);
175     ok(height == 256, "Returned height %d, expected %d\n", height, 256);
176
177     width = D3DX_DEFAULT;
178     hr = D3DXCheckTextureRequirements(device, &width, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
179     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
180     ok(width == 256, "Returned width %d, expected %d\n", width, 256);
181
182     if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
183         skip("Hardware only supports pow2 textures\n");
184     else
185     {
186         width = 62;
187         hr = D3DXCheckTextureRequirements(device, &width, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
188         ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
189         ok(width == 62, "Returned width %d, expected %d\n", width, 62);
190
191         width = D3DX_DEFAULT; height = 63;
192         hr = D3DXCheckTextureRequirements(device, &width, &height, NULL, 0, NULL, D3DPOOL_DEFAULT);
193         ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
194         ok(width == height, "Returned width %d, expected %d\n", width, height);
195         ok(height == 63, "Returned height %d, expected %d\n", height, 63);
196     }
197
198     width = D3DX_DEFAULT; height = 0;
199     hr = D3DXCheckTextureRequirements(device, &width, &height, NULL, 0, NULL, D3DPOOL_DEFAULT);
200     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
201     ok(width == 1, "Returned width %d, expected %d\n", width, 1);
202     ok(height == 1, "Returned height %d, expected %d\n", height, 1);
203
204     width = 0; height = 0;
205     hr = D3DXCheckTextureRequirements(device, &width, &height, NULL, 0, NULL, D3DPOOL_DEFAULT);
206     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
207     ok(width == 1, "Returned width %d, expected %d\n", width, 1);
208     ok(height == 1, "Returned height %d, expected %d\n", height, 1);
209
210     width = 0;
211     hr = D3DXCheckTextureRequirements(device, &width, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
212     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
213     ok(width == 1, "Returned width %d, expected %d\n", width, 1);
214
215     width = 0xFFFFFFFE;
216     hr = D3DXCheckTextureRequirements(device, &width, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
217     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
218     ok(width == caps.MaxTextureWidth, "Returned width %d, expected %d\n", width, caps.MaxTextureWidth);
219
220     width = caps.MaxTextureWidth-1;
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     if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
224         ok(width == caps.MaxTextureWidth, "Returned width %d, expected %d\n", width, caps.MaxTextureWidth);
225     else
226         ok(width == caps.MaxTextureWidth-1, "Returned width %d, expected %d\n", width, caps.MaxTextureWidth-1);
227
228     /* mipmaps */
229     width = 64; height = 63;
230     mipmaps = 9;
231     hr = D3DXCheckTextureRequirements(device, &width, &height, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
232     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
233     ok(mipmaps == 7, "Returned mipmaps %d, expected %d\n", mipmaps, 7);
234
235     if (!(caps.TextureCaps & D3DPTEXTURECAPS_POW2))
236     {
237         width = 284; height = 137;
238         mipmaps = 20;
239         hr = D3DXCheckTextureRequirements(device, &width, &height, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
240         ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
241         ok(mipmaps == 9, "Returned mipmaps %d, expected %d\n", mipmaps, 9);
242
243         width = height = 63;
244         mipmaps = 9;
245         hr = D3DXCheckTextureRequirements(device, &width, &height, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
246         ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
247         ok(mipmaps == 6, "Returned mipmaps %d, expected %d\n", mipmaps, 6);
248     }
249     else
250         skip("Skipping some tests, npot2 textures unsupported\n");
251
252     mipmaps = 20;
253     hr = D3DXCheckTextureRequirements(device, NULL, NULL, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
254     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
255     ok(mipmaps == 9, "Returned mipmaps %d, expected %d\n", mipmaps, 9);
256
257     mipmaps = 0;
258     hr = D3DXCheckTextureRequirements(device, NULL, NULL, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
259     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
260     ok(mipmaps == 9, "Returned mipmaps %d, expected %d\n", mipmaps, 9);
261
262     /* mipmaps when D3DUSAGE_AUTOGENMIPMAP is set */
263     if (is_autogenmipmap_supported(device, D3DRTYPE_TEXTURE))
264     {
265         mipmaps = 0;
266         hr = D3DXCheckTextureRequirements(device, NULL, NULL, &mipmaps, D3DUSAGE_AUTOGENMIPMAP, NULL, D3DPOOL_DEFAULT);
267         ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
268         ok(mipmaps == 0, "Returned mipmaps %d, expected %d\n", mipmaps, 0);
269         mipmaps = 1;
270         hr = D3DXCheckTextureRequirements(device, NULL, NULL, &mipmaps, D3DUSAGE_AUTOGENMIPMAP, NULL, D3DPOOL_DEFAULT);
271         ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
272         ok(mipmaps == 1, "Returned mipmaps %d, expected %d\n", mipmaps, 1);
273         mipmaps = 2;
274         hr = D3DXCheckTextureRequirements(device, NULL, NULL, &mipmaps, D3DUSAGE_AUTOGENMIPMAP, NULL, D3DPOOL_DEFAULT);
275         ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
276         ok(mipmaps == 0, "Returned mipmaps %d, expected %d\n", mipmaps, 0);
277         mipmaps = 6;
278         hr = D3DXCheckTextureRequirements(device, NULL, NULL, &mipmaps, D3DUSAGE_AUTOGENMIPMAP, NULL, D3DPOOL_DEFAULT);
279         ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
280         ok(mipmaps == 0, "Returned mipmaps %d, expected %d\n", mipmaps, 0);
281     }
282     else
283         skip("No D3DUSAGE_AUTOGENMIPMAP support for textures\n");
284
285     /* usage */
286     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DUSAGE_WRITEONLY, NULL, D3DPOOL_DEFAULT);
287     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckTextureRequirements succeeded, but should've failed.\n");
288     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DUSAGE_DONOTCLIP, NULL, D3DPOOL_DEFAULT);
289     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckTextureRequirements succeeded, but should've failed.\n");
290     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DUSAGE_POINTS, NULL, D3DPOOL_DEFAULT);
291     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckTextureRequirements succeeded, but should've failed.\n");
292     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DUSAGE_RTPATCHES, NULL, D3DPOOL_DEFAULT);
293     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckTextureRequirements succeeded, but should've failed.\n");
294     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DUSAGE_NPATCHES, NULL, D3DPOOL_DEFAULT);
295     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckTextureRequirements succeeded, but should've failed.\n");
296
297     /* format */
298     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
299     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
300
301     format = D3DFMT_UNKNOWN;
302     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
303     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
304     ok(format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_A8R8G8B8);
305
306     format = D3DX_DEFAULT;
307     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
308     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
309     ok(format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_A8R8G8B8);
310
311     format = D3DFMT_R8G8B8;
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_X8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_X8R8G8B8);
315
316     IDirect3DDevice9_GetDirect3D(device, &d3d);
317     IDirect3DDevice9_GetCreationParameters(device, &params);
318     IDirect3DDevice9_GetDisplayMode(device, 0, &mode);
319
320     if (SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType,
321                                                mode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_R3G3B2)))
322         expected = D3DFMT_R3G3B2;
323     else
324     {
325         if (SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType,
326                                                    mode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_X4R4G4B4)))
327             expected = D3DFMT_X4R4G4B4;
328         else
329             expected = D3DFMT_X1R5G5B5;
330     }
331
332     format = D3DFMT_R3G3B2;
333     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
334     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
335     ok(format == expected, "Returned format %u, expected %u\n", format, expected);
336
337     if(SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType,
338                                               mode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_A8R3G3B2)))
339         expected = D3DFMT_A8R3G3B2;
340     else
341         expected = D3DFMT_A8R8G8B8;
342
343     format = D3DFMT_A8R3G3B2;
344     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
345     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
346     ok(format == expected, "Returned format %u, expected %u\n", format, expected);
347
348     IDirect3D9_Release(d3d);
349 }
350
351 static void test_D3DXCheckCubeTextureRequirements(IDirect3DDevice9 *device)
352 {
353     UINT size, mipmaps, expected;
354     D3DFORMAT format;
355     D3DCAPS9 caps;
356     HRESULT hr;
357
358     IDirect3DDevice9_GetDeviceCaps(device, &caps);
359
360     if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP))
361     {
362         skip("No cube textures support\n");
363         return;
364     }
365
366     /* general tests */
367     hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
368     ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
369
370     hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, D3DX_DEFAULT, NULL, D3DPOOL_DEFAULT);
371     ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
372
373     hr = D3DXCheckCubeTextureRequirements(NULL, NULL, NULL, D3DX_DEFAULT, NULL, D3DPOOL_DEFAULT);
374     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
375
376     /* size */
377     size = D3DX_DEFAULT;
378     hr = D3DXCheckCubeTextureRequirements(device, &size, NULL, 0, NULL, D3DPOOL_DEFAULT);
379     ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
380     ok(size == 256, "Returned size %d, expected %d\n", size, 256);
381
382     /* mipmaps */
383     size = 64;
384     mipmaps = 9;
385     hr = D3DXCheckCubeTextureRequirements(device, &size, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
386     ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
387     ok(mipmaps == 7, "Returned mipmaps %d, expected %d\n", mipmaps, 7);
388
389     size = 284;
390     mipmaps = 20;
391     expected = caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2 ? 10 : 9;
392     hr = D3DXCheckCubeTextureRequirements(device, &size, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
393     ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
394     ok(mipmaps == expected, "Returned mipmaps %d, expected %d\n", mipmaps, expected);
395
396     size = 63;
397     mipmaps = 9;
398     expected = caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2 ? 7 : 6;
399     hr = D3DXCheckCubeTextureRequirements(device, &size, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
400     ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
401     ok(mipmaps == expected, "Returned mipmaps %d, expected %d\n", mipmaps, expected);
402
403     mipmaps = 0;
404     hr = D3DXCheckCubeTextureRequirements(device, NULL, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
405     ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
406     ok(mipmaps == 9, "Returned mipmaps %d, expected %d\n", mipmaps, 9);
407
408     if (is_autogenmipmap_supported(device, D3DRTYPE_CUBETEXTURE))
409     {
410         mipmaps = 3;
411         hr = D3DXCheckCubeTextureRequirements(device, NULL,  &mipmaps, D3DUSAGE_AUTOGENMIPMAP, NULL, D3DPOOL_DEFAULT);
412         ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
413         ok(mipmaps == 0, "Returned mipmaps %d, expected %d\n", mipmaps, 0);
414     }
415     else
416         skip("No D3DUSAGE_AUTOGENMIPMAP support for cube textures\n");
417
418     /* usage */
419     hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, D3DUSAGE_WRITEONLY, NULL, D3DPOOL_DEFAULT);
420     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckCubeTextureRequirements succeeded, but should've failed.\n");
421     hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, D3DUSAGE_DONOTCLIP, NULL, D3DPOOL_DEFAULT);
422     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckCubeTextureRequirements succeeded, but should've failed.\n");
423     hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, D3DUSAGE_POINTS, NULL, D3DPOOL_DEFAULT);
424     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckCubeTextureRequirements succeeded, but should've failed.\n");
425     hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, D3DUSAGE_RTPATCHES, NULL, D3DPOOL_DEFAULT);
426     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckCubeTextureRequirements succeeded, but should've failed.\n");
427     hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, D3DUSAGE_NPATCHES, NULL, D3DPOOL_DEFAULT);
428     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckCubeTextureRequirements succeeded, but should've failed.\n");
429
430     /* format */
431     hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
432     ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
433
434     format = D3DFMT_UNKNOWN;
435     hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
436     ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
437     ok(format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_A8R8G8B8);
438
439     format = D3DX_DEFAULT;
440     hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
441     ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
442     ok(format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_A8R8G8B8);
443
444     format = D3DFMT_R8G8B8;
445     hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
446     ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
447     ok(format == D3DFMT_X8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_X8R8G8B8);
448 }
449
450 static void test_D3DXCheckVolumeTextureRequirements(IDirect3DDevice9 *device)
451 {
452     UINT width, height, depth, mipmaps, expected;
453     D3DFORMAT format;
454     D3DCAPS9 caps;
455     HRESULT hr;
456
457     IDirect3DDevice9_GetDeviceCaps(device, &caps);
458
459     if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
460     {
461         skip("No volume textures support\n");
462         return;
463     }
464
465     /* general tests */
466     hr = D3DXCheckVolumeTextureRequirements(device, NULL, NULL, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
467     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
468
469     hr = D3DXCheckVolumeTextureRequirements(device, NULL, NULL, NULL, NULL, D3DX_DEFAULT, NULL, D3DPOOL_DEFAULT);
470     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
471
472     hr = D3DXCheckVolumeTextureRequirements(NULL, NULL, NULL, NULL, NULL, D3DX_DEFAULT, NULL, D3DPOOL_DEFAULT);
473     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
474
475     /* width, height, depth */
476     width = height = depth = D3DX_DEFAULT;
477     hr = D3DXCheckVolumeTextureRequirements(device, &width, &height, &depth, NULL, 0, NULL, D3DPOOL_DEFAULT);
478     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
479     ok(width == 256, "Returned width %d, expected %d\n", width, 256);
480     ok(height == 256, "Returned height %d, expected %d\n", height, 256);
481     ok(depth == 1, "Returned depth %d, expected %d\n", depth, 1);
482
483     width = D3DX_DEFAULT;
484     hr = D3DXCheckVolumeTextureRequirements(device, &width, NULL, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
485     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
486     ok(width == 256, "Returned width %d, expected %d\n", width, 256);
487
488     width = D3DX_DEFAULT; height = 0; depth = 0;
489     hr = D3DXCheckVolumeTextureRequirements(device, &width, &height, &depth, NULL, 0, NULL, D3DPOOL_DEFAULT);
490     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
491     ok(width == 1, "Returned width %d, expected %d\n", width, 1);
492     ok(height == 1, "Returned height %d, expected %d\n", height, 1);
493     ok(depth == 1, "Returned height %d, expected %d\n", depth, 1);
494
495     width = 0; height = 0; depth = 0;
496     hr = D3DXCheckVolumeTextureRequirements(device, &width, &height, &depth, NULL, 0, NULL, D3DPOOL_DEFAULT);
497     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
498     ok(width == 1, "Returned width %d, expected %d\n", width, 1);
499     ok(height == 1, "Returned height %d, expected %d\n", height, 1);
500     ok(depth == 1, "Returned height %d, expected %d\n", depth, 1);
501
502     width = 0;
503     hr = D3DXCheckVolumeTextureRequirements(device, &width, NULL, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
504     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
505     ok(width == 1, "Returned width %d, expected %d\n", width, 1);
506
507     width = 0xFFFFFFFE;
508     hr = D3DXCheckVolumeTextureRequirements(device, &width, NULL, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
509     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
510     ok(width == caps.MaxVolumeExtent, "Returned width %d, expected %d\n", width, caps.MaxVolumeExtent);
511
512     /* format */
513     hr = D3DXCheckVolumeTextureRequirements(device, NULL, NULL, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
514     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
515
516     format = D3DFMT_UNKNOWN;
517     hr = D3DXCheckVolumeTextureRequirements(device, NULL, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
518     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
519     ok(format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_A8R8G8B8);
520
521     format = D3DX_DEFAULT;
522     hr = D3DXCheckVolumeTextureRequirements(device, NULL, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
523     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
524     ok(format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_A8R8G8B8);
525
526     format = D3DFMT_R8G8B8;
527     hr = D3DXCheckVolumeTextureRequirements(device, NULL, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
528     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
529     ok(format == D3DFMT_X8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_X8R8G8B8);
530
531     /* mipmaps */
532     if (!(caps.TextureCaps & D3DPTEXTURECAPS_MIPVOLUMEMAP))
533     {
534         skip("No volume textures mipmapping support\n");
535         return;
536     }
537
538     width = height = depth = 64;
539     mipmaps = 9;
540     hr = D3DXCheckVolumeTextureRequirements(device, &width, &height, &depth, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
541     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
542     ok(mipmaps == 7, "Returned mipmaps %d, expected %d\n", mipmaps, 7);
543
544     width = 284;
545     height = 143;
546     depth = 55;
547     mipmaps = 20;
548     expected = caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP_POW2 ? 10 : 9;
549     hr = D3DXCheckVolumeTextureRequirements(device, &width, &height, &depth, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
550     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
551     ok(mipmaps == expected, "Returned mipmaps %d, expected %d\n", mipmaps, expected);
552
553     mipmaps = 0;
554     hr = D3DXCheckVolumeTextureRequirements(device, NULL, NULL, NULL, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
555     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
556     ok(mipmaps == 9, "Returned mipmaps %d, expected %d\n", mipmaps, 9);
557
558     if (!is_autogenmipmap_supported(device, D3DRTYPE_VOLUMETEXTURE))
559     {
560         skip("No D3DUSAGE_AUTOGENMIPMAP support for volume textures\n");
561         return;
562     }
563
564     /* mipmaps when D3DUSAGE_AUTOGENMIPMAP is set */
565     mipmaps = 0;
566     hr = D3DXCheckVolumeTextureRequirements(device, NULL, NULL,NULL, &mipmaps, D3DUSAGE_AUTOGENMIPMAP, NULL, D3DPOOL_DEFAULT);
567     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
568     ok(mipmaps == 0, "Returned mipmaps %d, expected %d\n", mipmaps, 0);
569     mipmaps = 1;
570     hr = D3DXCheckVolumeTextureRequirements(device, NULL, NULL,NULL, &mipmaps, D3DUSAGE_AUTOGENMIPMAP, NULL, D3DPOOL_DEFAULT);
571     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
572     ok(mipmaps == 1, "Returned mipmaps %d, expected %d\n", mipmaps, 1);
573     mipmaps = 3;
574     hr = D3DXCheckVolumeTextureRequirements(device, NULL, NULL,NULL, &mipmaps, D3DUSAGE_AUTOGENMIPMAP, NULL, D3DPOOL_DEFAULT);
575     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
576     ok(mipmaps == 0, "Returned mipmaps %d, expected %d\n", mipmaps, 0);
577 }
578
579 static void test_D3DXCreateTexture(IDirect3DDevice9 *device)
580 {
581     IDirect3DTexture9 *texture;
582     D3DSURFACE_DESC desc;
583     D3DCAPS9 caps;
584     UINT mipmaps;
585     HRESULT hr;
586
587     IDirect3DDevice9_GetDeviceCaps(device, &caps);
588
589     hr = D3DXCreateTexture(NULL, 0, 0, 0, 0, D3DX_DEFAULT, D3DPOOL_DEFAULT, NULL);
590     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
591
592     /* width and height tests */
593
594     hr = D3DXCreateTexture(device, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, 0, D3DPOOL_DEFAULT, &texture);
595     ok(hr == D3D_OK, "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3D_OK);
596
597     if (texture)
598     {
599         hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
600         ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
601         ok(desc.Format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", desc.Format, D3DFMT_A8R8G8B8);
602
603         ok(desc.Width == 256, "Returned width %d, expected %d\n", desc.Width, 256);
604         ok(desc.Height == 256, "Returned height %d, expected %d\n", desc.Height, 256);
605
606         IDirect3DTexture9_Release(texture);
607     }
608
609
610     hr = D3DXCreateTexture(device, 0, 0, 0, 0, 0, D3DPOOL_DEFAULT, &texture);
611     ok(hr == D3D_OK, "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3D_OK);
612
613     if (texture)
614     {
615         hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
616         ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
617         ok(desc.Format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", desc.Format, D3DFMT_A8R8G8B8);
618
619         ok(desc.Width == 1, "Returned width %d, expected %d\n", desc.Width, 1);
620         ok(desc.Height == 1, "Returned height %d, expected %d\n", desc.Height, 1);
621
622         IDirect3DTexture9_Release(texture);
623     }
624
625
626     if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
627         skip("Hardware only supports pow2 textures\n");
628     else
629     {
630         hr = D3DXCreateTexture(device, D3DX_DEFAULT, 63, 0, 0, 0, D3DPOOL_DEFAULT, &texture);
631         ok((hr == D3D_OK) ||
632            /* may not work with conditional NPOT */
633            ((hr != D3D_OK) && (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)),
634            "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3D_OK);
635
636         if (texture)
637         {
638             hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
639             ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
640             ok(desc.Format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", desc.Format, D3DFMT_A8R8G8B8);
641
642             /* Conditional NPOT may create a texture with different dimensions, so allow those
643                situations instead of returning a fail */
644
645             ok(desc.Width == 63 ||
646                (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL),
647                "Returned width %d, expected %d\n", desc.Width, 63);
648
649             ok(desc.Height == 63 ||
650                (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL),
651                "Returned height %d, expected %d\n", desc.Height, 63);
652
653             IDirect3DTexture9_Release(texture);
654         }
655     }
656
657     /* mipmaps */
658
659     hr = D3DXCreateTexture(device, 64, 63, 9, 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         mipmaps = IDirect3DTexture9_GetLevelCount(texture);
665         ok(mipmaps == 7, "Returned mipmaps %d, expected %d\n", mipmaps, 7);
666
667         IDirect3DTexture9_Release(texture);
668     }
669
670
671     hr = D3DXCreateTexture(device, 284, 137, 9, 0, 0, D3DPOOL_DEFAULT, &texture);
672     ok(hr == D3D_OK, "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3D_OK);
673
674     if (texture)
675     {
676         mipmaps = IDirect3DTexture9_GetLevelCount(texture);
677         ok(mipmaps == 9, "Returned mipmaps %d, expected %d\n", mipmaps, 9);
678
679         IDirect3DTexture9_Release(texture);
680     }
681
682
683     hr = D3DXCreateTexture(device, 0, 0, 20, 0, 0, D3DPOOL_DEFAULT, &texture);
684     ok(hr == D3D_OK, "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3D_OK);
685
686     if (texture)
687     {
688         mipmaps = IDirect3DTexture9_GetLevelCount(texture);
689         ok(mipmaps == 1, "Returned mipmaps %d, expected %d\n", mipmaps, 1);
690
691         IDirect3DTexture9_Release(texture);
692     }
693
694
695     hr = D3DXCreateTexture(device, 64, 64, 1, 0, 0, D3DPOOL_DEFAULT, &texture);
696     ok(hr == D3D_OK, "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3D_OK);
697
698     if (texture)
699     {
700         mipmaps = IDirect3DTexture9_GetLevelCount(texture);
701         ok(mipmaps == 1, "Returned mipmaps %d, expected %d\n", mipmaps, 1);
702
703         IDirect3DTexture9_Release(texture);
704     }
705
706     /* usage */
707
708     hr = D3DXCreateTexture(device, 0, 0, 0, D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &texture);
709     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTexture succeeded, but should have failed.\n");
710     hr = D3DXCreateTexture(device, 0, 0, 0, D3DUSAGE_DONOTCLIP, 0, D3DPOOL_DEFAULT, &texture);
711     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTexture succeeded, but should have failed.\n");
712     hr = D3DXCreateTexture(device, 0, 0, 0, D3DUSAGE_POINTS, 0, D3DPOOL_DEFAULT, &texture);
713     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTexture succeeded, but should have failed.\n");
714     hr = D3DXCreateTexture(device, 0, 0, 0, D3DUSAGE_RTPATCHES, 0, D3DPOOL_DEFAULT, &texture);
715     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTexture succeeded, but should have failed.\n");
716     hr = D3DXCreateTexture(device, 0, 0, 0, D3DUSAGE_NPATCHES, 0, D3DPOOL_DEFAULT, &texture);
717     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTexture succeeded, but should have failed.\n");
718
719     /* format */
720
721     hr = D3DXCreateTexture(device, 0, 0, 0, 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, &texture);
722     ok(hr == D3D_OK, "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3D_OK);
723
724     if (texture)
725     {
726         hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
727         ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
728         ok(desc.Format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", desc.Format, D3DFMT_A8R8G8B8);
729
730         IDirect3DTexture9_Release(texture);
731     }
732
733
734     hr = D3DXCreateTexture(device, 0, 0, 0, 0, 0, D3DPOOL_DEFAULT, &texture);
735     ok(hr == D3D_OK, "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3D_OK);
736
737     if (texture)
738     {
739         hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
740         ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
741         ok(desc.Format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", desc.Format, D3DFMT_A8R8G8B8);
742
743         IDirect3DTexture9_Release(texture);
744     }
745
746     /* D3DXCreateTextureFromResource */
747     todo_wine {
748         hr = D3DXCreateTextureFromResourceA(device, NULL, MAKEINTRESOURCEA(IDB_BITMAP_1x1), &texture);
749         ok(hr == D3D_OK, "D3DXCreateTextureFromResource returned %#x, expected %#x\n", hr, D3D_OK);
750         if (SUCCEEDED(hr)) IDirect3DTexture9_Release(texture);
751     }
752     hr = D3DXCreateTextureFromResourceA(device, NULL, MAKEINTRESOURCEA(IDD_BITMAPDATA_1x1), &texture);
753     ok(hr == D3D_OK, "D3DXCreateTextureFromResource returned %#x, expected %#x\n", hr, D3D_OK);
754     if (SUCCEEDED(hr)) IDirect3DTexture9_Release(texture);
755
756     hr = D3DXCreateTextureFromResourceA(device, NULL, MAKEINTRESOURCEA(IDS_STRING), &texture);
757     ok(hr == D3DXERR_INVALIDDATA, "D3DXCreateTextureFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
758
759     hr = D3DXCreateTextureFromResourceA(NULL, NULL, MAKEINTRESOURCEA(IDD_BITMAPDATA_1x1), &texture);
760     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTextureFromResource returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
761
762     hr = D3DXCreateTextureFromResourceA(device, NULL, NULL, &texture);
763     ok(hr == D3DXERR_INVALIDDATA, "D3DXCreateTextureFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
764
765     hr = D3DXCreateTextureFromResourceA(device, NULL, MAKEINTRESOURCEA(IDD_BITMAPDATA_1x1), NULL);
766     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTextureFromResource returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
767
768
769     /* D3DXCreateTextureFromResourceEx */
770     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);
771     ok(hr == D3D_OK, "D3DXCreateTextureFromResourceEx returned %#x, expected %#x\n", hr, D3D_OK);
772     if (SUCCEEDED(hr)) IDirect3DTexture9_Release(texture);
773
774     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);
775     ok(hr == D3DXERR_INVALIDDATA, "D3DXCreateTextureFromResourceEx returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
776
777     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);
778     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTextureFromResourceEx returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
779
780     hr = D3DXCreateTextureFromResourceExA(device, NULL, NULL, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texture);
781     ok(hr == D3DXERR_INVALIDDATA, "D3DXCreateTextureFromResourceEx returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
782
783     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);
784     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTextureFromResourceEx returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
785 }
786
787 static void test_D3DXFilterTexture(IDirect3DDevice9 *device)
788 {
789     IDirect3DTexture9 *tex;
790     IDirect3DCubeTexture9 *cubetex;
791     IDirect3DVolumeTexture9 *voltex;
792     HRESULT hr;
793
794     hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 5, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex, NULL);
795
796     if (SUCCEEDED(hr))
797     {
798         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, D3DX_DEFAULT, D3DX_FILTER_NONE);
799         ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
800
801         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_NONE);
802         ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
803
804         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_BOX + 1); /* Invalid filter */
805         ok(hr == D3DERR_INVALIDCALL, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
806
807         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 5, D3DX_FILTER_NONE); /* Invalid miplevel */
808         ok(hr == D3DERR_INVALIDCALL, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
809
810         IDirect3DTexture9_Release(tex);
811     }
812     else
813         skip("Failed to create texture\n");
814
815     hr = D3DXFilterTexture(NULL, NULL, 0, D3DX_FILTER_NONE);
816     ok(hr == D3DERR_INVALIDCALL, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
817
818     /* Test different pools */
819     hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &tex, NULL);
820
821     if (SUCCEEDED(hr))
822     {
823         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_NONE);
824         ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
825         IDirect3DTexture9_Release(tex);
826     }
827     else
828         skip("Failed to create texture\n");
829
830     hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &tex, NULL);
831
832     if (SUCCEEDED(hr))
833     {
834         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_NONE);
835         ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
836         IDirect3DTexture9_Release(tex);
837     }
838     else
839         skip("Failed to create texture\n");
840
841     hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex, NULL);
842     if (SUCCEEDED(hr))
843     {
844         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_POINT);
845         ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
846         IDirect3DTexture9_Release(tex);
847     }
848     else
849         skip("Failed to create texture\n");
850
851     hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 0, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex, NULL);
852     if (SUCCEEDED(hr))
853     {
854         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_POINT);
855         ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
856         IDirect3DTexture9_Release(tex);
857     }
858     else
859         skip("Failed to create texture\n");
860
861     /* Cube texture test */
862     hr = IDirect3DDevice9_CreateCubeTexture(device, 256, 5, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &cubetex, NULL);
863
864     if (SUCCEEDED(hr))
865     {
866         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) cubetex, NULL, 0, D3DX_FILTER_NONE);
867         ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
868
869         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) cubetex, NULL, 0, D3DX_FILTER_BOX + 1); /* Invalid filter */
870         ok(hr == D3DERR_INVALIDCALL, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
871
872         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) cubetex, NULL, 5, D3DX_FILTER_NONE); /* Invalid miplevel */
873         ok(hr == D3DERR_INVALIDCALL, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
874         IDirect3DCubeTexture9_Release(cubetex);
875     }
876     else
877         skip("Failed to create texture\n");
878
879     /* Volume texture test */
880     hr = IDirect3DDevice9_CreateVolumeTexture(device, 256, 256, 4, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &voltex, NULL);
881     if (SUCCEEDED(hr))
882     {
883         DWORD level_count = IDirect3DVolumeTexture9_GetLevelCount(voltex);
884
885         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) voltex, NULL, 0, D3DX_FILTER_NONE);
886         ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
887
888         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) voltex, NULL, 0, D3DX_DEFAULT);
889         ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
890
891         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) voltex, NULL, 0, D3DX_FILTER_BOX);
892         ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
893
894         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) voltex, NULL, level_count - 1, D3DX_DEFAULT);
895         ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
896
897         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) voltex, NULL, level_count, D3DX_DEFAULT);
898         ok(hr == D3DERR_INVALIDCALL, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
899
900         IDirect3DVolumeTexture9_Release(voltex);
901     }
902     else
903         skip("Failed to create volume texture\n");
904
905     /* Test textures with D3DUSAGE_AUTOGENMIPMAP usage */
906     if (!is_autogenmipmap_supported(device, D3DRTYPE_TEXTURE))
907     {
908         skip("No D3DUSAGE_AUTOGENMIPMAP supported for textures\n");
909         return;
910     }
911
912     hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 0, D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex, NULL);
913     if (SUCCEEDED(hr))
914     {
915         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_NONE);
916         ok(hr == D3D_OK, "D3dXFilteTexture returned %#x, expected %#x\n", hr, D3D_OK);
917         IDirect3DTexture9_Release(tex);
918     }
919     else
920         skip("Failed to create texture\n");
921
922     hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex, NULL);
923     if (SUCCEEDED(hr))
924     {
925         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_NONE);
926         ok(hr == D3D_OK, "D3dXFilteTexture returned %#x, expected %#x\n", hr, D3D_OK);
927         IDirect3DTexture9_Release(tex);
928     }
929     else
930         skip("Failed to create texture\n");
931 }
932
933 static BOOL color_match(const DWORD *value, const DWORD *expected)
934 {
935     int i;
936
937     for (i = 0; i < 4; i++)
938     {
939         DWORD diff = value[i] > expected[i] ? value[i] - expected[i] : expected[i] - value[i];
940         if (diff > 1) return FALSE;
941     }
942     return TRUE;
943 }
944
945 static void WINAPI fillfunc(D3DXVECTOR4 *value, const D3DXVECTOR2 *texcoord,
946                             const D3DXVECTOR2 *texelsize, void *data)
947 {
948     value->x = texcoord->x;
949     value->y = texcoord->y;
950     value->z = texelsize->x;
951     value->w = 1.0f;
952 }
953
954 static void test_D3DXFillTexture(IDirect3DDevice9 *device)
955 {
956     IDirect3DTexture9 *tex;
957     HRESULT hr;
958     D3DLOCKED_RECT lock_rect;
959     DWORD x, y, m;
960     DWORD v[4], e[4];
961     DWORD value, expected, size, pitch;
962
963     size = 4;
964     hr = IDirect3DDevice9_CreateTexture(device, size, size, 0, 0, D3DFMT_A8R8G8B8,
965                                         D3DPOOL_MANAGED, &tex, NULL);
966
967     if (SUCCEEDED(hr))
968     {
969         hr = D3DXFillTexture(tex, fillfunc, NULL);
970         ok(hr == D3D_OK, "D3DXFillTexture returned %#x, expected %#x\n", hr, D3D_OK);
971
972         for (m = 0; m < 3; m++)
973         {
974             hr = IDirect3DTexture9_LockRect(tex, m, &lock_rect, NULL, D3DLOCK_READONLY);
975             ok(hr == D3D_OK, "Couldn't lock the texture, error %#x\n", hr);
976             if (SUCCEEDED(hr))
977             {
978                 pitch = lock_rect.Pitch / sizeof(DWORD);
979                 for (y = 0; y < size; y++)
980                 {
981                     for (x = 0; x < size; x++)
982                     {
983                         value = ((DWORD *)lock_rect.pBits)[y * pitch + x];
984                         v[0] = (value >> 24) & 0xff;
985                         v[1] = (value >> 16) & 0xff;
986                         v[2] = (value >> 8) & 0xff;
987                         v[3] = value & 0xff;
988
989                         e[0] = 0xff;
990                         e[1] = (x + 0.5f) / size * 255.0f + 0.5f;
991                         e[2] = (y + 0.5f) / size * 255.0f + 0.5f;
992                         e[3] = 255.0f / size + 0.5f;
993                         expected = e[0] << 24 | e[1] << 16 | e[2] << 8 | e[3];
994
995                         ok(color_match(v, e),
996                            "Texel at (%u, %u) doesn't match: %#x, expected %#x\n",
997                            x, y, value, expected);
998                     }
999                 }
1000                 IDirect3DTexture9_UnlockRect(tex, m);
1001             }
1002             size >>= 1;
1003         }
1004
1005         IDirect3DTexture9_Release(tex);
1006     }
1007     else
1008         skip("Failed to create texture\n");
1009
1010     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_A1R5G5B5,
1011                                         D3DPOOL_MANAGED, &tex, NULL);
1012
1013     if (SUCCEEDED(hr))
1014     {
1015         hr = D3DXFillTexture(tex, fillfunc, NULL);
1016         ok(hr == D3D_OK, "D3DXFillTexture returned %#x, expected %#x\n", hr, D3D_OK);
1017
1018         hr = IDirect3DTexture9_LockRect(tex, 0, &lock_rect, NULL, D3DLOCK_READONLY);
1019         ok(hr == D3D_OK, "Couldn't lock the texture, error %#x\n", hr);
1020         if (SUCCEEDED(hr))
1021         {
1022             pitch = lock_rect.Pitch / sizeof(WORD);
1023             for (y = 0; y < 4; y++)
1024             {
1025                 for (x = 0; x < 4; x++)
1026                 {
1027                     value = ((WORD *)lock_rect.pBits)[y * pitch + x];
1028                     v[0] = value >> 15;
1029                     v[1] = value >> 10 & 0x1f;
1030                     v[2] = value >> 5 & 0x1f;
1031                     v[3] = value & 0x1f;
1032
1033                     e[0] = 1;
1034                     e[1] = (x + 0.5f) / 4.0f * 31.0f + 0.5f;
1035                     e[2] = (y + 0.5f) / 4.0f * 31.0f + 0.5f;
1036                     e[3] = 8;
1037                     expected = e[0] << 15 | e[1] << 10 | e[2] << 5 | e[3];
1038
1039                     ok(color_match(v, e),
1040                        "Texel at (%u, %u) doesn't match: %#x, expected %#x\n",
1041                        x, y, value, expected);
1042                 }
1043             }
1044             IDirect3DTexture9_UnlockRect(tex, 0);
1045         }
1046
1047         IDirect3DTexture9_Release(tex);
1048     }
1049     else
1050         skip("Failed to create texture\n");
1051
1052     /* test floating-point textures */
1053     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_A16B16G16R16F,
1054                                         D3DPOOL_MANAGED, &tex, NULL);
1055
1056     if (SUCCEEDED(hr))
1057     {
1058         hr = D3DXFillTexture(tex, fillfunc, NULL);
1059         todo_wine ok(hr == D3D_OK, "D3DXFillTexture returned %#x, expected %#x\n", hr, D3D_OK);
1060
1061         hr = IDirect3DTexture9_LockRect(tex, 0, &lock_rect, NULL, D3DLOCK_READONLY);
1062         if (SUCCEEDED(hr))
1063         {
1064             pitch = lock_rect.Pitch / sizeof(WORD);
1065             for (y = 0; y < 4; y++)
1066             {
1067                 WORD *ptr = (WORD *)lock_rect.pBits + y * pitch;
1068                 for (x = 0; x < 4; x++)
1069                 {
1070                     D3DXVECTOR4 got, expected;
1071
1072                     got.x = float_16_to_32(*ptr++);
1073                     got.y = float_16_to_32(*ptr++);
1074                     got.z = float_16_to_32(*ptr++);
1075                     got.w = float_16_to_32(*ptr++);
1076
1077                     expected.x = (x + 0.5f) / 4.0f;
1078                     expected.y = (y + 0.5f) / 4.0f;
1079                     expected.z = 1.0f / 4.0f;
1080                     expected.w = 1.0f;
1081
1082                     todo_wine expect_vec4(&expected, &got);
1083                 }
1084             }
1085
1086             IDirect3DTexture9_UnlockRect(tex, 0);
1087         }
1088         else
1089             skip("Failed to lock texture\n");
1090
1091         IDirect3DTexture9_Release(tex);
1092     }
1093     else
1094         skip("Failed to create D3DFMT_A16B16G16R16F texture\n");
1095
1096     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_A32B32G32R32F,
1097                                         D3DPOOL_MANAGED, &tex, NULL);
1098
1099     if (SUCCEEDED(hr))
1100     {
1101         hr = D3DXFillTexture(tex, fillfunc, NULL);
1102         todo_wine ok(hr == D3D_OK, "D3DXFillTexture returned %#x, expected %#x\n", hr, D3D_OK);
1103
1104         hr = IDirect3DTexture9_LockRect(tex, 0, &lock_rect, NULL, D3DLOCK_READONLY);
1105         if (SUCCEEDED(hr))
1106         {
1107             pitch = lock_rect.Pitch / sizeof(float);
1108             for (y = 0; y < 4; y++)
1109             {
1110                 float *ptr = (float *)lock_rect.pBits + y * pitch;
1111                 for (x = 0; x < 4; x++)
1112                 {
1113                     D3DXVECTOR4 got, expected;
1114
1115                     got.x = *ptr++;
1116                     got.y = *ptr++;
1117                     got.z = *ptr++;
1118                     got.w = *ptr++;
1119
1120                     expected.x = (x + 0.5f) / 4.0f;
1121                     expected.y = (y + 0.5f) / 4.0f;
1122                     expected.z = 1.0f / 4.0f;
1123                     expected.w = 1.0f;
1124
1125                     todo_wine expect_vec4(&expected, &got);
1126                 }
1127             }
1128
1129             IDirect3DTexture9_UnlockRect(tex, 0);
1130         }
1131         else
1132             skip("Failed to lock texture\n");
1133
1134         IDirect3DTexture9_Release(tex);
1135     }
1136     else
1137         skip("Failed to create D3DFMT_A32B32G32R32F texture\n");
1138
1139     /* test a compressed texture */
1140     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_DXT1,
1141                                         D3DPOOL_MANAGED, &tex, NULL);
1142
1143     if (SUCCEEDED(hr))
1144     {
1145         hr = D3DXFillTexture(tex, fillfunc, NULL);
1146         todo_wine ok(hr == D3D_OK, "D3DXFillTexture returned %#x, expected %#x\n", hr, D3D_OK);
1147
1148         IDirect3DTexture9_Release(tex);
1149     }
1150     else
1151         skip("Failed to create D3DFMT_DXT1 texture\n");
1152 }
1153
1154 static void WINAPI fillfunc_cube(D3DXVECTOR4 *value, const D3DXVECTOR3 *texcoord,
1155                                  const D3DXVECTOR3 *texelsize, void *data)
1156 {
1157     value->x = (texcoord->x + 1.0f) / 2.0f;
1158     value->y = (texcoord->y + 1.0f) / 2.0f;
1159     value->z = (texcoord->z + 1.0f) / 2.0f;
1160     value->w = texelsize->x;
1161 }
1162
1163 enum cube_coord
1164 {
1165     XCOORD = 0,
1166     XCOORDINV = 1,
1167     YCOORD = 2,
1168     YCOORDINV = 3,
1169     ZERO = 4,
1170     ONE = 5
1171 };
1172
1173 static float get_cube_coord(enum cube_coord coord, unsigned int x, unsigned int y, unsigned int size)
1174 {
1175     switch (coord)
1176     {
1177         case XCOORD:
1178             return x + 0.5f;
1179         case XCOORDINV:
1180             return size - x - 0.5f;
1181         case YCOORD:
1182             return y + 0.5f;
1183         case YCOORDINV:
1184             return size - y - 0.5f;
1185         case ZERO:
1186             return 0.0f;
1187         case ONE:
1188             return size;
1189         default:
1190            trace("Unexpected coordinate value\n");
1191            return 0.0f;
1192     }
1193 }
1194
1195 static void test_D3DXFillCubeTexture(IDirect3DDevice9 *device)
1196 {
1197     IDirect3DCubeTexture9 *tex;
1198     HRESULT hr;
1199     D3DLOCKED_RECT lock_rect;
1200     DWORD x, y, f, m;
1201     DWORD v[4], e[4];
1202     DWORD value, expected, size, pitch;
1203     enum cube_coord coordmap[6][3] =
1204         {
1205             {ONE, YCOORDINV, XCOORDINV},
1206             {ZERO, YCOORDINV, XCOORD},
1207             {XCOORD, ONE, YCOORD},
1208             {XCOORD, ZERO, YCOORDINV},
1209             {XCOORD, YCOORDINV, ONE},
1210             {XCOORDINV, YCOORDINV, ZERO}
1211         };
1212
1213     size = 4;
1214     hr = IDirect3DDevice9_CreateCubeTexture(device, size, 0, 0, D3DFMT_A8R8G8B8,
1215                                             D3DPOOL_MANAGED, &tex, NULL);
1216
1217     if (SUCCEEDED(hr))
1218     {
1219         hr = D3DXFillCubeTexture(tex, fillfunc_cube, NULL);
1220         ok(hr == D3D_OK, "D3DXFillCubeTexture returned %#x, expected %#x\n", hr, D3D_OK);
1221
1222         for (m = 0; m < 3; m++)
1223         {
1224             for (f = 0; f < 6; f++)
1225             {
1226                 hr = IDirect3DCubeTexture9_LockRect(tex, f, m, &lock_rect, NULL, D3DLOCK_READONLY);
1227                 ok(hr == D3D_OK, "Couldn't lock the texture, error %#x\n", hr);
1228                 if (SUCCEEDED(hr))
1229                 {
1230                     pitch = lock_rect.Pitch / sizeof(DWORD);
1231                     for (y = 0; y < size; y++)
1232                     {
1233                         for (x = 0; x < size; x++)
1234                         {
1235                             value = ((DWORD *)lock_rect.pBits)[y * pitch + x];
1236                             v[0] = (value >> 24) & 0xff;
1237                             v[1] = (value >> 16) & 0xff;
1238                             v[2] = (value >> 8) & 0xff;
1239                             v[3] = value & 0xff;
1240
1241                             e[0] = (f == 0) || (f == 1) ?
1242                                 0 : (BYTE)(255.0f / size * 2.0f + 0.5f);
1243                             e[1] = get_cube_coord(coordmap[f][0], x, y, size) / size * 255.0f + 0.5f;
1244                             e[2] = get_cube_coord(coordmap[f][1], x, y, size) / size * 255.0f + 0.5f;
1245                             e[3] = get_cube_coord(coordmap[f][2], x, y, size) / size * 255.0f + 0.5f;
1246                             expected = e[0] << 24 | e[1] << 16 | e[2] << 8 | e[3];
1247
1248                             ok(color_match(v, e),
1249                                "Texel at face %u (%u, %u) doesn't match: %#x, expected %#x\n",
1250                                f, x, y, value, expected);
1251                         }
1252                     }
1253                     IDirect3DCubeTexture9_UnlockRect(tex, f, m);
1254                 }
1255             }
1256             size >>= 1;
1257         }
1258
1259         IDirect3DCubeTexture9_Release(tex);
1260     }
1261     else
1262         skip("Failed to create texture\n");
1263
1264     hr = IDirect3DDevice9_CreateCubeTexture(device, 4, 1, 0, D3DFMT_A1R5G5B5,
1265                                             D3DPOOL_MANAGED, &tex, NULL);
1266
1267     if (SUCCEEDED(hr))
1268     {
1269         hr = D3DXFillCubeTexture(tex, fillfunc_cube, NULL);
1270         ok(hr == D3D_OK, "D3DXFillTexture returned %#x, expected %#x\n", hr, D3D_OK);
1271         for (f = 0; f < 6; f++)
1272         {
1273             hr = IDirect3DCubeTexture9_LockRect(tex, f, 0, &lock_rect, NULL, D3DLOCK_READONLY);
1274             ok(hr == D3D_OK, "Couldn't lock the texture, error %#x\n", hr);
1275             if (SUCCEEDED(hr))
1276             {
1277                 pitch = lock_rect.Pitch / sizeof(WORD);
1278                 for (y = 0; y < 4; y++)
1279                 {
1280                     for (x = 0; x < 4; x++)
1281                     {
1282                         value = ((WORD *)lock_rect.pBits)[y * pitch + x];
1283                         v[0] = value >> 15;
1284                         v[1] = value >> 10 & 0x1f;
1285                         v[2] = value >> 5 & 0x1f;
1286                         v[3] = value & 0x1f;
1287
1288                         e[0] = (f == 0) || (f == 1) ?
1289                             0 : (BYTE)(1.0f / size * 2.0f + 0.5f);
1290                         e[1] = get_cube_coord(coordmap[f][0], x, y, 4) / 4 * 31.0f + 0.5f;
1291                         e[2] = get_cube_coord(coordmap[f][1], x, y, 4) / 4 * 31.0f + 0.5f;
1292                         e[3] = get_cube_coord(coordmap[f][2], x, y, 4) / 4 * 31.0f + 0.5f;
1293                         expected = e[0] << 15 | e[1] << 10 | e[2] << 5 | e[3];
1294
1295                         ok(color_match(v, e),
1296                            "Texel at face %u (%u, %u) doesn't match: %#x, expected %#x\n",
1297                            f, x, y, value, expected);
1298                     }
1299                 }
1300                 IDirect3DCubeTexture9_UnlockRect(tex, f, 0);
1301             }
1302         }
1303
1304         IDirect3DCubeTexture9_Release(tex);
1305     }
1306     else
1307         skip("Failed to create texture\n");
1308 }
1309
1310 static void WINAPI fillfunc_volume(D3DXVECTOR4 *value, const D3DXVECTOR3 *texcoord,
1311                                    const D3DXVECTOR3 *texelsize, void *data)
1312 {
1313     value->x = texcoord->x;
1314     value->y = texcoord->y;
1315     value->z = texcoord->z;
1316     value->w = texelsize->x;
1317 }
1318
1319 static void test_D3DXFillVolumeTexture(IDirect3DDevice9 *device)
1320 {
1321     IDirect3DVolumeTexture9 *tex;
1322     HRESULT hr;
1323     D3DLOCKED_BOX lock_box;
1324     DWORD x, y, z, m;
1325     DWORD v[4], e[4];
1326     DWORD value, expected, size, row_pitch, slice_pitch;
1327
1328     size = 4;
1329     hr = IDirect3DDevice9_CreateVolumeTexture(device, size, size, size, 0, 0, D3DFMT_A8R8G8B8,
1330                                               D3DPOOL_MANAGED, &tex, NULL);
1331
1332     if (SUCCEEDED(hr))
1333     {
1334         hr = D3DXFillVolumeTexture(tex, fillfunc_volume, NULL);
1335         ok(hr == D3D_OK, "D3DXFillVolumeTexture returned %#x, expected %#x\n", hr, D3D_OK);
1336
1337         for (m = 0; m < 3; m++)
1338         {
1339             hr = IDirect3DVolumeTexture9_LockBox(tex, m, &lock_box, NULL, D3DLOCK_READONLY);
1340             ok(hr == D3D_OK, "Couldn't lock the texture, error %#x\n", hr);
1341             if (SUCCEEDED(hr))
1342             {
1343                 row_pitch = lock_box.RowPitch / sizeof(DWORD);
1344                 slice_pitch = lock_box.SlicePitch / sizeof(DWORD);
1345                 for (z = 0; z < size; z++)
1346                 {
1347                     for (y = 0; y < size; y++)
1348                     {
1349                         for (x = 0; x < size; x++)
1350                         {
1351                             value = ((DWORD *)lock_box.pBits)[z * slice_pitch + y * row_pitch + x];
1352                             v[0] = (value >> 24) & 0xff;
1353                             v[1] = (value >> 16) & 0xff;
1354                             v[2] = (value >> 8) & 0xff;
1355                             v[3] = value & 0xff;
1356
1357                             e[0] = 255.0f / size + 0.5f;
1358                             e[1] = (x + 0.5f) / size * 255.0f + 0.5f;
1359                             e[2] = (y + 0.5f) / size * 255.0f + 0.5f;
1360                             e[3] = (z + 0.5f) / size * 255.0f + 0.5f;
1361                             expected = e[0] << 24 | e[1] << 16 | e[2] << 8 | e[3];
1362
1363                             ok(color_match(v, e),
1364                                "Texel at (%u, %u, %u) doesn't match: %#x, expected %#x\n",
1365                                x, y, z, value, expected);
1366                         }
1367                     }
1368                 }
1369                 IDirect3DVolumeTexture9_UnlockBox(tex, m);
1370             }
1371             size >>= 1;
1372         }
1373
1374         IDirect3DVolumeTexture9_Release(tex);
1375     }
1376     else
1377         skip("Failed to create texture\n");
1378
1379     hr = IDirect3DDevice9_CreateVolumeTexture(device, 4, 4, 4, 1, 0, D3DFMT_A1R5G5B5,
1380                                               D3DPOOL_MANAGED, &tex, NULL);
1381
1382     if (SUCCEEDED(hr))
1383     {
1384         hr = D3DXFillVolumeTexture(tex, fillfunc_volume, NULL);
1385         ok(hr == D3D_OK, "D3DXFillTexture returned %#x, expected %#x\n", hr, D3D_OK);
1386         hr = IDirect3DVolumeTexture9_LockBox(tex, 0, &lock_box, NULL, D3DLOCK_READONLY);
1387         ok(hr == D3D_OK, "Couldn't lock the texture, error %#x\n", hr);
1388         if (SUCCEEDED(hr))
1389         {
1390             row_pitch = lock_box.RowPitch / sizeof(WORD);
1391             slice_pitch = lock_box.SlicePitch / sizeof(WORD);
1392             for (z = 0; z < 4; z++)
1393             {
1394                 for (y = 0; y < 4; y++)
1395                 {
1396                     for (x = 0; x < 4; x++)
1397                     {
1398                         value = ((WORD *)lock_box.pBits)[z * slice_pitch + y * row_pitch + x];
1399                         v[0] = value >> 15;
1400                         v[1] = value >> 10 & 0x1f;
1401                         v[2] = value >> 5 & 0x1f;
1402                         v[3] = value & 0x1f;
1403
1404                         e[0] = 1;
1405                         e[1] = (x + 0.5f) / 4 * 31.0f + 0.5f;
1406                         e[2] = (y + 0.5f) / 4 * 31.0f + 0.5f;
1407                         e[3] = (z + 0.5f) / 4 * 31.0f + 0.5f;
1408                         expected = e[0] << 15 | e[1] << 10 | e[2] << 5 | e[3];
1409
1410                         ok(color_match(v, e),
1411                            "Texel at (%u, %u, %u) doesn't match: %#x, expected %#x\n",
1412                            x, y, z, value, expected);
1413                     }
1414                 }
1415             }
1416             IDirect3DVolumeTexture9_UnlockBox(tex, 0);
1417         }
1418
1419         IDirect3DVolumeTexture9_Release(tex);
1420     }
1421     else
1422         skip("Failed to create texture\n");
1423 }
1424
1425 static void test_D3DXCreateTextureFromFileInMemory(IDirect3DDevice9 *device)
1426 {
1427     HRESULT hr;
1428     IDirect3DTexture9 *texture;
1429     D3DRESOURCETYPE type;
1430     D3DSURFACE_DESC desc;
1431     D3DLOCKED_RECT lock_rect;
1432     int i;
1433
1434     hr = D3DXCreateTextureFromFileInMemory(device, dds_16bit, sizeof(dds_16bit), &texture);
1435     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
1436     if (SUCCEEDED(hr)) IDirect3DTexture9_Release(texture);
1437
1438     hr = D3DXCreateTextureFromFileInMemory(device, dds_24bit, sizeof(dds_24bit), &texture);
1439     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
1440     if (SUCCEEDED(hr)) IDirect3DTexture9_Release(texture);
1441
1442     hr = D3DXCreateTextureFromFileInMemory(device, dds_24bit, sizeof(dds_24bit) - 1, &texture);
1443     ok(hr == D3DXERR_INVALIDDATA, "D3DXCreateTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
1444
1445     /* Check that D3DXCreateTextureFromFileInMemory accepts cube texture dds file (only first face texture is loaded) */
1446     hr = D3DXCreateTextureFromFileInMemory(device, dds_cube_map, sizeof(dds_cube_map), &texture);
1447     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
1448     if (SUCCEEDED(hr))
1449     {
1450         type = IDirect3DTexture9_GetType(texture);
1451         ok(type == D3DRTYPE_TEXTURE, "IDirect3DTexture9_GetType returned %u, expected %u\n", type, D3DRTYPE_TEXTURE);
1452         hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
1453         ok(hr == D3D_OK, "IDirect3DTexture9_GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
1454         ok(desc.Width == 4, "Width is %u, expected 4\n", desc.Width);
1455         ok(desc.Height == 4, "Height is %u, expected 4\n", desc.Height);
1456         hr = IDirect3DTexture9_LockRect(texture, 0, &lock_rect, NULL, D3DLOCK_READONLY);
1457         ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %#x, expected %#x\n", hr, D3D_OK);
1458         if (SUCCEEDED(hr))
1459         {
1460             for (i = 0; i < 16; i++)
1461                 ok(((BYTE*)lock_rect.pBits)[i] == dds_cube_map[128+i], "Byte at index %u is 0x%02x, expected 0x%02x\n", i, ((BYTE*)lock_rect.pBits)[i], dds_cube_map[144+i]);
1462             IDirect3DTexture9_UnlockRect(texture, 0);
1463         }
1464         IDirect3DTexture9_Release(texture);
1465
1466     }
1467 }
1468
1469 static void test_D3DXCreateTextureFromFileInMemoryEx(IDirect3DDevice9 *device)
1470 {
1471     HRESULT hr;
1472     IDirect3DTexture9 *texture;
1473
1474     hr = D3DXCreateTextureFromFileInMemoryEx(device, dds_16bit, sizeof(dds_16bit), D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT,
1475         0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texture);
1476     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x\n", hr, D3D_OK);
1477     if (SUCCEEDED(hr)) IDirect3DTexture9_Release(texture);
1478
1479     hr = D3DXCreateTextureFromFileInMemoryEx(device, dds_16bit, sizeof(dds_16bit), D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT,
1480         D3DUSAGE_DYNAMIC, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texture);
1481     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x\n", hr, D3D_OK);
1482     if (SUCCEEDED(hr)) IDirect3DTexture9_Release(texture);
1483
1484     if (!is_autogenmipmap_supported(device, D3DRTYPE_TEXTURE))
1485     {
1486         skip("No D3DUSAGE_AUTOGENMIPMAP support for textures\n");
1487         return;
1488     }
1489
1490     hr = D3DXCreateTextureFromFileInMemoryEx(device, dds_16bit, sizeof(dds_16bit), D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT,
1491         D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texture);
1492     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x\n", hr, D3D_OK);
1493     if (SUCCEEDED(hr)) IDirect3DTexture9_Release(texture);
1494 }
1495
1496 static void test_D3DXCreateCubeTextureFromFileInMemory(IDirect3DDevice9 *device)
1497 {
1498     HRESULT hr;
1499     ULONG ref;
1500     DWORD levelcount;
1501     IDirect3DCubeTexture9 *cube_texture;
1502     D3DSURFACE_DESC surface_desc;
1503
1504     hr = D3DXCreateCubeTextureFromFileInMemory(NULL, dds_cube_map, sizeof(dds_cube_map), &cube_texture);
1505     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateCubeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
1506
1507     hr = D3DXCreateCubeTextureFromFileInMemory(device, NULL, sizeof(dds_cube_map), &cube_texture);
1508     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateCubeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
1509
1510     hr = D3DXCreateCubeTextureFromFileInMemory(device, dds_cube_map, 0, &cube_texture);
1511     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateCubeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
1512
1513     hr = D3DXCreateCubeTextureFromFileInMemory(device, dds_cube_map, sizeof(dds_cube_map), NULL);
1514     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateCubeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
1515
1516     hr = D3DXCreateCubeTextureFromFileInMemory(device, dds_cube_map, sizeof(dds_cube_map), &cube_texture);
1517     if (SUCCEEDED(hr))
1518     {
1519         levelcount = IDirect3DCubeTexture9_GetLevelCount(cube_texture);
1520         todo_wine ok(levelcount == 3, "GetLevelCount returned %u, expected 3\n", levelcount);
1521
1522         hr = IDirect3DCubeTexture9_GetLevelDesc(cube_texture, 0, &surface_desc);
1523         ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
1524         ok(surface_desc.Width == 4, "Got width %u, expected 4\n", surface_desc.Width);
1525         ok(surface_desc.Height == 4, "Got height %u, expected 4\n", surface_desc.Height);
1526
1527         ref = IDirect3DCubeTexture9_Release(cube_texture);
1528         ok(ref == 0, "Invalid reference count. Got %u, expected 0\n", ref);
1529     } else skip("Couldn't create cube texture\n");
1530 }
1531
1532 static void test_D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 *device)
1533 {
1534     HRESULT hr;
1535     IDirect3DCubeTexture9 *cube_texture;
1536
1537     if (!is_autogenmipmap_supported(device, D3DRTYPE_CUBETEXTURE))
1538     {
1539         skip("No D3DUSAGE_AUTOGENMIPMAP support for cube textures\n");
1540         return;
1541     }
1542
1543     hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, dds_cube_map, sizeof(dds_cube_map), D3DX_DEFAULT, D3DX_DEFAULT,
1544         D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &cube_texture);
1545     ok(hr == D3D_OK, "D3DXCreateCubeTextureFromFileInMemoryEx returned %#x, expected %#x\n", hr, D3D_OK);
1546     if (SUCCEEDED(hr)) IDirect3DCubeTexture9_Release(cube_texture);
1547 }
1548
1549 static void test_D3DXCreateVolumeTextureFromFileInMemory(IDirect3DDevice9 *device)
1550 {
1551     HRESULT hr;
1552     ULONG ref;
1553     DWORD levelcount;
1554     IDirect3DVolumeTexture9 *volume_texture;
1555     D3DVOLUME_DESC volume_desc;
1556
1557     hr = D3DXCreateVolumeTextureFromFileInMemory(NULL, dds_volume_map, sizeof(dds_volume_map), &volume_texture);
1558     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
1559
1560     hr = D3DXCreateVolumeTextureFromFileInMemory(device, NULL, sizeof(dds_volume_map), &volume_texture);
1561     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
1562
1563     hr = D3DXCreateVolumeTextureFromFileInMemory(device, dds_volume_map, 0, &volume_texture);
1564     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
1565
1566     hr = D3DXCreateVolumeTextureFromFileInMemory(device, dds_volume_map, sizeof(dds_volume_map), NULL);
1567     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
1568
1569     hr = D3DXCreateVolumeTextureFromFileInMemory(device, dds_volume_map, sizeof(dds_volume_map), &volume_texture);
1570     ok(hr == D3D_OK, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
1571     if (SUCCEEDED(hr))
1572     {
1573         levelcount = IDirect3DVolumeTexture9_GetLevelCount(volume_texture);
1574         ok(levelcount == 3, "GetLevelCount returned %u, expected 3\n", levelcount);
1575
1576         hr = IDirect3DVolumeTexture9_GetLevelDesc(volume_texture, 0, &volume_desc);
1577         ok(hr == D3D_OK, "GetLevelDesc returend %#x, expected %#x\n", hr, D3D_OK);
1578         ok(volume_desc.Width == 4, "Got width %u, expected 4\n", volume_desc.Width);
1579         ok(volume_desc.Height == 4, "Got height %u, expected 4\n", volume_desc.Height);
1580         ok(volume_desc.Depth == 2, "Got depth %u, expected 2\n", volume_desc.Depth);
1581
1582         hr = IDirect3DVolumeTexture9_GetLevelDesc(volume_texture, 1, &volume_desc);
1583         ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
1584         ok(volume_desc.Width == 2, "Got width %u, expected 2\n", volume_desc.Width);
1585         ok(volume_desc.Height == 2, "Got height %u, expected 2\n", volume_desc.Height);
1586         ok(volume_desc.Depth == 1, "Got depth %u, expected 1\n", volume_desc.Depth);
1587
1588         ref = IDirect3DVolumeTexture9_Release(volume_texture);
1589         ok(ref == 0, "Invalid reference count. Got %u, expected 0\n", ref);
1590     }
1591 }
1592
1593 /* fills positive x face with red color */
1594 static void WINAPI fill_cube_positive_x(D3DXVECTOR4 *out, const D3DXVECTOR3 *tex_coord, const D3DXVECTOR3 *texel_size, void *data)
1595 {
1596     memset(out, 0, sizeof(*out));
1597     if (tex_coord->x > 0 && fabs(tex_coord->x) > fabs(tex_coord->y) && fabs(tex_coord->x) > fabs(tex_coord->z))
1598         out->x = 1;
1599 }
1600
1601 static void test_D3DXSaveTextureToFileInMemory(IDirect3DDevice9 *device)
1602 {
1603     HRESULT hr;
1604     IDirect3DTexture9 *texture;
1605     IDirect3DCubeTexture9 *cube_texture;
1606     IDirect3DVolumeTexture9 *volume_texture;
1607     ID3DXBuffer *buffer;
1608     void *buffer_pointer;
1609     DWORD buffer_size;
1610     D3DXIMAGE_INFO info;
1611     D3DXIMAGE_FILEFORMAT file_format;
1612
1613     /* textures */
1614     hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
1615     if (FAILED(hr))
1616     {
1617         skip("Failed to create texture\n");
1618         return;
1619     }
1620
1621     for (file_format = D3DXIFF_BMP; file_format <= D3DXIFF_JPG; file_format++)
1622     {
1623         hr = D3DXSaveTextureToFileInMemory(&buffer, file_format, (IDirect3DBaseTexture9 *)texture, NULL);
1624         ok(hr == D3D_OK, "D3DXSaveTextureToFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
1625         if (SUCCEEDED(hr))
1626         {
1627             buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer);
1628             buffer_size = ID3DXBuffer_GetBufferSize(buffer);
1629             hr = D3DXGetImageInfoFromFileInMemory(buffer_pointer, buffer_size, &info);
1630             ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
1631
1632             ok(info.Width == 256, "Got width %u, expected %u\n", info.Width, 256);
1633             ok(info.Height == 256, "Got height %u, expected %u\n", info.Height, 256);
1634             ok(info.MipLevels == 1, "Got miplevels %u, expected %u\n", info.MipLevels, 1);
1635             ok(info.ResourceType == D3DRTYPE_TEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_TEXTURE);
1636             ok(info.ImageFileFormat == file_format, "Got file format %#x, expected %#x\n", info.ImageFileFormat, file_format);
1637             ID3DXBuffer_Release(buffer);
1638         }
1639     }
1640
1641     todo_wine {
1642     hr = D3DXSaveTextureToFileInMemory(&buffer, D3DXIFF_DDS, (IDirect3DBaseTexture9 *)texture, NULL);
1643     ok(hr == D3D_OK, "D3DXSaveTextureToFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
1644     if (SUCCEEDED(hr))
1645     {
1646         buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer);
1647         buffer_size = ID3DXBuffer_GetBufferSize(buffer);
1648         hr = D3DXGetImageInfoFromFileInMemory(buffer_pointer, buffer_size, &info);
1649         ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
1650
1651         ok(info.Width == 256, "Got width %u, expected %u\n", info.Width, 256);
1652         ok(info.Height == 256, "Got height %u, expected %u\n", info.Height, 256);
1653         ok(info.MipLevels == 9, "Got miplevels %u, expected %u\n", info.MipLevels, 9);
1654         ok(info.ResourceType == D3DRTYPE_TEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_TEXTURE);
1655         ok(info.ImageFileFormat == D3DXIFF_DDS, "Got file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_DDS);
1656         ID3DXBuffer_Release(buffer);
1657     }
1658     }
1659
1660     IDirect3DTexture9_Release(texture);
1661
1662     /* cube textures */
1663     hr = IDirect3DDevice9_CreateCubeTexture(device, 256, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &cube_texture, NULL);
1664     if (FAILED(hr))
1665     {
1666         skip("Failed to create cube texture\n");
1667         return;
1668     }
1669
1670     hr = D3DXFillCubeTexture(cube_texture, fill_cube_positive_x, NULL);
1671     ok(hr == D3D_OK, "D3DXFillCubeTexture returned %#x, expected %#x\n", hr, D3D_OK);
1672
1673     hr = D3DXSaveTextureToFileInMemory(&buffer, D3DXIFF_BMP, (IDirect3DBaseTexture9 *)cube_texture, NULL);
1674     ok(hr == D3D_OK, "D3DXSaveTextureToFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
1675     if (SUCCEEDED(hr))
1676     {
1677         IDirect3DSurface9 *surface;
1678
1679         buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer);
1680         buffer_size = ID3DXBuffer_GetBufferSize(buffer);
1681         hr = D3DXGetImageInfoFromFileInMemory(buffer_pointer, buffer_size, &info);
1682         ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
1683
1684         ok(info.Width == 256, "Got width %u, expected %u\n", info.Width, 256);
1685         ok(info.Height == 256, "Got height %u, expected %u\n", info.Height, 256);
1686         ok(info.MipLevels == 1, "Got miplevels %u, expected %u\n", info.MipLevels, 1);
1687         ok(info.ResourceType == D3DRTYPE_TEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_TEXTURE);
1688         ok(info.ImageFileFormat == D3DXIFF_BMP, "Got file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_BMP);
1689
1690         /* positive x face is saved */
1691         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1692         if (SUCCEEDED(hr))
1693         {
1694             D3DLOCKED_RECT locked_rect;
1695
1696             hr = D3DXLoadSurfaceFromFileInMemory(surface, NULL, NULL, buffer_pointer, buffer_size, NULL, D3DX_FILTER_NONE, 0, NULL);
1697             ok(hr == D3D_OK, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
1698
1699             hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, D3DLOCK_READONLY);
1700             if (SUCCEEDED(hr))
1701             {
1702                 DWORD *color = locked_rect.pBits;
1703                 ok(*color == 0x00ff0000, "Got color %#x, expected %#x\n", *color, 0x00ff0000);
1704                 IDirect3DSurface9_UnlockRect(surface);
1705             }
1706
1707             IDirect3DSurface9_Release(surface);
1708         } else skip("Failed to create surface\n");
1709
1710         ID3DXBuffer_Release(buffer);
1711     }
1712
1713     todo_wine {
1714     hr = D3DXSaveTextureToFileInMemory(&buffer, D3DXIFF_DDS, (IDirect3DBaseTexture9 *)cube_texture, NULL);
1715     ok(hr == D3D_OK, "D3DXSaveTextureToFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
1716     if (SUCCEEDED(hr))
1717     {
1718         buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer);
1719         buffer_size = ID3DXBuffer_GetBufferSize(buffer);
1720         hr = D3DXGetImageInfoFromFileInMemory(buffer_pointer, buffer_size, &info);
1721         ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
1722
1723         ok(info.Width == 256, "Got width %u, expected %u\n", info.Width, 256);
1724         ok(info.Height == 256, "Got height %u, expected %u\n", info.Height, 256);
1725         ok(info.MipLevels == 9, "Got miplevels %u, expected %u\n", info.MipLevels, 9);
1726         ok(info.ResourceType == D3DRTYPE_CUBETEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_CUBETEXTURE);
1727         ok(info.ImageFileFormat == D3DXIFF_DDS, "Got file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_DDS);
1728         ID3DXBuffer_Release(buffer);
1729     }
1730     }
1731
1732     IDirect3DCubeTexture9_Release(cube_texture);
1733
1734     /* volume textures */
1735     hr = IDirect3DDevice9_CreateVolumeTexture(device, 256, 256, 256, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &volume_texture, NULL);
1736     if (FAILED(hr))
1737     {
1738         skip("Failed to create volume texture\n");
1739         return;
1740     }
1741
1742     todo_wine {
1743     hr = D3DXSaveTextureToFileInMemory(&buffer, D3DXIFF_BMP, (IDirect3DBaseTexture9 *)volume_texture, NULL);
1744     ok(hr == D3D_OK, "D3DXSaveTextureToFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
1745     if (SUCCEEDED(hr))
1746     {
1747         buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer);
1748         buffer_size = ID3DXBuffer_GetBufferSize(buffer);
1749         hr = D3DXGetImageInfoFromFileInMemory(buffer_pointer, buffer_size, &info);
1750         ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
1751
1752         ok(info.Width == 256, "Got width %u, expected %u\n", info.Width, 256);
1753         ok(info.Height == 256, "Got height %u, expected %u\n", info.Height, 256);
1754         ok(info.Depth == 1, "Got depth %u, expected %u\n", info.Depth, 1);
1755         ok(info.MipLevels == 1, "Got miplevels %u, expected %u\n", info.MipLevels, 1);
1756         ok(info.ResourceType == D3DRTYPE_TEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_TEXTURE);
1757         ok(info.ImageFileFormat == D3DXIFF_BMP, "Got file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_BMP);
1758         ID3DXBuffer_Release(buffer);
1759     }
1760
1761     hr = D3DXSaveTextureToFileInMemory(&buffer, D3DXIFF_DDS, (IDirect3DBaseTexture9 *)volume_texture, NULL);
1762     ok(hr == D3D_OK, "D3DXSaveTextureToFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
1763     if (SUCCEEDED(hr))
1764     {
1765         buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer);
1766         buffer_size = ID3DXBuffer_GetBufferSize(buffer);
1767         hr = D3DXGetImageInfoFromFileInMemory(buffer_pointer, buffer_size, &info);
1768         ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
1769
1770         ok(info.Width == 256, "Got width %u, expected %u\n", info.Width, 256);
1771         ok(info.Height == 256, "Got height %u, expected %u\n", info.Height, 256);
1772         ok(info.Depth == 256, "Got depth %u, expected %u\n", info.Depth, 256);
1773         ok(info.MipLevels == 9, "Got miplevels %u, expected %u\n", info.MipLevels, 9);
1774         ok(info.ResourceType == D3DRTYPE_VOLUMETEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_VOLUMETEXTURE);
1775         ok(info.ImageFileFormat == D3DXIFF_DDS, "Got file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_DDS);
1776         ID3DXBuffer_Release(buffer);
1777     }
1778     }
1779
1780     IDirect3DVolumeTexture9_Release(volume_texture);
1781 }
1782
1783 START_TEST(texture)
1784 {
1785     HWND wnd;
1786     IDirect3D9 *d3d;
1787     IDirect3DDevice9 *device;
1788     D3DPRESENT_PARAMETERS d3dpp;
1789     HRESULT hr;
1790
1791     wnd = CreateWindow("static", "d3dx9_test", 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL);
1792     if (!wnd) {
1793         skip("Couldn't create application window\n");
1794         return;
1795     }
1796     d3d = Direct3DCreate9(D3D_SDK_VERSION);
1797     if (!d3d) {
1798         skip("Couldn't create IDirect3D9 object\n");
1799         DestroyWindow(wnd);
1800         return;
1801     }
1802
1803     ZeroMemory(&d3dpp, sizeof(d3dpp));
1804     d3dpp.Windowed   = TRUE;
1805     d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1806     hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, wnd, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &device);
1807     if (FAILED(hr)) {
1808         skip("Failed to create IDirect3DDevice9 object %#x\n", hr);
1809         IDirect3D9_Release(d3d);
1810         DestroyWindow(wnd);
1811         return;
1812     }
1813
1814     test_D3DXCheckTextureRequirements(device);
1815     test_D3DXCheckCubeTextureRequirements(device);
1816     test_D3DXCheckVolumeTextureRequirements(device);
1817     test_D3DXCreateTexture(device);
1818     test_D3DXFilterTexture(device);
1819     test_D3DXFillTexture(device);
1820     test_D3DXFillCubeTexture(device);
1821     test_D3DXFillVolumeTexture(device);
1822     test_D3DXCreateTextureFromFileInMemory(device);
1823     test_D3DXCreateTextureFromFileInMemoryEx(device);
1824     test_D3DXCreateCubeTextureFromFileInMemory(device);
1825     test_D3DXCreateCubeTextureFromFileInMemoryEx(device);
1826     test_D3DXCreateVolumeTextureFromFileInMemory(device);
1827     test_D3DXSaveTextureToFileInMemory(device);
1828
1829     IDirect3DDevice9_Release(device);
1830     IDirect3D9_Release(d3d);
1831     DestroyWindow(wnd);
1832 }