d3dx9/tests: Add a more detailed test for saving a surface to a DDS file.
[wine/multimedia.git] / dlls / d3dx9_36 / tests / surface.c
blob84a70cfd8c292a9b7d0c873821b5d9c6093a661a
1 /*
2 * Tests for the D3DX9 surface functions
4 * Copyright 2009 Tony Wasserka
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.
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.
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
21 #define COBJMACROS
22 #include <assert.h>
23 #include "wine/test.h"
24 #include "d3dx9tex.h"
25 #include "resources.h"
27 static inline int get_ref(IUnknown *obj)
29 IUnknown_AddRef(obj);
30 return IUnknown_Release(obj);
33 #define check_ref(obj, exp) _check_ref(__LINE__, obj, exp)
34 static inline void _check_ref(unsigned int line, IUnknown *obj, int exp)
36 int ref = get_ref(obj);
37 ok_(__FILE__, line)(exp == ref, "Invalid refcount. Expected %d, got %d\n", exp, ref);
40 #define check_release(obj, exp) _check_release(__LINE__, obj, exp)
41 static inline void _check_release(unsigned int line, IUnknown *obj, int exp)
43 int ref = IUnknown_Release(obj);
44 ok_(__FILE__, line)(ref == exp, "Invalid refcount. Expected %d, got %d\n", exp, ref);
47 /* 1x1 bmp (1 bpp) */
48 static const unsigned char bmp01[66] = {
49 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
50 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
51 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
52 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
53 0x00,0x00
56 /* 2x2 A8R8G8B8 pixel data */
57 static const unsigned char pixdata[] = {
58 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
61 /* invalid image file */
62 static const unsigned char noimage[4] = {
63 0x11,0x22,0x33,0x44
66 /* 2x2 24-bit dds, 2 mipmaps */
67 static const unsigned char dds_24bit[] = {
68 0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x0a,0x00,0x02,0x00,0x00,0x00,
69 0x02,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
70 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
71 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
72 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
73 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0xff,0x00,
74 0x00,0xff,0x00,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x40,0x00,
75 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
76 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
79 /* 2x2 16-bit dds, no mipmaps */
80 static const unsigned char dds_16bit[] = {
81 0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x08,0x00,0x02,0x00,0x00,0x00,
82 0x02,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
83 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
84 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
85 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
86 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x7c,0x00,0x00,
87 0xe0,0x03,0x00,0x00,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,
88 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
89 0xff,0x7f,0xff,0x7f,0xff,0x7f,0xff,0x7f
92 /* 4x4 cube map dds */
93 static const unsigned char dds_cube_map[] = {
94 0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x08,0x00,0x04,0x00,0x00,0x00,
95 0x04,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
96 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
97 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
98 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
99 0x04,0x00,0x00,0x00,0x44,0x58,0x54,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
100 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x00,0x00,
101 0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
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 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50,
106 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50,
107 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50
110 /* 4x4x2 volume map dds, 2 mipmaps */
111 static const unsigned char dds_volume_map[] = {
112 0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x8a,0x00,0x04,0x00,0x00,0x00,
113 0x04,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
114 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
115 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
116 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
117 0x04,0x00,0x00,0x00,0x44,0x58,0x54,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
118 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x40,0x00,
119 0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
120 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50,
121 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50,
122 0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x2f,0x7e,0xcf,0x79,0x01,0x54,0x5c,0x5c,
123 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x84,0xef,0x7b,0xaa,0xab,0xab,0xab
126 static HRESULT create_file(const char *filename, const unsigned char *data, const unsigned int size)
128 DWORD received;
129 HANDLE hfile;
131 hfile = CreateFileA(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
132 if(hfile == INVALID_HANDLE_VALUE) return HRESULT_FROM_WIN32(GetLastError());
134 if(WriteFile(hfile, data, size, &received, NULL))
136 CloseHandle(hfile);
137 return D3D_OK;
140 CloseHandle(hfile);
141 return D3DERR_INVALIDCALL;
144 /* dds_header.flags */
145 #define DDS_CAPS 0x00000001
146 #define DDS_HEIGHT 0x00000002
147 #define DDS_WIDTH 0x00000004
148 #define DDS_PITCH 0x00000008
149 #define DDS_PIXELFORMAT 0x00001000
150 #define DDS_LINEARSIZE 0x00080000
152 /* dds_header.caps */
153 #define DDS_CAPS_TEXTURE 0x00001000
155 /* dds_pixel_format.flags */
156 #define DDS_PF_ALPHA 0x00000001
157 #define DDS_PF_ALPHA_ONLY 0x00000002
158 #define DDS_PF_FOURCC 0x00000004
159 #define DDS_PF_RGB 0x00000040
160 #define DDS_PF_LUMINANCE 0x00020000
161 #define DDS_PF_BUMPDUDV 0x00080000
163 struct dds_pixel_format
165 DWORD size;
166 DWORD flags;
167 DWORD fourcc;
168 DWORD bpp;
169 DWORD rmask;
170 DWORD gmask;
171 DWORD bmask;
172 DWORD amask;
175 struct dds_header
177 DWORD magic;
178 DWORD size;
179 DWORD flags;
180 DWORD height;
181 DWORD width;
182 DWORD pitch_or_linear_size;
183 DWORD depth;
184 DWORD miplevels;
185 DWORD reserved[11];
186 struct dds_pixel_format pixel_format;
187 DWORD caps;
188 DWORD caps2;
189 DWORD reserved2[3];
192 /* fills dds_header with reasonable default values */
193 static void fill_dds_header(struct dds_header *header)
195 memset(header, 0, sizeof(*header));
197 header->magic = MAKEFOURCC('D','D','S',' ');
198 header->size = sizeof(*header);
199 header->flags = DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT;
200 header->height = 4;
201 header->width = 4;
202 header->pixel_format.size = sizeof(header->pixel_format);
203 /* X8R8G8B8 */
204 header->pixel_format.flags = DDS_PF_RGB;
205 header->pixel_format.fourcc = 0;
206 header->pixel_format.bpp = 32;
207 header->pixel_format.rmask = 0xff0000;
208 header->pixel_format.gmask = 0x00ff00;
209 header->pixel_format.bmask = 0x0000ff;
210 header->pixel_format.amask = 0;
211 header->caps = DDS_CAPS_TEXTURE;
214 #define check_dds_pixel_format(flags, fourcc, bpp, rmask, gmask, bmask, amask, format) \
215 check_dds_pixel_format_(__LINE__, flags, fourcc, bpp, rmask, gmask, bmask, amask, format)
216 static void check_dds_pixel_format_(unsigned int line,
217 DWORD flags, DWORD fourcc, DWORD bpp,
218 DWORD rmask, DWORD gmask, DWORD bmask, DWORD amask,
219 D3DFORMAT expected_format)
221 HRESULT hr;
222 D3DXIMAGE_INFO info;
223 struct
225 struct dds_header header;
226 BYTE data[256];
227 } dds;
229 fill_dds_header(&dds.header);
230 dds.header.pixel_format.flags = flags;
231 dds.header.pixel_format.fourcc = fourcc;
232 dds.header.pixel_format.bpp = bpp;
233 dds.header.pixel_format.rmask = rmask;
234 dds.header.pixel_format.gmask = gmask;
235 dds.header.pixel_format.bmask = bmask;
236 dds.header.pixel_format.amask = amask;
237 memset(dds.data, 0, sizeof(dds.data));
239 hr = D3DXGetImageInfoFromFileInMemory(&dds, sizeof(dds), &info);
240 ok_(__FILE__, line)(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x for pixel format %#x, expected %#x\n",
241 hr, expected_format, D3D_OK);
242 if (SUCCEEDED(hr))
244 ok_(__FILE__, line)(info.Format == expected_format, "D3DXGetImageInfoFromFileInMemory returned format %#x, expected %#x\n",
245 info.Format, expected_format);
249 static void test_dds_header_handling(void)
251 int i;
252 HRESULT hr;
253 D3DXIMAGE_INFO info;
254 struct
256 struct dds_header header;
257 BYTE data[256];
258 } dds;
260 struct
262 struct dds_pixel_format pixel_format;
263 DWORD flags;
264 DWORD width;
265 DWORD height;
266 DWORD pitch;
267 DWORD pixel_data_size;
268 HRESULT expected_result;
269 } tests[] = {
270 /* pitch is ignored */
271 { { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, 0, 4, 4, 0,
272 63 /* pixel data size */, D3DXERR_INVALIDDATA },
273 { { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDS_PITCH, 4, 4, 0 /* pitch */,
274 64, D3D_OK },
275 { { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDS_PITCH, 4, 4, 1 /* pitch */,
276 64, D3D_OK },
277 { { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDS_PITCH, 4, 4, 2 /* pitch */,
278 64, D3D_OK },
279 { { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDS_PITCH, 4, 4, 3 /* pitch */,
280 64, D3D_OK },
281 { { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDS_PITCH, 4, 4, 4 /* pitch */,
282 64, D3D_OK },
283 { { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDS_PITCH, 4, 4, 16 /* pitch */,
284 64, D3D_OK },
285 { { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDS_PITCH, 4, 4, 1024 /* pitch */,
286 64, D3D_OK },
287 { { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDS_PITCH, 4, 4, -1 /* pitch */,
288 64, D3D_OK },
289 /* linear size is ignored */
290 { { 32, DDS_PF_FOURCC, MAKEFOURCC('D','X','T','1'), 0, 0, 0, 0, 0 }, 0, 4, 4, 0,
291 7 /* pixel data size */, D3DXERR_INVALIDDATA },
292 { { 32, DDS_PF_FOURCC, MAKEFOURCC('D','X','T','1'), 0, 0, 0, 0, 0 }, DDS_LINEARSIZE, 4, 4, 0 /* linear size */,
293 8, D3D_OK },
294 { { 32, DDS_PF_FOURCC, MAKEFOURCC('D','X','T','1'), 0, 0, 0, 0, 0 }, DDS_LINEARSIZE, 4, 4, 1 /* linear size */,
295 8, D3D_OK },
296 { { 32, DDS_PF_FOURCC, MAKEFOURCC('D','X','T','1'), 0, 0, 0, 0, 0 }, DDS_LINEARSIZE, 4, 4, 2 /* linear size */,
297 8, D3D_OK },
298 { { 32, DDS_PF_FOURCC, MAKEFOURCC('D','X','T','1'), 0, 0, 0, 0, 0 }, DDS_LINEARSIZE, 4, 4, 9 /* linear size */,
299 8, D3D_OK },
300 { { 32, DDS_PF_FOURCC, MAKEFOURCC('D','X','T','1'), 0, 0, 0, 0, 0 }, DDS_LINEARSIZE, 4, 4, 16 /* linear size */,
301 8, D3D_OK },
302 { { 32, DDS_PF_FOURCC, MAKEFOURCC('D','X','T','1'), 0, 0, 0, 0, 0 }, DDS_LINEARSIZE, 4, 4, -1 /* linear size */,
303 8, D3D_OK },
304 /* integer overflows */
305 { { 32, DDS_PF_RGB, 0, 32, 0xff0000, 0x00ff00, 0x0000ff, 0 }, 0, 0x80000000, 0x80000000 /* 0x80000000 * 0x80000000 * 4 = 0 */, 0,
306 64, D3D_OK },
307 { { 32, DDS_PF_RGB, 0, 32, 0xff0000, 0x00ff00, 0x0000ff, 0 }, 0, 0x8000100, 0x800100 /* 0x8000100 * 0x800100 * 4 = 262144 */, 0,
308 64, D3DXERR_INVALIDDATA },
309 { { 32, DDS_PF_RGB, 0, 32, 0xff0000, 0x00ff00, 0x0000ff, 0 }, 0, 0x80000001, 0x80000001 /* 0x80000001 * 0x80000001 * 4 = 4 */, 0,
310 4, D3D_OK },
311 { { 32, DDS_PF_RGB, 0, 32, 0xff0000, 0x00ff00, 0x0000ff, 0 }, 0, 0x80000001, 0x80000001 /* 0x80000001 * 0x80000001 * 4 = 4 */, 0,
312 3 /* pixel data size */, D3DXERR_INVALIDDATA }
315 memset(&dds, 0, sizeof(dds));
317 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
319 DWORD file_size = sizeof(dds.header) + tests[i].pixel_data_size;
320 assert(file_size <= sizeof(dds));
322 fill_dds_header(&dds.header);
323 dds.header.flags |= tests[i].flags;
324 dds.header.width = tests[i].width;
325 dds.header.height = tests[i].height;
326 dds.header.pitch_or_linear_size = tests[i].pitch;
327 memcpy(&dds.header.pixel_format, &tests[i].pixel_format, sizeof(struct dds_pixel_format));
329 hr = D3DXGetImageInfoFromFileInMemory(&dds, file_size, &info);
330 ok(hr == tests[i].expected_result, "%d: D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", i, hr, tests[i].expected_result);
334 static void test_D3DXGetImageInfo(void)
336 HRESULT hr;
337 D3DXIMAGE_INFO info;
338 BOOL testdummy_ok, testbitmap_ok;
340 hr = create_file("testdummy.bmp", noimage, sizeof(noimage)); /* invalid image */
341 testdummy_ok = SUCCEEDED(hr);
343 hr = create_file("testbitmap.bmp", bmp01, sizeof(bmp01)); /* valid image */
344 testbitmap_ok = SUCCEEDED(hr);
346 /* D3DXGetImageInfoFromFile */
347 if(testbitmap_ok) {
348 hr = D3DXGetImageInfoFromFileA("testbitmap.bmp", &info);
349 ok(hr == D3D_OK, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3D_OK);
351 hr = D3DXGetImageInfoFromFileA("testbitmap.bmp", NULL); /* valid image, second parameter is NULL */
352 ok(hr == D3D_OK, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3D_OK);
353 } else skip("Couldn't create \"testbitmap.bmp\"\n");
355 if(testdummy_ok) {
356 hr = D3DXGetImageInfoFromFileA("testdummy.bmp", NULL); /* invalid image, second parameter is NULL */
357 ok(hr == D3D_OK, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3D_OK);
359 hr = D3DXGetImageInfoFromFileA("testdummy.bmp", &info);
360 ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
361 } else skip("Couldn't create \"testdummy.bmp\"\n");
363 hr = D3DXGetImageInfoFromFileA("filedoesnotexist.bmp", &info);
364 ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
366 hr = D3DXGetImageInfoFromFileA("filedoesnotexist.bmp", NULL);
367 ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
369 hr = D3DXGetImageInfoFromFileA("", &info);
370 ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
372 hr = D3DXGetImageInfoFromFileA(NULL, &info);
373 ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
375 hr = D3DXGetImageInfoFromFileA(NULL, NULL);
376 ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
379 /* D3DXGetImageInfoFromResource */
380 todo_wine {
381 hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDB_BITMAP_1x1), &info); /* RT_BITMAP */
382 ok(hr == D3D_OK, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3D_OK);
384 hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDB_BITMAP_1x1), NULL);
385 ok(hr == D3D_OK, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3D_OK);
388 hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDD_BITMAPDATA_1x1), &info); /* RT_RCDATA */
389 ok(hr == D3D_OK, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3D_OK);
391 hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDS_STRING), &info);
392 ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
394 hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDS_STRING), NULL);
395 ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
397 hr = D3DXGetImageInfoFromResourceA(NULL, "resourcedoesnotexist", &info);
398 ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
400 hr = D3DXGetImageInfoFromResourceA(NULL, "resourcedoesnotexist", NULL);
401 ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
403 hr = D3DXGetImageInfoFromResourceA(NULL, NULL, NULL);
404 ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
407 /* D3DXGetImageInfoFromFileInMemory */
408 hr = D3DXGetImageInfoFromFileInMemory(bmp01, sizeof(bmp01), &info);
409 ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
411 hr = D3DXGetImageInfoFromFileInMemory(bmp01, sizeof(bmp01)+5, &info); /* too large size */
412 ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
414 hr = D3DXGetImageInfoFromFileInMemory(bmp01, sizeof(bmp01), NULL);
415 ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
417 hr = D3DXGetImageInfoFromFileInMemory(noimage, sizeof(noimage), NULL);
418 ok(hr == D3D_OK, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3D_OK);
420 hr = D3DXGetImageInfoFromFileInMemory(noimage, sizeof(noimage), &info);
421 ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
423 todo_wine {
424 hr = D3DXGetImageInfoFromFileInMemory(bmp01, sizeof(bmp01)-1, &info);
425 ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
428 hr = D3DXGetImageInfoFromFileInMemory(bmp01+1, sizeof(bmp01)-1, &info);
429 ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
431 hr = D3DXGetImageInfoFromFileInMemory(bmp01, 0, &info);
432 ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
434 hr = D3DXGetImageInfoFromFileInMemory(bmp01, 0, NULL);
435 ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
437 hr = D3DXGetImageInfoFromFileInMemory(noimage, 0, &info);
438 ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
440 hr = D3DXGetImageInfoFromFileInMemory(noimage, 0, NULL);
441 ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
443 hr = D3DXGetImageInfoFromFileInMemory(NULL, 0, &info);
444 ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
446 hr = D3DXGetImageInfoFromFileInMemory(NULL, 4, NULL);
447 ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
449 hr = D3DXGetImageInfoFromFileInMemory(NULL, 4, &info);
450 ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
452 hr = D3DXGetImageInfoFromFileInMemory(NULL, 0, NULL);
453 ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
456 /* test DDS support */
457 hr = D3DXGetImageInfoFromFileInMemory(dds_24bit, sizeof(dds_24bit), &info);
458 ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
459 if (hr == D3D_OK) {
460 ok(info.Width == 2, "Got width %u, expected 2\n", info.Width);
461 ok(info.Height == 2, "Got height %u, expected 2\n", info.Height);
462 ok(info.Depth == 1, "Got depth %u, expected 1\n", info.Depth);
463 ok(info.MipLevels == 2, "Got miplevels %u, expected 2\n", info.MipLevels);
464 ok(info.Format == D3DFMT_R8G8B8, "Got format %#x, expected %#x\n", info.Format, D3DFMT_R8G8B8);
465 ok(info.ResourceType == D3DRTYPE_TEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_TEXTURE);
466 ok(info.ImageFileFormat == D3DXIFF_DDS, "Got image file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_DDS);
467 } else skip("Couldn't get image info from 24-bit DDS file in memory\n");
469 hr = D3DXGetImageInfoFromFileInMemory(dds_16bit, sizeof(dds_16bit), &info);
470 ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
471 if (hr == D3D_OK) {
472 ok(info.Width == 2, "Got width %u, expected 2\n", info.Width);
473 ok(info.Height == 2, "Got height %u, expected 2\n", info.Height);
474 ok(info.Depth == 1, "Got depth %u, expected 1\n", info.Depth);
475 ok(info.MipLevels == 1, "Got miplevels %u, expected 1\n", info.MipLevels);
476 ok(info.Format == D3DFMT_X1R5G5B5, "Got format %#x, expected %#x\n", info.Format, D3DFMT_X1R5G5B5);
477 ok(info.ResourceType == D3DRTYPE_TEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_TEXTURE);
478 ok(info.ImageFileFormat == D3DXIFF_DDS, "Got image file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_DDS);
479 } else skip("Couldn't get image info from 16-bit DDS file in memory\n");
481 hr = D3DXGetImageInfoFromFileInMemory(dds_cube_map, sizeof(dds_cube_map), &info);
482 ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
483 if (hr == D3D_OK) {
484 ok(info.Width == 4, "Got width %u, expected 4\n", info.Width);
485 ok(info.Height == 4, "Got height %u, expected 4\n", info.Height);
486 ok(info.Depth == 1, "Got depth %u, expected 1\n", info.Depth);
487 ok(info.MipLevels == 1, "Got miplevels %u, expected 1\n", info.MipLevels);
488 ok(info.Format == D3DFMT_DXT5, "Got format %#x, expected %#x\n", info.Format, D3DFMT_DXT5);
489 ok(info.ResourceType == D3DRTYPE_CUBETEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_CUBETEXTURE);
490 ok(info.ImageFileFormat == D3DXIFF_DDS, "Got image file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_DDS);
491 } else skip("Couldn't get image info from cube map in memory\n");
493 hr = D3DXGetImageInfoFromFileInMemory(dds_volume_map, sizeof(dds_volume_map), &info);
494 ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
495 if (hr == D3D_OK) {
496 ok(info.Width == 4, "Got width %u, expected 4\n", info.Width);
497 ok(info.Height == 4, "Got height %u, expected 4\n", info.Height);
498 ok(info.Depth == 2, "Got depth %u, expected 2\n", info.Depth);
499 ok(info.MipLevels == 3, "Got miplevels %u, expected 3\n", info.MipLevels);
500 ok(info.Format == D3DFMT_DXT3, "Got format %#x, expected %#x\n", info.Format, D3DFMT_DXT3);
501 ok(info.ResourceType == D3DRTYPE_VOLUMETEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_VOLUMETEXTURE);
502 ok(info.ImageFileFormat == D3DXIFF_DDS, "Got image file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_DDS);
503 } else skip("Couldn't get image info from volume map in memory\n");
505 check_dds_pixel_format(DDS_PF_FOURCC, MAKEFOURCC('D','X','T','1'), 0, 0, 0, 0, 0, D3DFMT_DXT1);
506 check_dds_pixel_format(DDS_PF_FOURCC, MAKEFOURCC('D','X','T','2'), 0, 0, 0, 0, 0, D3DFMT_DXT2);
507 check_dds_pixel_format(DDS_PF_FOURCC, MAKEFOURCC('D','X','T','3'), 0, 0, 0, 0, 0, D3DFMT_DXT3);
508 check_dds_pixel_format(DDS_PF_FOURCC, MAKEFOURCC('D','X','T','4'), 0, 0, 0, 0, 0, D3DFMT_DXT4);
509 check_dds_pixel_format(DDS_PF_FOURCC, MAKEFOURCC('D','X','T','5'), 0, 0, 0, 0, 0, D3DFMT_DXT5);
510 check_dds_pixel_format(DDS_PF_FOURCC, MAKEFOURCC('R','G','B','G'), 0, 0, 0, 0, 0, D3DFMT_R8G8_B8G8);
511 check_dds_pixel_format(DDS_PF_FOURCC, MAKEFOURCC('G','R','G','B'), 0, 0, 0, 0, 0, D3DFMT_G8R8_G8B8);
512 check_dds_pixel_format(DDS_PF_FOURCC, MAKEFOURCC('U','Y','V','Y'), 0, 0, 0, 0, 0, D3DFMT_UYVY);
513 check_dds_pixel_format(DDS_PF_FOURCC, MAKEFOURCC('Y','U','Y','2'), 0, 0, 0, 0, 0, D3DFMT_YUY2);
514 check_dds_pixel_format(DDS_PF_RGB, 0, 16, 0xf800, 0x07e0, 0x001f, 0, D3DFMT_R5G6B5);
515 check_dds_pixel_format(DDS_PF_RGB | DDS_PF_ALPHA, 0, 16, 0x7c00, 0x03e0, 0x001f, 0x8000, D3DFMT_A1R5G5B5);
516 check_dds_pixel_format(DDS_PF_RGB | DDS_PF_ALPHA, 0, 16, 0x0f00, 0x00f0, 0x000f, 0xf000, D3DFMT_A4R4G4B4);
517 check_dds_pixel_format(DDS_PF_RGB, 0, 8, 0xe0, 0x1c, 0x03, 0, D3DFMT_R3G3B2);
518 check_dds_pixel_format(DDS_PF_ALPHA_ONLY, 0, 8, 0, 0, 0, 0xff, D3DFMT_A8);
519 check_dds_pixel_format(DDS_PF_RGB | DDS_PF_ALPHA, 0, 16, 0x00e0, 0x001c, 0x0003, 0xff00, D3DFMT_A8R3G3B2);
520 check_dds_pixel_format(DDS_PF_RGB, 0, 16, 0xf00, 0x0f0, 0x00f, 0, D3DFMT_X4R4G4B4);
521 check_dds_pixel_format(DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x3ff00000, 0x000ffc00, 0x000003ff, 0xc0000000, D3DFMT_A2B10G10R10);
522 check_dds_pixel_format(DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x000003ff, 0x000ffc00, 0x3ff00000, 0xc0000000, D3DFMT_A2R10G10B10);
523 check_dds_pixel_format(DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000, D3DFMT_A8R8G8B8);
524 check_dds_pixel_format(DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000, D3DFMT_A8B8G8R8);
525 check_dds_pixel_format(DDS_PF_RGB, 0, 32, 0xff0000, 0x00ff00, 0x0000ff, 0, D3DFMT_X8R8G8B8);
526 check_dds_pixel_format(DDS_PF_RGB, 0, 32, 0x0000ff, 0x00ff00, 0xff0000, 0, D3DFMT_X8B8G8R8);
527 check_dds_pixel_format(DDS_PF_RGB, 0, 32, 0x0000ffff, 0xffff0000, 0, 0, D3DFMT_G16R16);
528 check_dds_pixel_format(DDS_PF_LUMINANCE, 0, 8, 0xff, 0, 0, 0, D3DFMT_L8);
529 check_dds_pixel_format(DDS_PF_LUMINANCE, 0, 16, 0xffff, 0, 0, 0, D3DFMT_L16);
530 check_dds_pixel_format(DDS_PF_LUMINANCE | DDS_PF_ALPHA, 0, 16, 0x00ff, 0, 0, 0xff00, D3DFMT_A8L8);
531 check_dds_pixel_format(DDS_PF_LUMINANCE | DDS_PF_ALPHA, 0, 8, 0x0f, 0, 0, 0xf0, D3DFMT_A4L4);
532 check_dds_pixel_format(DDS_PF_BUMPDUDV, 0, 16, 0x00ff, 0xff00, 0, 0, D3DFMT_V8U8);
533 check_dds_pixel_format(DDS_PF_BUMPDUDV, 0, 32, 0x0000ffff, 0xffff0000, 0, 0, D3DFMT_V16U16);
535 test_dds_header_handling();
537 hr = D3DXGetImageInfoFromFileInMemory(dds_16bit, sizeof(dds_16bit) - 1, &info);
538 ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
540 hr = D3DXGetImageInfoFromFileInMemory(dds_24bit, sizeof(dds_24bit) - 1, &info);
541 ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
543 hr = D3DXGetImageInfoFromFileInMemory(dds_cube_map, sizeof(dds_cube_map) - 1, &info);
544 ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
546 hr = D3DXGetImageInfoFromFileInMemory(dds_volume_map, sizeof(dds_volume_map) - 1, &info);
547 ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
550 /* cleanup */
551 if(testdummy_ok) DeleteFileA("testdummy.bmp");
552 if(testbitmap_ok) DeleteFileA("testbitmap.bmp");
555 #define check_pixel_1bpp(lockrect, x, y, color) _check_pixel_1bpp(__LINE__, lockrect, x, y, color)
556 static inline void _check_pixel_1bpp(unsigned int line, const D3DLOCKED_RECT *lockrect, int x, int y, BYTE expected_color)
558 BYTE color = ((BYTE*)lockrect->pBits)[x + y * lockrect->Pitch];
559 ok_(__FILE__, line)(color == expected_color, "Got color 0x%02x, expected 0x%02x\n", color, expected_color);
562 #define check_pixel_2bpp(lockrect, x, y, color) _check_pixel_2bpp(__LINE__, lockrect, x, y, color)
563 static inline void _check_pixel_2bpp(unsigned int line, const D3DLOCKED_RECT *lockrect, int x, int y, WORD expected_color)
565 WORD color = ((WORD*)lockrect->pBits)[x + y * lockrect->Pitch / 2];
566 ok_(__FILE__, line)(color == expected_color, "Got color 0x%04x, expected 0x%04x\n", color, expected_color);
569 #define check_pixel_4bpp(lockrect, x, y, color) _check_pixel_4bpp(__LINE__, lockrect, x, y, color)
570 static inline void _check_pixel_4bpp(unsigned int line, const D3DLOCKED_RECT *lockrect, int x, int y, DWORD expected_color)
572 DWORD color = ((DWORD*)lockrect->pBits)[x + y * lockrect->Pitch / 4];
573 ok_(__FILE__, line)(color == expected_color, "Got color 0x%08x, expected 0x%08x\n", color, expected_color);
576 static void test_D3DXLoadSurface(IDirect3DDevice9 *device)
578 HRESULT hr;
579 BOOL testdummy_ok, testbitmap_ok;
580 IDirect3DTexture9 *tex;
581 IDirect3DSurface9 *surf, *newsurf;
582 RECT rect, destrect;
583 D3DLOCKED_RECT lockrect;
584 const WORD pixdata_a8r3g3b2[] = { 0x57df, 0x98fc, 0xacdd, 0xc891 };
585 const WORD pixdata_a1r5g5b5[] = { 0x46b5, 0x99c8, 0x06a2, 0x9431 };
586 const WORD pixdata_r5g6b5[] = { 0x9ef6, 0x658d, 0x0aee, 0x42ee };
587 const WORD pixdata_a8l8[] = { 0xff00, 0x00ff, 0xff30, 0x7f7f };
588 const DWORD pixdata_g16r16[] = { 0x07d23fbe, 0xdc7f44a4, 0xe4d8976b, 0x9a84fe89 };
589 const DWORD pixdata_a8b8g8r8[] = { 0xc3394cf0, 0x235ae892, 0x09b197fd, 0x8dc32bf6 };
590 const DWORD pixdata_a2r10g10b10[] = { 0x57395aff, 0x5b7668fd, 0xb0d856b5, 0xff2c61d6 };
592 hr = create_file("testdummy.bmp", noimage, sizeof(noimage)); /* invalid image */
593 testdummy_ok = SUCCEEDED(hr);
595 hr = create_file("testbitmap.bmp", bmp01, sizeof(bmp01)); /* valid image */
596 testbitmap_ok = SUCCEEDED(hr);
598 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf, NULL);
599 if(FAILED(hr)) {
600 skip("Failed to create a surface (%#x)\n", hr);
601 if(testdummy_ok) DeleteFileA("testdummy.bmp");
602 if(testbitmap_ok) DeleteFileA("testbitmap.bmp");
603 return;
606 /* D3DXLoadSurfaceFromFile */
607 if(testbitmap_ok) {
608 hr = D3DXLoadSurfaceFromFileA(surf, NULL, NULL, "testbitmap.bmp", NULL, D3DX_DEFAULT, 0, NULL);
609 ok(hr == D3D_OK, "D3DXLoadSurfaceFromFile returned %#x, expected %#x\n", hr, D3D_OK);
611 hr = D3DXLoadSurfaceFromFileA(NULL, NULL, NULL, "testbitmap.bmp", NULL, D3DX_DEFAULT, 0, NULL);
612 ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromFile returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
613 } else skip("Couldn't create \"testbitmap.bmp\"\n");
615 if(testdummy_ok) {
616 hr = D3DXLoadSurfaceFromFileA(surf, NULL, NULL, "testdummy.bmp", NULL, D3DX_DEFAULT, 0, NULL);
617 ok(hr == D3DXERR_INVALIDDATA, "D3DXLoadSurfaceFromFile returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
618 } else skip("Couldn't create \"testdummy.bmp\"\n");
620 hr = D3DXLoadSurfaceFromFileA(surf, NULL, NULL, NULL, NULL, D3DX_DEFAULT, 0, NULL);
621 ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromFile returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
623 hr = D3DXLoadSurfaceFromFileA(surf, NULL, NULL, "", NULL, D3DX_DEFAULT, 0, NULL);
624 ok(hr == D3DXERR_INVALIDDATA, "D3DXLoadSurfaceFromFile returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
627 /* D3DXLoadSurfaceFromResource */
628 todo_wine {
629 hr = D3DXLoadSurfaceFromResourceA(surf, NULL, NULL, NULL, MAKEINTRESOURCE(IDB_BITMAP_1x1), NULL, D3DX_DEFAULT, 0, NULL);
630 ok(hr == D3D_OK, "D3DXLoadSurfaceFromResource returned %#x, expected %#x\n", hr, D3D_OK);
633 hr = D3DXLoadSurfaceFromResourceA(surf, NULL, NULL, NULL, MAKEINTRESOURCE(IDD_BITMAPDATA_1x1), NULL, D3DX_DEFAULT, 0, NULL);
634 ok(hr == D3D_OK, "D3DXLoadSurfaceFromResource returned %#x, expected %#x\n", hr, D3D_OK);
636 hr = D3DXLoadSurfaceFromResourceA(surf, NULL, NULL, NULL, NULL, NULL, D3DX_DEFAULT, 0, NULL);
637 ok(hr == D3DXERR_INVALIDDATA, "D3DXLoadSurfaceFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
639 hr = D3DXLoadSurfaceFromResourceA(NULL, NULL, NULL, NULL, MAKEINTRESOURCE(IDB_BITMAP_1x1), NULL, D3DX_DEFAULT, 0, NULL);
640 ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromResource returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
642 hr = D3DXLoadSurfaceFromResourceA(surf, NULL, NULL, NULL, MAKEINTRESOURCE(IDS_STRING), NULL, D3DX_DEFAULT, 0, NULL);
643 ok(hr == D3DXERR_INVALIDDATA, "D3DXLoadSurfaceFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
646 /* D3DXLoadSurfaceFromFileInMemory */
647 hr = D3DXLoadSurfaceFromFileInMemory(surf, NULL, NULL, bmp01, sizeof(bmp01), NULL, D3DX_DEFAULT, 0, NULL);
648 ok(hr == D3D_OK, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
650 hr = D3DXLoadSurfaceFromFileInMemory(surf, NULL, NULL, noimage, sizeof(noimage), NULL, D3DX_DEFAULT, 0, NULL);
651 ok(hr == D3DXERR_INVALIDDATA, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
653 hr = D3DXLoadSurfaceFromFileInMemory(surf, NULL, NULL, bmp01, 0, NULL, D3DX_DEFAULT, 0, NULL);
654 ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
656 hr = D3DXLoadSurfaceFromFileInMemory(NULL, NULL, NULL, bmp01, sizeof(bmp01), NULL, D3DX_DEFAULT, 0, NULL);
657 ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
659 hr = D3DXLoadSurfaceFromFileInMemory(surf, NULL, NULL, NULL, 8, NULL, D3DX_DEFAULT, 0, NULL);
660 ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
662 hr = D3DXLoadSurfaceFromFileInMemory(surf, NULL, NULL, NULL, 0, NULL, D3DX_DEFAULT, 0, NULL);
663 ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
665 hr = D3DXLoadSurfaceFromFileInMemory(NULL, NULL, NULL, NULL, 0, NULL, D3DX_DEFAULT, 0, NULL);
666 ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
669 /* D3DXLoadSurfaceFromMemory */
670 SetRect(&rect, 0, 0, 2, 2);
672 hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata, D3DFMT_A8R8G8B8, sizeof(pixdata), NULL, &rect, D3DX_FILTER_NONE, 0);
673 ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
675 hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata, D3DFMT_A8R8G8B8, 0, NULL, &rect, D3DX_FILTER_NONE, 0);
676 ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
678 hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, NULL, D3DFMT_A8R8G8B8, sizeof(pixdata), NULL, &rect, D3DX_DEFAULT, 0);
679 ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
681 hr = D3DXLoadSurfaceFromMemory(NULL, NULL, NULL, pixdata, D3DFMT_A8R8G8B8, sizeof(pixdata), NULL, &rect, D3DX_DEFAULT, 0);
682 ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
684 hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata, D3DFMT_A8R8G8B8, sizeof(pixdata), NULL, NULL, D3DX_DEFAULT, 0);
685 ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
687 hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata, D3DFMT_UNKNOWN, sizeof(pixdata), NULL, &rect, D3DX_DEFAULT, 0);
688 ok(hr == E_FAIL, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, E_FAIL);
690 SetRect(&destrect, -1, -1, 1, 1); /* destination rect is partially outside texture boundaries */
691 hr = D3DXLoadSurfaceFromMemory(surf, NULL, &destrect, pixdata, D3DFMT_A8R8G8B8, sizeof(pixdata), NULL, &rect, D3DX_FILTER_NONE, 0);
692 ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
694 SetRect(&destrect, 255, 255, 257, 257); /* destination rect is partially outside texture boundaries */
695 hr = D3DXLoadSurfaceFromMemory(surf, NULL, &destrect, pixdata, D3DFMT_A8R8G8B8, sizeof(pixdata), NULL, &rect, D3DX_FILTER_NONE, 0);
696 ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
698 SetRect(&destrect, 1, 1, 0, 0); /* left > right, top > bottom */
699 hr = D3DXLoadSurfaceFromMemory(surf, NULL, &destrect, pixdata, D3DFMT_A8R8G8B8, sizeof(pixdata), NULL, &rect, D3DX_FILTER_NONE, 0);
700 ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
702 SetRect(&destrect, 0, 0, 0, 0); /* left = right, top = bottom */
703 hr = D3DXLoadSurfaceFromMemory(surf, NULL, &destrect, pixdata, D3DFMT_A8R8G8B8, sizeof(pixdata), NULL, &rect, D3DX_FILTER_NONE, 0);
704 /* fails when debug version of d3d9 is used */
705 ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
707 SetRect(&destrect, 257, 257, 257, 257); /* left = right, top = bottom, but invalid values */
708 hr = D3DXLoadSurfaceFromMemory(surf, NULL, &destrect, pixdata, D3DFMT_A8R8G8B8, sizeof(pixdata), NULL, &rect, D3DX_FILTER_NONE, 0);
709 ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
712 /* D3DXLoadSurfaceFromSurface */
713 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &newsurf, NULL);
714 if(SUCCEEDED(hr)) {
715 hr = D3DXLoadSurfaceFromSurface(newsurf, NULL, NULL, surf, NULL, NULL, D3DX_DEFAULT, 0);
716 ok(hr == D3D_OK, "D3DXLoadSurfaceFromSurface returned %#x, expected %#x\n", hr, D3D_OK);
718 hr = D3DXLoadSurfaceFromSurface(NULL, NULL, NULL, surf, NULL, NULL, D3DX_DEFAULT, 0);
719 ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromSurface returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
721 hr = D3DXLoadSurfaceFromSurface(newsurf, NULL, NULL, NULL, NULL, NULL, D3DX_DEFAULT, 0);
722 ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromSurface returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
724 check_release((IUnknown*)newsurf, 0);
725 } else skip("Failed to create a second surface\n");
727 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex, NULL);
728 if (SUCCEEDED(hr))
730 IDirect3DTexture9_GetSurfaceLevel(tex, 0, &newsurf);
732 hr = D3DXLoadSurfaceFromSurface(newsurf, NULL, NULL, surf, NULL, NULL, D3DX_DEFAULT, 0);
733 ok(hr == D3D_OK, "D3DXLoadSurfaceFromSurface returned %#x, expected %#x\n", hr, D3D_OK);
735 IDirect3DSurface9_Release(newsurf);
736 IDirect3DTexture9_Release(tex);
737 } else skip("Failed to create texture\n");
739 /* non-lockable render target */
740 hr = IDirect3DDevice9_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &newsurf, NULL);
741 if (SUCCEEDED(hr)) {
742 hr = D3DXLoadSurfaceFromSurface(surf, NULL, NULL, newsurf, NULL, NULL, D3DX_FILTER_NONE, 0);
743 ok(hr == D3D_OK, "D3DXLoadSurfaceFromSurface returned %#x, expected %#x\n", hr, D3D_OK);
745 IDirect3DSurface9_Release(newsurf);
746 } else skip("Failed to create render target surface\n");
748 /* non-lockable multisampled render target */
749 hr = IDirect3DDevice9_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &newsurf, NULL);
750 if (SUCCEEDED(hr)) {
751 hr = D3DXLoadSurfaceFromSurface(surf, NULL, NULL, newsurf, NULL, NULL, D3DX_FILTER_NONE, 0);
752 ok(hr == D3D_OK, "D3DXLoadSurfaceFromSurface returned %#x, expected %#x\n", hr, D3D_OK);
754 IDirect3DSurface9_Release(newsurf);
755 } else skip("Failed to create multisampled render target\n");
757 check_release((IUnknown*)surf, 0);
760 /* test color conversion */
761 /* A8R8G8B8 */
762 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 2, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf, NULL);
763 if(FAILED(hr)) skip("Failed to create a surface (%#x)\n", hr);
764 else {
765 hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a8r3g3b2, D3DFMT_A8R3G3B2, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
766 ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
767 IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
768 check_pixel_4bpp(&lockrect, 0, 0, 0x57dbffff);
769 check_pixel_4bpp(&lockrect, 1, 0, 0x98ffff00);
770 check_pixel_4bpp(&lockrect, 0, 1, 0xacdbff55);
771 check_pixel_4bpp(&lockrect, 1, 1, 0xc8929255);
772 IDirect3DSurface9_UnlockRect(surf);
774 hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a1r5g5b5, D3DFMT_A1R5G5B5, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
775 ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
776 IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
777 check_pixel_4bpp(&lockrect, 0, 0, 0x008cadad);
778 check_pixel_4bpp(&lockrect, 1, 0, 0xff317342);
779 check_pixel_4bpp(&lockrect, 0, 1, 0x0008ad10);
780 check_pixel_4bpp(&lockrect, 1, 1, 0xff29088c);
781 IDirect3DSurface9_UnlockRect(surf);
783 hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_r5g6b5, D3DFMT_R5G6B5, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
784 ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
785 IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
786 check_pixel_4bpp(&lockrect, 0, 0, 0xff9cdfb5);
787 check_pixel_4bpp(&lockrect, 1, 0, 0xff63b26b);
788 check_pixel_4bpp(&lockrect, 0, 1, 0xff085d73);
789 check_pixel_4bpp(&lockrect, 1, 1, 0xff425d73);
790 IDirect3DSurface9_UnlockRect(surf);
792 hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_g16r16, D3DFMT_G16R16, 8, NULL, &rect, D3DX_FILTER_NONE, 0);
793 ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
794 IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
795 todo_wine {
796 check_pixel_4bpp(&lockrect, 0, 0, 0xff3f08ff);
798 check_pixel_4bpp(&lockrect, 1, 0, 0xff44dcff);
799 check_pixel_4bpp(&lockrect, 0, 1, 0xff97e4ff);
800 check_pixel_4bpp(&lockrect, 1, 1, 0xfffe9aff);
801 IDirect3DSurface9_UnlockRect(surf);
803 hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a8b8g8r8, D3DFMT_A8B8G8R8, 8, NULL, &rect, D3DX_FILTER_NONE, 0);
804 ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
805 IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
806 check_pixel_4bpp(&lockrect, 0, 0, 0xc3f04c39);
807 check_pixel_4bpp(&lockrect, 1, 0, 0x2392e85a);
808 check_pixel_4bpp(&lockrect, 0, 1, 0x09fd97b1);
809 check_pixel_4bpp(&lockrect, 1, 1, 0x8df62bc3);
810 IDirect3DSurface9_UnlockRect(surf);
812 hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a2r10g10b10, D3DFMT_A2R10G10B10, 8, NULL, &rect, D3DX_FILTER_NONE, 0);
813 ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
814 IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
815 check_pixel_4bpp(&lockrect, 0, 0, 0x555c95bf);
816 check_pixel_4bpp(&lockrect, 1, 0, 0x556d663f);
817 check_pixel_4bpp(&lockrect, 0, 1, 0xaac385ad);
818 todo_wine {
819 check_pixel_4bpp(&lockrect, 1, 1, 0xfffcc575);
821 IDirect3DSurface9_UnlockRect(surf);
823 hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a8l8,
824 D3DFMT_A8L8, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
825 ok(SUCCEEDED(hr), "Failed to load surface, hr %#x.\n", hr);
826 hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
827 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
828 check_pixel_4bpp(&lockrect, 0, 0, 0xff000000);
829 check_pixel_4bpp(&lockrect, 1, 0, 0x00ffffff);
830 check_pixel_4bpp(&lockrect, 0, 1, 0xff303030);
831 check_pixel_4bpp(&lockrect, 1, 1, 0x7f7f7f7f);
832 hr = IDirect3DSurface9_UnlockRect(surf);
833 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
835 check_release((IUnknown*)surf, 0);
838 /* A1R5G5B5 */
839 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 2, D3DFMT_A1R5G5B5, D3DPOOL_DEFAULT, &surf, NULL);
840 if(FAILED(hr)) skip("Failed to create a surface (%#x)\n", hr);
841 else {
842 hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a8r3g3b2, D3DFMT_A8R3G3B2, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
843 ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
844 IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
845 check_pixel_2bpp(&lockrect, 0, 0, 0x6fff);
846 check_pixel_2bpp(&lockrect, 1, 0, 0xffe0);
847 check_pixel_2bpp(&lockrect, 0, 1, 0xefea);
848 check_pixel_2bpp(&lockrect, 1, 1, 0xca4a);
849 IDirect3DSurface9_UnlockRect(surf);
851 hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a1r5g5b5, D3DFMT_A1R5G5B5, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
852 ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
853 IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
854 check_pixel_2bpp(&lockrect, 0, 0, 0x46b5);
855 check_pixel_2bpp(&lockrect, 1, 0, 0x99c8);
856 check_pixel_2bpp(&lockrect, 0, 1, 0x06a2);
857 check_pixel_2bpp(&lockrect, 1, 1, 0x9431);
858 IDirect3DSurface9_UnlockRect(surf);
860 hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_r5g6b5, D3DFMT_R5G6B5, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
861 ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
862 IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
863 check_pixel_2bpp(&lockrect, 0, 0, 0xcf76);
864 check_pixel_2bpp(&lockrect, 1, 0, 0xb2cd);
865 check_pixel_2bpp(&lockrect, 0, 1, 0x856e);
866 check_pixel_2bpp(&lockrect, 1, 1, 0xa16e);
867 IDirect3DSurface9_UnlockRect(surf);
869 hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_g16r16, D3DFMT_G16R16, 8, NULL, &rect, D3DX_FILTER_NONE, 0);
870 ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
871 IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
872 todo_wine {
873 check_pixel_2bpp(&lockrect, 0, 0, 0xa03f);
875 check_pixel_2bpp(&lockrect, 1, 0, 0xa37f);
876 check_pixel_2bpp(&lockrect, 0, 1, 0xcb9f);
877 check_pixel_2bpp(&lockrect, 1, 1, 0xfe7f);
878 IDirect3DSurface9_UnlockRect(surf);
880 hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a8b8g8r8, D3DFMT_A8B8G8R8, 8, NULL, &rect, D3DX_FILTER_NONE, 0);
881 ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
882 IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
883 todo_wine {
884 check_pixel_2bpp(&lockrect, 0, 0, 0xf527);
885 check_pixel_2bpp(&lockrect, 1, 0, 0x4b8b);
887 check_pixel_2bpp(&lockrect, 0, 1, 0x7e56);
888 check_pixel_2bpp(&lockrect, 1, 1, 0xf8b8);
889 IDirect3DSurface9_UnlockRect(surf);
891 hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a2r10g10b10, D3DFMT_A2R10G10B10, 8, NULL, &rect, D3DX_FILTER_NONE, 0);
892 ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
893 IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
894 check_pixel_2bpp(&lockrect, 0, 0, 0x2e57);
895 todo_wine {
896 check_pixel_2bpp(&lockrect, 1, 0, 0x3588);
898 check_pixel_2bpp(&lockrect, 0, 1, 0xe215);
899 check_pixel_2bpp(&lockrect, 1, 1, 0xff0e);
900 IDirect3DSurface9_UnlockRect(surf);
902 hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a8l8,
903 D3DFMT_A8L8, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
904 ok(SUCCEEDED(hr), "Failed to load surface, hr %#x.\n", hr);
905 hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
906 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
907 check_pixel_2bpp(&lockrect, 0, 0, 0x8000);
908 check_pixel_2bpp(&lockrect, 1, 0, 0x7fff);
909 check_pixel_2bpp(&lockrect, 0, 1, 0x98c6);
910 check_pixel_2bpp(&lockrect, 1, 1, 0x3def);
911 hr = IDirect3DSurface9_UnlockRect(surf);
912 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
914 check_release((IUnknown*)surf, 0);
917 /* A8L8 */
918 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 2, D3DFMT_A8L8, D3DPOOL_DEFAULT, &surf, NULL);
919 if (FAILED(hr))
920 skip("Failed to create A8L8 surface, hr %#x.\n", hr);
921 else
923 hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a8r3g3b2,
924 D3DFMT_A8R3G3B2, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
925 ok(SUCCEEDED(hr), "Failed to load surface, hr %#x.\n", hr);
926 hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
927 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
928 check_pixel_2bpp(&lockrect, 0, 0, 0x57f7);
929 check_pixel_2bpp(&lockrect, 1, 0, 0x98ed);
930 check_pixel_2bpp(&lockrect, 0, 1, 0xaceb);
931 check_pixel_2bpp(&lockrect, 1, 1, 0xc88d);
932 hr = IDirect3DSurface9_UnlockRect(surf);
933 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
935 hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a1r5g5b5,
936 D3DFMT_A1R5G5B5, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
937 ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
938 hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
939 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
940 check_pixel_2bpp(&lockrect, 0, 0, 0x00a6);
941 check_pixel_2bpp(&lockrect, 1, 0, 0xff62);
942 check_pixel_2bpp(&lockrect, 0, 1, 0x007f);
943 check_pixel_2bpp(&lockrect, 1, 1, 0xff19);
944 hr = IDirect3DSurface9_UnlockRect(surf);
945 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
947 hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_r5g6b5,
948 D3DFMT_R5G6B5, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
949 ok(SUCCEEDED(hr), "Failed to load surface, hr %#x.\n", hr);
950 hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
951 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
952 check_pixel_2bpp(&lockrect, 0, 0, 0xffce);
953 check_pixel_2bpp(&lockrect, 1, 0, 0xff9c);
954 check_pixel_2bpp(&lockrect, 0, 1, 0xff4d);
955 check_pixel_2bpp(&lockrect, 1, 1, 0xff59);
956 hr = IDirect3DSurface9_UnlockRect(surf);
957 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
959 hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_g16r16,
960 D3DFMT_G16R16, 8, NULL, &rect, D3DX_FILTER_NONE, 0);
961 ok(SUCCEEDED(hr), "Failed to load surface, hr %#x.\n", hr);
962 hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
963 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
964 check_pixel_2bpp(&lockrect, 0, 0, 0xff25);
965 check_pixel_2bpp(&lockrect, 1, 0, 0xffbe);
966 check_pixel_2bpp(&lockrect, 0, 1, 0xffd6);
967 check_pixel_2bpp(&lockrect, 1, 1, 0xffb6);
968 hr = IDirect3DSurface9_UnlockRect(surf);
969 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
971 hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a8b8g8r8,
972 D3DFMT_A8B8G8R8, 8, NULL, &rect, D3DX_FILTER_NONE, 0);
973 ok(SUCCEEDED(hr), "Failed to load surface, hr %#x.\n", hr);
974 hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
975 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
976 check_pixel_2bpp(&lockrect, 0, 0, 0xc36d);
977 check_pixel_2bpp(&lockrect, 1, 0, 0x23cb);
978 check_pixel_2bpp(&lockrect, 0, 1, 0x09af);
979 check_pixel_2bpp(&lockrect, 1, 1, 0x8d61);
980 hr = IDirect3DSurface9_UnlockRect(surf);
981 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
983 hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a2r10g10b10,
984 D3DFMT_A2R10G10B10, 8, NULL, &rect, D3DX_FILTER_NONE, 0);
985 ok(SUCCEEDED(hr), "Failed to load surface, hr %#x.\n", hr);
986 hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
987 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
988 check_pixel_2bpp(&lockrect, 0, 0, 0x558c);
989 check_pixel_2bpp(&lockrect, 1, 0, 0x5565);
990 check_pixel_2bpp(&lockrect, 0, 1, 0xaa95);
991 check_pixel_2bpp(&lockrect, 1, 1, 0xffcb);
992 hr = IDirect3DSurface9_UnlockRect(surf);
993 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
995 hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a8l8,
996 D3DFMT_A8L8, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
997 ok(SUCCEEDED(hr), "Failed to load surface, hr %#x.\n", hr);
998 hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
999 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
1000 check_pixel_2bpp(&lockrect, 0, 0, 0xff00);
1001 check_pixel_2bpp(&lockrect, 1, 0, 0x00ff);
1002 check_pixel_2bpp(&lockrect, 0, 1, 0xff30);
1003 check_pixel_2bpp(&lockrect, 1, 1, 0x7f7f);
1004 hr = IDirect3DSurface9_UnlockRect(surf);
1005 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
1007 check_release((IUnknown*)surf, 0);
1010 /* DXT1, DXT2, DXT3, DXT4, DXT5 */
1011 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 4, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
1012 if (FAILED(hr))
1013 skip("Failed to create R8G8B8 surface, hr %#x.\n", hr);
1014 else
1016 hr = D3DXLoadSurfaceFromFileInMemory(surf, NULL, NULL, dds_24bit, sizeof(dds_24bit), NULL, D3DX_FILTER_NONE, 0, NULL);
1017 ok(SUCCEEDED(hr), "Failed to load surface, hr %#x.\n", hr);
1019 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 4, D3DFMT_DXT2, D3DPOOL_SYSTEMMEM, &newsurf, NULL);
1020 if (FAILED(hr))
1021 skip("Failed to create DXT2 surface, hr %#x.\n", hr);
1022 else
1024 hr = D3DXLoadSurfaceFromSurface(newsurf, NULL, NULL, surf, NULL, NULL, D3DX_FILTER_NONE, 0);
1025 todo_wine ok(SUCCEEDED(hr), "Failed to convert pixels to DXT2 format.\n");
1026 check_release((IUnknown*)newsurf, 0);
1029 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 4, D3DFMT_DXT3, D3DPOOL_SYSTEMMEM, &newsurf, NULL);
1030 if (FAILED(hr))
1031 skip("Failed to create DXT3 surface, hr %#x.\n", hr);
1032 else
1034 hr = D3DXLoadSurfaceFromSurface(newsurf, NULL, NULL, surf, NULL, NULL, D3DX_FILTER_NONE, 0);
1035 todo_wine ok(SUCCEEDED(hr), "Failed to convert pixels to DXT3 format.\n");
1036 check_release((IUnknown*)newsurf, 0);
1039 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 4, D3DFMT_DXT4, D3DPOOL_SYSTEMMEM, &newsurf, NULL);
1040 if (FAILED(hr))
1041 skip("Failed to create DXT4 surface, hr %#x.\n", hr);
1042 else
1044 hr = D3DXLoadSurfaceFromSurface(newsurf, NULL, NULL, surf, NULL, NULL, D3DX_FILTER_NONE, 0);
1045 todo_wine ok(SUCCEEDED(hr), "Failed to convert pixels to DXT4 format.\n");
1046 check_release((IUnknown*)newsurf, 0);
1049 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 4, D3DFMT_DXT5, D3DPOOL_SYSTEMMEM, &newsurf, NULL);
1050 if (FAILED(hr))
1051 skip("Failed to create DXT5 surface, hr %#x.\n", hr);
1052 else
1054 hr = D3DXLoadSurfaceFromSurface(newsurf, NULL, NULL, surf, NULL, NULL, D3DX_FILTER_NONE, 0);
1055 todo_wine ok(SUCCEEDED(hr), "Failed to convert pixels to DXT5 format.\n");
1056 check_release((IUnknown*)newsurf, 0);
1059 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 4, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &newsurf, NULL);
1060 if (FAILED(hr))
1061 skip("Failed to create DXT1 surface, hr %#x.\n", hr);
1062 else
1064 hr = D3DXLoadSurfaceFromSurface(newsurf, NULL, NULL, surf, NULL, NULL, D3DX_FILTER_NONE, 0);
1065 todo_wine ok(SUCCEEDED(hr), "Failed to convert pixels to DXT1 format.\n");
1067 hr = D3DXLoadSurfaceFromSurface(surf, NULL, NULL, newsurf, NULL, NULL, D3DX_FILTER_NONE, 0);
1068 todo_wine ok(SUCCEEDED(hr), "Failed to convert pixels from DXT1 format.\n");
1070 check_release((IUnknown*)newsurf, 0);
1073 check_release((IUnknown*)surf, 0);
1076 /* cleanup */
1077 if(testdummy_ok) DeleteFileA("testdummy.bmp");
1078 if(testbitmap_ok) DeleteFileA("testbitmap.bmp");
1081 static void test_D3DXSaveSurfaceToFileInMemory(IDirect3DDevice9 *device)
1083 HRESULT hr;
1084 RECT rect;
1085 ID3DXBuffer *buffer;
1086 IDirect3DSurface9 *surface;
1088 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 4, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
1089 if (FAILED(hr)) {
1090 skip("Couldn't create surface\n");
1091 return;
1094 SetRect(&rect, 0, 0, 0, 0);
1095 hr = D3DXSaveSurfaceToFileInMemory(&buffer, D3DXIFF_BMP, surface, NULL, &rect);
1096 /* fails with the debug version of d3d9 */
1097 ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "D3DXSaveSurfaceToFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
1098 if (SUCCEEDED(hr)) {
1099 DWORD size = ID3DXBuffer_GetBufferSize(buffer);
1100 ok(size > 0, "ID3DXBuffer_GetBufferSize returned %u, expected > 0\n", size);
1101 ID3DXBuffer_Release(buffer);
1104 IDirect3DSurface9_Release(surface);
1107 static void test_D3DXSaveSurfaceToFile(IDirect3DDevice9 *device)
1109 HRESULT hr;
1110 IDirect3DSurface9 *surface;
1111 RECT rect;
1112 D3DLOCKED_RECT lock_rect;
1113 D3DXIMAGE_INFO image_info;
1114 const BYTE pixels[] = { 0xff, 0x00, 0x00, 0x00, 0xff, 0x00,
1115 0x00, 0x00, 0xff, 0x00, 0x00, 0xff };
1116 DWORD pitch = sizeof(pixels) / 2;
1118 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 2, D3DFMT_R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
1119 if (FAILED(hr)) {
1120 skip("Couldn't create surface\n");
1121 return;
1124 SetRect(&rect, 0, 0, 2, 2);
1125 hr = D3DXLoadSurfaceFromMemory(surface, NULL, NULL, pixels, D3DFMT_R8G8B8, pitch, NULL, &rect, D3DX_FILTER_NONE, 0);
1126 if (SUCCEEDED(hr)) {
1127 hr = D3DXSaveSurfaceToFileA("saved_surface.bmp", D3DXIFF_BMP, surface, NULL, NULL);
1128 ok(hr == D3D_OK, "D3DXSaveSurfaceToFileA returned %#x, expected %#x\n", hr, D3D_OK);
1130 hr = D3DXLoadSurfaceFromFileA(surface, NULL, NULL, "saved_surface.bmp", NULL, D3DX_FILTER_NONE, 0, &image_info);
1131 ok(hr == D3D_OK, "Couldn't load saved surface %#x\n", hr);
1132 if (FAILED(hr)) goto next_tests;
1134 ok(image_info.Width == 2, "Wrong width %u\n", image_info.Width);
1135 ok(image_info.Height == 2, "Wrong height %u\n", image_info.Height);
1136 ok(image_info.Format == D3DFMT_R8G8B8, "Wrong format %#x\n", image_info.Format);
1137 ok(image_info.ImageFileFormat == D3DXIFF_BMP, "Wrong file format %u\n", image_info.ImageFileFormat);
1139 hr = IDirect3DSurface9_LockRect(surface, &lock_rect, NULL, D3DLOCK_READONLY);
1140 ok(hr == D3D_OK, "Couldn't lock surface %#x\n", hr);
1141 if (FAILED(hr)) goto next_tests;
1143 ok(!memcmp(lock_rect.pBits, pixels, pitch), "Pixel data mismatch in first row\n");
1144 ok(!memcmp((BYTE *)lock_rect.pBits + lock_rect.Pitch, pixels + pitch, pitch), "Pixel data mismatch in second row\n");
1146 IDirect3DSurface9_UnlockRect(surface);
1147 } else skip("Couldn't fill surface\n");
1149 next_tests:
1150 hr = D3DXSaveSurfaceToFileA(NULL, D3DXIFF_BMP, surface, NULL, NULL);
1151 ok(hr == D3DERR_INVALIDCALL, "D3DXSaveSurfaceToFileA returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
1153 /* PPM and TGA are supported, even though MSDN claims they aren't */
1154 todo_wine {
1155 hr = D3DXSaveSurfaceToFileA("saved_surface.ppm", D3DXIFF_PPM, surface, NULL, NULL);
1156 ok(hr == D3D_OK, "D3DXSaveSurfaceToFileA returned %#x, expected %#x\n", hr, D3D_OK);
1157 hr = D3DXSaveSurfaceToFileA("saved_surface.tga", D3DXIFF_TGA, surface, NULL, NULL);
1158 ok(hr == D3D_OK, "D3DXSaveSurfaceToFileA returned %#x, expected %#x\n", hr, D3D_OK);
1161 hr = D3DXSaveSurfaceToFileA("saved_surface.dds", D3DXIFF_DDS, surface, NULL, NULL);
1162 ok(hr == D3D_OK, "D3DXSaveSurfaceToFileA returned %#x, expected %#x\n", hr, D3D_OK);
1163 if (SUCCEEDED(hr)) {
1164 hr = D3DXLoadSurfaceFromFileA(surface, NULL, NULL, "saved_surface.dds", NULL, D3DX_FILTER_NONE, 0, &image_info);
1165 ok(hr == D3D_OK, "Couldn't load saved surface %#x\n", hr);
1167 if (SUCCEEDED(hr)) {
1168 ok(image_info.Width == 2, "Wrong width %u\n", image_info.Width);
1169 ok(image_info.Format == D3DFMT_R8G8B8, "Wrong format %#x\n", image_info.Format);
1170 ok(image_info.ImageFileFormat == D3DXIFF_DDS, "Wrong file format %u\n", image_info.ImageFileFormat);
1172 hr = IDirect3DSurface9_LockRect(surface, &lock_rect, NULL, D3DLOCK_READONLY);
1173 ok(hr == D3D_OK, "Couldn't lock surface %#x\n", hr);
1174 if (SUCCEEDED(hr)) {
1175 ok(!memcmp(lock_rect.pBits, pixels, pitch), "Pixel data mismatch in first row\n");
1176 ok(!memcmp((BYTE *)lock_rect.pBits + lock_rect.Pitch, pixels + pitch, pitch), "Pixel data mismatch in second row\n");
1177 IDirect3DSurface9_UnlockRect(surface);
1180 } else skip("Couldn't save surface\n");
1182 hr = D3DXSaveSurfaceToFileA("saved_surface", D3DXIFF_PFM + 1, surface, NULL, NULL);
1183 ok(hr == D3DERR_INVALIDCALL, "D3DXSaveSurfaceToFileA returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
1185 SetRect(&rect, 0, 0, 4, 4);
1186 hr = D3DXSaveSurfaceToFileA("saved_surface.bmp", D3DXIFF_BMP, surface, NULL, &rect);
1187 ok(hr == D3DERR_INVALIDCALL, "D3DXSaveSurfaceToFileA returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
1188 SetRect(&rect, 2, 0, 1, 4);
1189 hr = D3DXSaveSurfaceToFileA("saved_surface.bmp", D3DXIFF_BMP, surface, NULL, &rect);
1190 ok(hr == D3DERR_INVALIDCALL, "D3DXSaveSurfaceToFileA returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
1191 SetRect(&rect, 0, 2, 4, 1);
1192 hr = D3DXSaveSurfaceToFileA("saved_surface.bmp", D3DXIFF_BMP, surface, NULL, &rect);
1193 ok(hr == D3DERR_INVALIDCALL, "D3DXSaveSurfaceToFileA returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
1194 SetRect(&rect, -1, -1, 2, 2);
1195 hr = D3DXSaveSurfaceToFileA("saved_surface.bmp", D3DXIFF_BMP, surface, NULL, &rect);
1196 ok(hr == D3DERR_INVALIDCALL, "D3DXSaveSurfaceToFileA returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
1197 SetRect(&rect, 0, 0, 0, 0);
1198 hr = D3DXSaveSurfaceToFileA("saved_surface.bmp", D3DXIFF_BMP, surface, NULL, &rect);
1199 /* fails when debug version of d3d9 is used */
1200 ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "D3DXSaveSurfaceToFileA returned %#x, expected %#x\n", hr, D3D_OK);
1202 DeleteFileA("saved_surface.bmp");
1203 DeleteFileA("saved_surface.ppm");
1204 DeleteFileA("saved_surface.tga");
1205 DeleteFileA("saved_surface.dds");
1207 IDirect3DSurface9_Release(surface);
1210 START_TEST(surface)
1212 HWND wnd;
1213 IDirect3D9 *d3d;
1214 IDirect3DDevice9 *device;
1215 D3DPRESENT_PARAMETERS d3dpp;
1216 HRESULT hr;
1218 wnd = CreateWindow("static", "d3dx9_test", 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL);
1219 if (!wnd) {
1220 skip("Couldn't create application window\n");
1221 return;
1223 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1224 if (!d3d) {
1225 skip("Couldn't create IDirect3D9 object\n");
1226 DestroyWindow(wnd);
1227 return;
1230 ZeroMemory(&d3dpp, sizeof(d3dpp));
1231 d3dpp.Windowed = TRUE;
1232 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1233 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, wnd, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &device);
1234 if(FAILED(hr)) {
1235 skip("Failed to create IDirect3DDevice9 object %#x\n", hr);
1236 IDirect3D9_Release(d3d);
1237 DestroyWindow(wnd);
1238 return;
1241 test_D3DXGetImageInfo();
1242 test_D3DXLoadSurface(device);
1243 test_D3DXSaveSurfaceToFileInMemory(device);
1244 test_D3DXSaveSurfaceToFile(device);
1246 check_release((IUnknown*)device, 0);
1247 check_release((IUnknown*)d3d, 0);
1248 DestroyWindow(wnd);