d3dx9/tests: Add tests for D3DXCreateCubeTextureFromFileInMemory.
[wine] / dlls / d3dx9_36 / tests / surface.c
1 /*
2  * Tests for the D3DX9 surface functions
3  *
4  * Copyright 2009 Tony Wasserka
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #define COBJMACROS
22 #include "wine/test.h"
23 #include "d3dx9tex.h"
24 #include "resources.h"
25
26 static inline int get_ref(IUnknown *obj)
27 {
28     IUnknown_AddRef(obj);
29     return IUnknown_Release(obj);
30 }
31
32 static inline void check_ref(IUnknown *obj, int exp)
33 {
34     int ref = get_ref(obj);
35     ok (exp == ref, "Invalid refcount. Expected %d, got %d\n", exp, ref);
36 }
37
38 static inline void check_release(IUnknown *obj, int exp)
39 {
40     int ref = IUnknown_Release(obj);
41     ok (ref == exp, "Invalid refcount. Expected %d, got %d\n", exp, ref);
42 }
43
44 /* 1x1 bmp (1 bpp) */
45 static const unsigned char bmp01[66] = {
46 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
47 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
48 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
49 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
50 0x00,0x00
51 };
52
53 /* 2x2 A8R8G8B8 pixel data */
54 static const unsigned char pixdata[] = {
55 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
56 };
57
58 /* invalid image file */
59 static const unsigned char noimage[4] = {
60 0x11,0x22,0x33,0x44
61 };
62
63 /* 2x2 24-bit dds, 2 mipmaps */
64 static const unsigned char dds_24bit[] = {
65 0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x0a,0x00,0x02,0x00,0x00,0x00,
66 0x02,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
67 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
68 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
69 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
70 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0xff,0x00,
71 0x00,0xff,0x00,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x40,0x00,
72 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
73 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
74 };
75
76 /* 2x2 16-bit dds, no mipmaps */
77 static const unsigned char dds_16bit[] = {
78 0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x08,0x00,0x02,0x00,0x00,0x00,
79 0x02,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
80 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
81 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
82 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
83 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x7c,0x00,0x00,
84 0xe0,0x03,0x00,0x00,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,
85 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
86 0xff,0x7f,0xff,0x7f,0xff,0x7f,0xff,0x7f
87 };
88
89 /* 4x4 cube map dds */
90 static const unsigned char dds_cube_map[] = {
91 0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x08,0x00,0x04,0x00,0x00,0x00,
92 0x04,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
93 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
94 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
95 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
96 0x04,0x00,0x00,0x00,0x44,0x58,0x54,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
97 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x00,0x00,
98 0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
99 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50,
100 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50,
101 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50,
102 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50,
103 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50,
104 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50
105 };
106
107 /* 4x4x2 volume map dds, 2 mipmaps */
108 static const unsigned char dds_volume_map[] = {
109 0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x8a,0x00,0x04,0x00,0x00,0x00,
110 0x04,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
111 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
112 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
113 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
114 0x04,0x00,0x00,0x00,0x44,0x58,0x54,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
115 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x40,0x00,
116 0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
117 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50,
118 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50,
119 0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x2f,0x7e,0xcf,0x79,0x01,0x54,0x5c,0x5c,
120 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x84,0xef,0x7b,0xaa,0xab,0xab,0xab
121 };
122
123 static HRESULT create_file(const char *filename, const unsigned char *data, const unsigned int size)
124 {
125     DWORD received;
126     HANDLE hfile;
127
128     hfile = CreateFileA(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
129     if(hfile == INVALID_HANDLE_VALUE) return HRESULT_FROM_WIN32(GetLastError());
130
131     if(WriteFile(hfile, data, size, &received, NULL))
132     {
133         CloseHandle(hfile);
134         return D3D_OK;
135     }
136
137     CloseHandle(hfile);
138     return D3DERR_INVALIDCALL;
139 }
140
141 static void test_D3DXGetImageInfo(void)
142 {
143     HRESULT hr;
144     D3DXIMAGE_INFO info;
145     BOOL testdummy_ok, testbitmap_ok;
146
147     hr = create_file("testdummy.bmp", noimage, sizeof(noimage));  /* invalid image */
148     testdummy_ok = SUCCEEDED(hr);
149
150     hr = create_file("testbitmap.bmp", bmp01, sizeof(bmp01));  /* valid image */
151     testbitmap_ok = SUCCEEDED(hr);
152
153     /* D3DXGetImageInfoFromFile */
154     if(testbitmap_ok) {
155         hr = D3DXGetImageInfoFromFileA("testbitmap.bmp", &info);
156         ok(hr == D3D_OK, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3D_OK);
157
158         hr = D3DXGetImageInfoFromFileA("testbitmap.bmp", NULL); /* valid image, second parameter is NULL */
159         ok(hr == D3D_OK, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3D_OK);
160     } else skip("Couldn't create \"testbitmap.bmp\"\n");
161
162     if(testdummy_ok) {
163         hr = D3DXGetImageInfoFromFileA("testdummy.bmp", NULL); /* invalid image, second parameter is NULL */
164         ok(hr == D3D_OK, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3D_OK);
165
166         hr = D3DXGetImageInfoFromFileA("testdummy.bmp", &info);
167         ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
168     } else skip("Couldn't create \"testdummy.bmp\"\n");
169
170     hr = D3DXGetImageInfoFromFileA("filedoesnotexist.bmp", &info);
171     ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
172
173     hr = D3DXGetImageInfoFromFileA("filedoesnotexist.bmp", NULL);
174     ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
175
176     hr = D3DXGetImageInfoFromFileA("", &info);
177     ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
178
179     hr = D3DXGetImageInfoFromFileA(NULL, &info);
180     ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
181
182     hr = D3DXGetImageInfoFromFileA(NULL, NULL);
183     ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
184
185
186     /* D3DXGetImageInfoFromResource */
187     todo_wine {
188         hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDB_BITMAP_1x1), &info); /* RT_BITMAP */
189         ok(hr == D3D_OK, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3D_OK);
190
191         hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDB_BITMAP_1x1), NULL);
192         ok(hr == D3D_OK, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3D_OK);
193     }
194
195     hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDD_BITMAPDATA_1x1), &info); /* RT_RCDATA */
196     ok(hr == D3D_OK, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3D_OK);
197
198     hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDS_STRING), &info);
199     ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
200
201     hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDS_STRING), NULL);
202     ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
203
204     hr = D3DXGetImageInfoFromResourceA(NULL, "resourcedoesnotexist", &info);
205     ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
206
207     hr = D3DXGetImageInfoFromResourceA(NULL, "resourcedoesnotexist", NULL);
208     ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
209
210     hr = D3DXGetImageInfoFromResourceA(NULL, NULL, NULL);
211     ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
212
213
214     /* D3DXGetImageInfoFromFileInMemory */
215     hr = D3DXGetImageInfoFromFileInMemory(bmp01, sizeof(bmp01), &info);
216     ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
217
218     hr = D3DXGetImageInfoFromFileInMemory(bmp01, sizeof(bmp01)+5, &info); /* too large size */
219     ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
220
221     hr = D3DXGetImageInfoFromFileInMemory(bmp01, sizeof(bmp01), NULL);
222     ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
223
224     hr = D3DXGetImageInfoFromFileInMemory(noimage, sizeof(noimage), NULL);
225     ok(hr == D3D_OK, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3D_OK);
226
227     hr = D3DXGetImageInfoFromFileInMemory(noimage, sizeof(noimage), &info);
228     ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
229
230     todo_wine {
231         hr = D3DXGetImageInfoFromFileInMemory(bmp01, sizeof(bmp01)-1, &info);
232         ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
233     }
234
235     hr = D3DXGetImageInfoFromFileInMemory(bmp01+1, sizeof(bmp01)-1, &info);
236     ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
237
238     hr = D3DXGetImageInfoFromFileInMemory(bmp01, 0, &info);
239     ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
240
241     hr = D3DXGetImageInfoFromFileInMemory(bmp01, 0, NULL);
242     ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
243
244     hr = D3DXGetImageInfoFromFileInMemory(noimage, 0, &info);
245     ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
246
247     hr = D3DXGetImageInfoFromFileInMemory(noimage, 0, NULL);
248     ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
249
250     hr = D3DXGetImageInfoFromFileInMemory(NULL, 0, &info);
251     ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
252
253     hr = D3DXGetImageInfoFromFileInMemory(NULL, 4, NULL);
254     ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
255
256     hr = D3DXGetImageInfoFromFileInMemory(NULL, 4, &info);
257     ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
258
259     hr = D3DXGetImageInfoFromFileInMemory(NULL, 0, NULL);
260     ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
261
262
263     /* test DDS support */
264     todo_wine {
265         hr = D3DXGetImageInfoFromFileInMemory(dds_24bit, sizeof(dds_24bit), &info);
266         ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
267         if (hr == D3D_OK) {
268             ok(info.Width == 2, "Got width %u, expected 2\n", info.Width);
269             ok(info.Height == 2, "Got height %u, expected 2\n", info.Height);
270             ok(info.Depth == 1, "Got depth %u, expected 1\n", info.Depth);
271             ok(info.MipLevels == 2, "Got miplevels %u, expected 2\n", info.MipLevels);
272             ok(info.Format == D3DFMT_R8G8B8, "Got format is %#x, expected %#x\n", info.Format, D3DFMT_R8G8B8);
273             ok(info.ResourceType == D3DRTYPE_TEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_TEXTURE);
274             ok(info.ImageFileFormat == D3DXIFF_DDS, "Got image file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_DDS);
275         } else skip("Couldn't get image info from 24-bit DDS file in memory\n");
276
277         hr = D3DXGetImageInfoFromFileInMemory(dds_16bit, sizeof(dds_16bit), &info);
278         ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
279         if (hr == D3D_OK) {
280             ok(info.Width == 2, "Got width %u, expected 2\n", info.Width);
281             ok(info.Height == 2, "Got height %u, expected 2\n", info.Height);
282             ok(info.Depth == 1, "Got depth %u, expected 1\n", info.Depth);
283             ok(info.MipLevels == 1, "Got miplevels %u, expected 1\n", info.MipLevels);
284             ok(info.Format == D3DFMT_X1R5G5B5, "Got format is %#x, expected %#x\n", info.Format, D3DFMT_X1R5G5B5);
285             ok(info.ResourceType == D3DRTYPE_TEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_TEXTURE);
286             ok(info.ImageFileFormat == D3DXIFF_DDS, "Got image file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_DDS);
287         } else skip("Couldn't get image info from 16-bit DDS file in memory\n");
288
289         hr = D3DXGetImageInfoFromFileInMemory(dds_cube_map, sizeof(dds_cube_map), &info);
290         ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
291         if (hr == D3D_OK) {
292             ok(info.Width == 4, "Got width %u, expected 4\n", info.Width);
293             ok(info.Height == 4, "Got height %u, expected 4\n", info.Height);
294             ok(info.Depth == 1, "Got depth %u, expected 1\n", info.Depth);
295             ok(info.MipLevels == 1, "Got miplevels %u, expected 1\n", info.MipLevels);
296             ok(info.Format == D3DFMT_DXT5, "Got format is %#x, expected %#x\n", info.Format, D3DFMT_DXT5);
297             ok(info.ResourceType == D3DRTYPE_CUBETEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_CUBETEXTURE);
298             ok(info.ImageFileFormat == D3DXIFF_DDS, "Got image file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_DDS);
299         } else skip("Couldn't get image info from cube map in memory\n");
300
301         hr = D3DXGetImageInfoFromFileInMemory(dds_volume_map, sizeof(dds_volume_map), &info);
302         ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
303         if (hr == D3D_OK) {
304             ok(info.Width == 4, "Got width %u, expected 4\n", info.Width);
305             ok(info.Height == 4, "Got height %u, expected 4\n", info.Height);
306             ok(info.Depth == 2, "Got depth %u, expected 2\n", info.Depth);
307             ok(info.MipLevels == 3, "Got miplevels %u, expected 3\n", info.MipLevels);
308             ok(info.Format == D3DFMT_DXT3, "Got format is %#x, expected %#x\n", info.Format, D3DFMT_DXT3);
309             ok(info.ResourceType == D3DRTYPE_VOLUMETEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_VOLUMETEXTURE);
310             ok(info.ImageFileFormat == D3DXIFF_DDS, "Got image file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_DDS);
311         } else skip("Couldn't get image info from volume map in memory\n");
312     }
313
314
315     /* cleanup */
316     if(testdummy_ok) DeleteFileA("testdummy.bmp");
317     if(testbitmap_ok) DeleteFileA("testbitmap.bmp");
318 }
319
320 #define check_pixel_1bpp(lockrect, x, y, color) \
321 ok(((BYTE*)(lockrect).pBits)[(x) + (y) * (lockrect).Pitch] == color, "Got color 0x%02x, expected 0x%02x.\n", \
322 ((BYTE*)(lockrect).pBits)[(x) + (y) * (lockrect).Pitch], color)
323
324 #define check_pixel_2bpp(lockrect, x, y, color) \
325 ok(((WORD*)(lockrect).pBits)[(x) + (y) * (lockrect).Pitch / 2] == color, "Got color 0x%04x, expected 0x%04x.\n", \
326 ((WORD*)(lockrect).pBits)[(x) + (y) * (lockrect).Pitch / 2], color)
327
328 #define check_pixel_4bpp(lockrect, x, y, color) \
329 ok(((DWORD*)(lockrect).pBits)[(x) + (y) * (lockrect).Pitch / 4] == color, "Got color 0x%08x, expected 0x%08x.\n", \
330 ((DWORD*)(lockrect).pBits)[(x) + (y) * (lockrect).Pitch / 4], color)
331 static void test_D3DXLoadSurface(IDirect3DDevice9 *device)
332 {
333     HRESULT hr;
334     BOOL testdummy_ok, testbitmap_ok;
335     IDirect3DSurface9 *surf, *newsurf;
336     RECT rect, destrect;
337     D3DLOCKED_RECT lockrect;
338     const WORD pixdata_a8r3g3b2[] = { 0x57df, 0x98fc, 0xacdd, 0xc891 };
339     const WORD pixdata_a1r5g5b5[] = { 0x46b5, 0x99c8, 0x06a2, 0x9431 };
340     const WORD pixdata_r5g6b5[] = { 0x9ef6, 0x658d, 0x0aee, 0x42ee };
341     const WORD pixdata_a8l8[] = { 0xff00, 0x00ff, 0xff30, 0x7f7f };
342     const DWORD pixdata_g16r16[] = { 0x07d23fbe, 0xdc7f44a4, 0xe4d8976b, 0x9a84fe89 };
343     const DWORD pixdata_a8b8g8r8[] = { 0xc3394cf0, 0x235ae892, 0x09b197fd, 0x8dc32bf6 };
344     const DWORD pixdata_a2r10g10b10[] = { 0x57395aff, 0x5b7668fd, 0xb0d856b5, 0xff2c61d6 };
345
346     hr = create_file("testdummy.bmp", noimage, sizeof(noimage));  /* invalid image */
347     testdummy_ok = SUCCEEDED(hr);
348
349     hr = create_file("testbitmap.bmp", bmp01, sizeof(bmp01));  /* valid image */
350     testbitmap_ok = SUCCEEDED(hr);
351
352     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf, NULL);
353     if(FAILED(hr)) {
354         skip("Failed to create a surface (%#x)\n", hr);
355         if(testdummy_ok) DeleteFileA("testdummy.bmp");
356         if(testbitmap_ok) DeleteFileA("testbitmap.bmp");
357         return;
358     }
359
360     /* D3DXLoadSurfaceFromFile */
361     if(testbitmap_ok) {
362         todo_wine {
363             hr = D3DXLoadSurfaceFromFileA(surf, NULL, NULL, "testbitmap.bmp", NULL, D3DX_DEFAULT, 0, NULL);
364             ok(hr == D3D_OK, "D3DXLoadSurfaceFromFile returned %#x, expected %#x\n", hr, D3D_OK);
365         }
366
367         hr = D3DXLoadSurfaceFromFileA(NULL, NULL, NULL, "testbitmap.bmp", NULL, D3DX_DEFAULT, 0, NULL);
368         ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromFile returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
369     } else skip("Couldn't create \"testbitmap.bmp\"\n");
370
371     if(testdummy_ok) {
372         hr = D3DXLoadSurfaceFromFileA(surf, NULL, NULL, "testdummy.bmp", NULL, D3DX_DEFAULT, 0, NULL);
373         ok(hr == D3DXERR_INVALIDDATA, "D3DXLoadSurfaceFromFile returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
374     } else skip("Couldn't create \"testdummy.bmp\"\n");
375
376     hr = D3DXLoadSurfaceFromFileA(surf, NULL, NULL, NULL, NULL, D3DX_DEFAULT, 0, NULL);
377     ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromFile returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
378
379     hr = D3DXLoadSurfaceFromFileA(surf, NULL, NULL, "", NULL, D3DX_DEFAULT, 0, NULL);
380     ok(hr == D3DXERR_INVALIDDATA, "D3DXLoadSurfaceFromFile returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
381
382
383     /* D3DXLoadSurfaceFromResource */
384     todo_wine {
385         hr = D3DXLoadSurfaceFromResourceA(surf, NULL, NULL, NULL, MAKEINTRESOURCE(IDB_BITMAP_1x1), NULL, D3DX_DEFAULT, 0, NULL);
386         ok(hr == D3D_OK, "D3DXLoadSurfaceFromResource returned %#x, expected %#x\n", hr, D3D_OK);
387     }
388
389     hr = D3DXLoadSurfaceFromResourceA(surf, NULL, NULL, NULL, MAKEINTRESOURCE(IDD_BITMAPDATA_1x1), NULL, D3DX_DEFAULT, 0, NULL);
390     ok(hr == D3D_OK, "D3DXLoadSurfaceFromResource returned %#x, expected %#x\n", hr, D3D_OK);
391
392     hr = D3DXLoadSurfaceFromResourceA(surf, NULL, NULL, NULL, NULL, NULL, D3DX_DEFAULT, 0, NULL);
393     ok(hr == D3DXERR_INVALIDDATA, "D3DXLoadSurfaceFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
394
395     hr = D3DXLoadSurfaceFromResourceA(NULL, NULL, NULL, NULL, MAKEINTRESOURCE(IDB_BITMAP_1x1), NULL, D3DX_DEFAULT, 0, NULL);
396     ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromResource returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
397
398     hr = D3DXLoadSurfaceFromResourceA(surf, NULL, NULL, NULL, MAKEINTRESOURCE(IDS_STRING), NULL, D3DX_DEFAULT, 0, NULL);
399     ok(hr == D3DXERR_INVALIDDATA, "D3DXLoadSurfaceFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
400
401
402     /* D3DXLoadSurfaceFromFileInMemory */
403     todo_wine {
404         hr = D3DXLoadSurfaceFromFileInMemory(surf, NULL, NULL, bmp01, sizeof(bmp01), NULL, D3DX_DEFAULT, 0, NULL);
405         ok(hr == D3D_OK, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
406     }
407
408     hr = D3DXLoadSurfaceFromFileInMemory(surf, NULL, NULL, noimage, sizeof(noimage), NULL, D3DX_DEFAULT, 0, NULL);
409     ok(hr == D3DXERR_INVALIDDATA, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
410
411     hr = D3DXLoadSurfaceFromFileInMemory(surf, NULL, NULL, bmp01, 0, NULL, D3DX_DEFAULT, 0, NULL);
412     ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
413
414     hr = D3DXLoadSurfaceFromFileInMemory(NULL, NULL, NULL, bmp01, sizeof(bmp01), NULL, D3DX_DEFAULT, 0, NULL);
415     ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
416
417     hr = D3DXLoadSurfaceFromFileInMemory(surf, NULL, NULL, NULL, 8, NULL, D3DX_DEFAULT, 0, NULL);
418     ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
419
420     hr = D3DXLoadSurfaceFromFileInMemory(surf, NULL, NULL, NULL, 0, NULL, D3DX_DEFAULT, 0, NULL);
421     ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
422
423     hr = D3DXLoadSurfaceFromFileInMemory(NULL, NULL, NULL, NULL, 0, NULL, D3DX_DEFAULT, 0, NULL);
424     ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
425
426
427     /* D3DXLoadSurfaceFromMemory */
428     SetRect(&rect, 0, 0, 2, 2);
429
430     hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata, D3DFMT_A8R8G8B8, sizeof(pixdata), NULL, &rect, D3DX_FILTER_NONE, 0);
431     ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
432
433     hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata, D3DFMT_A8R8G8B8, 0, NULL, &rect, D3DX_FILTER_NONE, 0);
434     ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
435
436     hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, NULL, D3DFMT_A8R8G8B8, sizeof(pixdata), NULL, &rect, D3DX_DEFAULT, 0);
437     ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
438
439     hr = D3DXLoadSurfaceFromMemory(NULL, NULL, NULL, pixdata, D3DFMT_A8R8G8B8, sizeof(pixdata), NULL, &rect, D3DX_DEFAULT, 0);
440     ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
441
442     hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata, D3DFMT_A8R8G8B8, sizeof(pixdata), NULL, NULL, D3DX_DEFAULT, 0);
443     ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
444
445     hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata, D3DFMT_UNKNOWN, sizeof(pixdata), NULL, &rect, D3DX_DEFAULT, 0);
446     ok(hr == E_FAIL, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, E_FAIL);
447
448     SetRect(&destrect, -1, -1, 1, 1); /* destination rect is partially outside texture boundaries */
449     hr = D3DXLoadSurfaceFromMemory(surf, NULL, &destrect, pixdata, D3DFMT_A8R8G8B8, sizeof(pixdata), NULL, &rect, D3DX_FILTER_NONE, 0);
450     ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
451
452     SetRect(&destrect, 255, 255, 257, 257); /* destination rect is partially outside texture boundaries */
453     hr = D3DXLoadSurfaceFromMemory(surf, NULL, &destrect, pixdata, D3DFMT_A8R8G8B8, sizeof(pixdata), NULL, &rect, D3DX_FILTER_NONE, 0);
454     ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
455
456     SetRect(&destrect, 1, 1, 0, 0); /* left > right, top > bottom */
457     hr = D3DXLoadSurfaceFromMemory(surf, NULL, &destrect, pixdata, D3DFMT_A8R8G8B8, sizeof(pixdata), NULL, &rect, D3DX_FILTER_NONE, 0);
458     ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
459
460     SetRect(&destrect, 0, 0, 0, 0); /* left = right, top = bottom */
461     hr = D3DXLoadSurfaceFromMemory(surf, NULL, &destrect, pixdata, D3DFMT_A8R8G8B8, sizeof(pixdata), NULL, &rect, D3DX_FILTER_NONE, 0);
462     ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
463
464     SetRect(&destrect, 257, 257, 257, 257); /* left = right, top = bottom, but invalid values */
465     hr = D3DXLoadSurfaceFromMemory(surf, NULL, &destrect, pixdata, D3DFMT_A8R8G8B8, sizeof(pixdata), NULL, &rect, D3DX_FILTER_NONE, 0);
466     ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
467
468
469     /* D3DXLoadSurfaceFromSurface */
470     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &newsurf, NULL);
471     if(SUCCEEDED(hr)) {
472         hr = D3DXLoadSurfaceFromSurface(newsurf, NULL, NULL, surf, NULL, NULL, D3DX_DEFAULT, 0);
473         ok(hr == D3D_OK, "D3DXLoadSurfaceFromSurface returned %#x, expected %#x\n", hr, D3D_OK);
474
475         hr = D3DXLoadSurfaceFromSurface(NULL, NULL, NULL, surf, NULL, NULL, D3DX_DEFAULT, 0);
476         ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromSurface returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
477
478         hr = D3DXLoadSurfaceFromSurface(newsurf, NULL, NULL, NULL, NULL, NULL, D3DX_DEFAULT, 0);
479         ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromSurface returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
480
481         check_release((IUnknown*)newsurf, 0);
482     } else skip("Failed to create a second surface\n");
483
484     check_release((IUnknown*)surf, 0);
485
486
487     /* test color conversion */
488     /* A8R8G8B8 */
489     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 2, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf, NULL);
490     if(FAILED(hr)) skip("Failed to create a surface (%#x)\n", hr);
491     else {
492         hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a8r3g3b2, D3DFMT_A8R3G3B2, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
493         ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
494         IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
495         check_pixel_4bpp(lockrect, 0, 0, 0x57dbffff);
496         check_pixel_4bpp(lockrect, 1, 0, 0x98ffff00);
497         check_pixel_4bpp(lockrect, 0, 1, 0xacdbff55);
498         check_pixel_4bpp(lockrect, 1, 1, 0xc8929255);
499         IDirect3DSurface9_UnlockRect(surf);
500
501         hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a1r5g5b5, D3DFMT_A1R5G5B5, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
502         ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
503         IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
504         check_pixel_4bpp(lockrect, 0, 0, 0x008cadad);
505         check_pixel_4bpp(lockrect, 1, 0, 0xff317342);
506         check_pixel_4bpp(lockrect, 0, 1, 0x0008ad10);
507         check_pixel_4bpp(lockrect, 1, 1, 0xff29088c);
508         IDirect3DSurface9_UnlockRect(surf);
509
510         hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_r5g6b5, D3DFMT_R5G6B5, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
511         ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
512         IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
513         check_pixel_4bpp(lockrect, 0, 0, 0xff9cdfb5);
514         check_pixel_4bpp(lockrect, 1, 0, 0xff63b26b);
515         check_pixel_4bpp(lockrect, 0, 1, 0xff085d73);
516         check_pixel_4bpp(lockrect, 1, 1, 0xff425d73);
517         IDirect3DSurface9_UnlockRect(surf);
518
519         hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_g16r16, D3DFMT_G16R16, 8, NULL, &rect, D3DX_FILTER_NONE, 0);
520         ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
521         IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
522         todo_wine {
523             check_pixel_4bpp(lockrect, 0, 0, 0xff3f08ff);
524         }
525         check_pixel_4bpp(lockrect, 1, 0, 0xff44dcff);
526         check_pixel_4bpp(lockrect, 0, 1, 0xff97e4ff);
527         check_pixel_4bpp(lockrect, 1, 1, 0xfffe9aff);
528         IDirect3DSurface9_UnlockRect(surf);
529
530         hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a8b8g8r8, D3DFMT_A8B8G8R8, 8, NULL, &rect, D3DX_FILTER_NONE, 0);
531         ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
532         IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
533         check_pixel_4bpp(lockrect, 0, 0, 0xc3f04c39);
534         check_pixel_4bpp(lockrect, 1, 0, 0x2392e85a);
535         check_pixel_4bpp(lockrect, 0, 1, 0x09fd97b1);
536         check_pixel_4bpp(lockrect, 1, 1, 0x8df62bc3);
537         IDirect3DSurface9_UnlockRect(surf);
538
539         hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a2r10g10b10, D3DFMT_A2R10G10B10, 8, NULL, &rect, D3DX_FILTER_NONE, 0);
540         ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
541         IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
542         check_pixel_4bpp(lockrect, 0, 0, 0x555c95bf);
543         check_pixel_4bpp(lockrect, 1, 0, 0x556d663f);
544         check_pixel_4bpp(lockrect, 0, 1, 0xaac385ad);
545         todo_wine {
546             check_pixel_4bpp(lockrect, 1, 1, 0xfffcc575);
547         }
548         IDirect3DSurface9_UnlockRect(surf);
549
550         hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a8l8,
551                 D3DFMT_A8L8, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
552         ok(SUCCEEDED(hr), "Failed to load surface, hr %#x.\n", hr);
553         hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
554         ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
555         check_pixel_4bpp(lockrect, 0, 0, 0xff000000);
556         check_pixel_4bpp(lockrect, 1, 0, 0x00ffffff);
557         check_pixel_4bpp(lockrect, 0, 1, 0xff303030);
558         check_pixel_4bpp(lockrect, 1, 1, 0x7f7f7f7f);
559         hr = IDirect3DSurface9_UnlockRect(surf);
560         ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
561
562         check_release((IUnknown*)surf, 0);
563     }
564
565     /* A1R5G5B5 */
566     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 2, D3DFMT_A1R5G5B5, D3DPOOL_DEFAULT, &surf, NULL);
567     if(FAILED(hr)) skip("Failed to create a surface (%#x)\n", hr);
568     else {
569         hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a8r3g3b2, D3DFMT_A8R3G3B2, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
570         ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
571         IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
572         check_pixel_2bpp(lockrect, 0, 0, 0x6fff);
573         check_pixel_2bpp(lockrect, 1, 0, 0xffe0);
574         check_pixel_2bpp(lockrect, 0, 1, 0xefea);
575         check_pixel_2bpp(lockrect, 1, 1, 0xca4a);
576         IDirect3DSurface9_UnlockRect(surf);
577
578         hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a1r5g5b5, D3DFMT_A1R5G5B5, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
579         ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
580         IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
581         check_pixel_2bpp(lockrect, 0, 0, 0x46b5);
582         check_pixel_2bpp(lockrect, 1, 0, 0x99c8);
583         check_pixel_2bpp(lockrect, 0, 1, 0x06a2);
584         check_pixel_2bpp(lockrect, 1, 1, 0x9431);
585         IDirect3DSurface9_UnlockRect(surf);
586
587         hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_r5g6b5, D3DFMT_R5G6B5, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
588         ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
589         IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
590         check_pixel_2bpp(lockrect, 0, 0, 0xcf76);
591         check_pixel_2bpp(lockrect, 1, 0, 0xb2cd);
592         check_pixel_2bpp(lockrect, 0, 1, 0x856e);
593         check_pixel_2bpp(lockrect, 1, 1, 0xa16e);
594         IDirect3DSurface9_UnlockRect(surf);
595
596         hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_g16r16, D3DFMT_G16R16, 8, NULL, &rect, D3DX_FILTER_NONE, 0);
597         ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
598         IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
599         todo_wine {
600             check_pixel_2bpp(lockrect, 0, 0, 0xa03f);
601         }
602         check_pixel_2bpp(lockrect, 1, 0, 0xa37f);
603         check_pixel_2bpp(lockrect, 0, 1, 0xcb9f);
604         check_pixel_2bpp(lockrect, 1, 1, 0xfe7f);
605         IDirect3DSurface9_UnlockRect(surf);
606
607         hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a8b8g8r8, D3DFMT_A8B8G8R8, 8, NULL, &rect, D3DX_FILTER_NONE, 0);
608         ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
609         IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
610         todo_wine {
611             check_pixel_2bpp(lockrect, 0, 0, 0xf527);
612             check_pixel_2bpp(lockrect, 1, 0, 0x4b8b);
613         }
614         check_pixel_2bpp(lockrect, 0, 1, 0x7e56);
615         check_pixel_2bpp(lockrect, 1, 1, 0xf8b8);
616         IDirect3DSurface9_UnlockRect(surf);
617
618         hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a2r10g10b10, D3DFMT_A2R10G10B10, 8, NULL, &rect, D3DX_FILTER_NONE, 0);
619         ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
620         IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
621         check_pixel_2bpp(lockrect, 0, 0, 0x2e57);
622         todo_wine {
623             check_pixel_2bpp(lockrect, 1, 0, 0x3588);
624         }
625         check_pixel_2bpp(lockrect, 0, 1, 0xe215);
626         check_pixel_2bpp(lockrect, 1, 1, 0xff0e);
627         IDirect3DSurface9_UnlockRect(surf);
628
629         hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a8l8,
630                 D3DFMT_A8L8, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
631         ok(SUCCEEDED(hr), "Failed to load surface, hr %#x.\n", hr);
632         hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
633         ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
634         check_pixel_2bpp(lockrect, 0, 0, 0x8000);
635         check_pixel_2bpp(lockrect, 1, 0, 0x7fff);
636         check_pixel_2bpp(lockrect, 0, 1, 0x98c6);
637         check_pixel_2bpp(lockrect, 1, 1, 0x3def);
638         hr = IDirect3DSurface9_UnlockRect(surf);
639         ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
640
641         check_release((IUnknown*)surf, 0);
642     }
643
644     /* A8L8 */
645     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 2, D3DFMT_A8L8, D3DPOOL_DEFAULT, &surf, NULL);
646     if (FAILED(hr))
647         skip("Failed to create A8L8 surface, hr %#x.\n", hr);
648     else
649     {
650         hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a8r3g3b2,
651                 D3DFMT_A8R3G3B2, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
652         ok(SUCCEEDED(hr), "Failed to load surface, hr %#x.\n", hr);
653         hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
654         ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
655         check_pixel_2bpp(lockrect, 0, 0, 0x57f7);
656         check_pixel_2bpp(lockrect, 1, 0, 0x98ed);
657         check_pixel_2bpp(lockrect, 0, 1, 0xaceb);
658         check_pixel_2bpp(lockrect, 1, 1, 0xc88d);
659         hr = IDirect3DSurface9_UnlockRect(surf);
660         ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
661
662         hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a1r5g5b5,
663                 D3DFMT_A1R5G5B5, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
664         ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
665         hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
666         ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
667         check_pixel_2bpp(lockrect, 0, 0, 0x00a6);
668         check_pixel_2bpp(lockrect, 1, 0, 0xff62);
669         check_pixel_2bpp(lockrect, 0, 1, 0x007f);
670         check_pixel_2bpp(lockrect, 1, 1, 0xff19);
671         hr = IDirect3DSurface9_UnlockRect(surf);
672         ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
673
674         hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_r5g6b5,
675                 D3DFMT_R5G6B5, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
676         ok(SUCCEEDED(hr), "Failed to load surface, hr %#x.\n", hr);
677         hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
678         ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
679         check_pixel_2bpp(lockrect, 0, 0, 0xffce);
680         check_pixel_2bpp(lockrect, 1, 0, 0xff9c);
681         check_pixel_2bpp(lockrect, 0, 1, 0xff4d);
682         check_pixel_2bpp(lockrect, 1, 1, 0xff59);
683         hr = IDirect3DSurface9_UnlockRect(surf);
684         ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
685
686         hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_g16r16,
687                 D3DFMT_G16R16, 8, NULL, &rect, D3DX_FILTER_NONE, 0);
688         ok(SUCCEEDED(hr), "Failed to load surface, hr %#x.\n", hr);
689         hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
690         ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
691         check_pixel_2bpp(lockrect, 0, 0, 0xff25);
692         check_pixel_2bpp(lockrect, 1, 0, 0xffbe);
693         check_pixel_2bpp(lockrect, 0, 1, 0xffd6);
694         check_pixel_2bpp(lockrect, 1, 1, 0xffb6);
695         hr = IDirect3DSurface9_UnlockRect(surf);
696         ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
697
698         hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a8b8g8r8,
699                 D3DFMT_A8B8G8R8, 8, NULL, &rect, D3DX_FILTER_NONE, 0);
700         ok(SUCCEEDED(hr), "Failed to load surface, hr %#x.\n", hr);
701         hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
702         ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
703         check_pixel_2bpp(lockrect, 0, 0, 0xc36d);
704         check_pixel_2bpp(lockrect, 1, 0, 0x23cb);
705         check_pixel_2bpp(lockrect, 0, 1, 0x09af);
706         check_pixel_2bpp(lockrect, 1, 1, 0x8d61);
707         hr = IDirect3DSurface9_UnlockRect(surf);
708         ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
709
710         hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a2r10g10b10,
711                 D3DFMT_A2R10G10B10, 8, NULL, &rect, D3DX_FILTER_NONE, 0);
712         ok(SUCCEEDED(hr), "Failed to load surface, hr %#x.\n", hr);
713         hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
714         ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
715         check_pixel_2bpp(lockrect, 0, 0, 0x558c);
716         check_pixel_2bpp(lockrect, 1, 0, 0x5565);
717         check_pixel_2bpp(lockrect, 0, 1, 0xaa95);
718         check_pixel_2bpp(lockrect, 1, 1, 0xffcb);
719         hr = IDirect3DSurface9_UnlockRect(surf);
720         ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
721
722         hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a8l8,
723                 D3DFMT_A8L8, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
724         ok(SUCCEEDED(hr), "Failed to load surface, hr %#x.\n", hr);
725         hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
726         ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
727         check_pixel_2bpp(lockrect, 0, 0, 0xff00);
728         check_pixel_2bpp(lockrect, 1, 0, 0x00ff);
729         check_pixel_2bpp(lockrect, 0, 1, 0xff30);
730         check_pixel_2bpp(lockrect, 1, 1, 0x7f7f);
731         hr = IDirect3DSurface9_UnlockRect(surf);
732         ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
733
734         check_release((IUnknown*)surf, 0);
735     }
736
737     /* cleanup */
738     if(testdummy_ok) DeleteFileA("testdummy.bmp");
739     if(testbitmap_ok) DeleteFileA("testbitmap.bmp");
740 }
741
742 static void test_D3DXCreateCubeTexture(IDirect3DDevice9 *device)
743 {
744     HRESULT hr;
745     ULONG ref;
746     DWORD levelcount;
747     IDirect3DCubeTexture9 *cube_texture;
748     D3DSURFACE_DESC surface_desc;
749
750     todo_wine {
751         hr = D3DXCreateCubeTextureFromFileInMemory(NULL, dds_cube_map, sizeof(dds_cube_map), &cube_texture);
752         ok(hr == D3DERR_INVALIDCALL, "D3DXCreateCubeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
753
754         hr = D3DXCreateCubeTextureFromFileInMemory(device, NULL, sizeof(dds_cube_map), &cube_texture);
755         ok(hr == D3DERR_INVALIDCALL, "D3DXCreateCubeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
756
757         hr = D3DXCreateCubeTextureFromFileInMemory(device, dds_cube_map, 0, &cube_texture);
758         ok(hr == D3DERR_INVALIDCALL, "D3DXCreateCubeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
759
760         hr = D3DXCreateCubeTextureFromFileInMemory(device, dds_cube_map, sizeof(dds_cube_map), NULL);
761         ok(hr == D3DERR_INVALIDCALL, "D3DXCreateCubeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
762
763         hr = D3DXCreateCubeTextureFromFileInMemory(device, dds_cube_map, sizeof(dds_cube_map), &cube_texture);
764         if(SUCCEEDED(hr)) {
765             levelcount = IDirect3DCubeTexture9_GetLevelCount(cube_texture);
766             ok(levelcount == 3, "GetLevelCount returned %u, expected 3\n", levelcount);
767
768             hr = IDirect3DCubeTexture9_GetLevelDesc(cube_texture, 0, &surface_desc);
769             ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
770             ok(surface_desc.Width == 4, "Got width %u, expected 4\n", surface_desc.Width);
771             ok(surface_desc.Height == 4, "Got height %u, expected 4\n", surface_desc.Height);
772
773             hr = IDirect3DCubeTexture9_GetLevelDesc(cube_texture, 3, &surface_desc);
774             ok(hr == D3DERR_INVALIDCALL, "GetLevelDesc returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
775
776             ref = IDirect3DCubeTexture9_Release(cube_texture);
777             ok(ref == 0, "Invalid reference count. Got %u, expected 0\n", ref);
778         } else skip("Couldn't create cube texture\n");
779     }
780 }
781
782 START_TEST(surface)
783 {
784     HWND wnd;
785     IDirect3D9 *d3d;
786     IDirect3DDevice9 *device;
787     D3DPRESENT_PARAMETERS d3dpp;
788     HRESULT hr;
789
790     wnd = CreateWindow("static", "d3dx9_test", 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL);
791     if (!wnd) {
792         skip("Couldn't create application window\n");
793         return;
794     }
795     d3d = Direct3DCreate9(D3D_SDK_VERSION);
796     if (!d3d) {
797         skip("Couldn't create IDirect3D9 object\n");
798         DestroyWindow(wnd);
799         return;
800     }
801
802     ZeroMemory(&d3dpp, sizeof(d3dpp));
803     d3dpp.Windowed   = TRUE;
804     d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
805     hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, wnd, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &device);
806     if(FAILED(hr)) {
807         skip("Failed to create IDirect3DDevice9 object %#x\n", hr);
808         IDirect3D9_Release(d3d);
809         DestroyWindow(wnd);
810         return;
811     }
812
813     test_D3DXGetImageInfo();
814     test_D3DXLoadSurface(device);
815     test_D3DXCreateCubeTexture(device);
816
817     check_release((IUnknown*)device, 0);
818     check_release((IUnknown*)d3d, 0);
819     DestroyWindow(wnd);
820 }