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