2 * Copyright 2016 Nikolay Sivov for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "wine/test.h"
24 #include "wine/heap.h"
26 static WCHAR temp_dir
[MAX_PATH
];
28 static BOOL
create_file(const WCHAR
*filename
, const char *data
, unsigned int size
, WCHAR
*out_path
)
35 GetTempPathW(ARRAY_SIZE(temp_dir
), temp_dir
);
36 lstrcpyW(path
, temp_dir
);
37 lstrcatW(path
, filename
);
39 file
= CreateFileW(path
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, 0);
40 if (file
== INVALID_HANDLE_VALUE
)
43 if (WriteFile(file
, data
, size
, &written
, NULL
))
48 lstrcpyW(out_path
, path
);
56 static void delete_file(const WCHAR
*filename
)
60 lstrcpyW(path
, temp_dir
);
61 lstrcatW(path
, filename
);
65 static BOOL
create_directory(const WCHAR
*dir
)
69 lstrcpyW(path
, temp_dir
);
71 return CreateDirectoryW(path
, NULL
);
74 static void delete_directory(const WCHAR
*dir
)
78 lstrcpyW(path
, temp_dir
);
80 RemoveDirectoryW(path
);
83 static void test_D3DX11CreateAsyncMemoryLoader(void)
85 ID3DX11DataLoader
*loader
;
91 hr
= D3DX11CreateAsyncMemoryLoader(NULL
, 0, NULL
);
92 ok(hr
== E_FAIL
, "Got unexpected hr %#x.\n", hr
);
94 hr
= D3DX11CreateAsyncMemoryLoader(NULL
, 0, &loader
);
95 ok(hr
== E_FAIL
, "Got unexpected hr %#x.\n", hr
);
97 hr
= D3DX11CreateAsyncMemoryLoader(&data
, 0, &loader
);
98 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
101 hr
= ID3DX11DataLoader_Decompress(loader
, &ptr
, &size
);
102 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
103 ok(ptr
== &data
, "Got data pointer %p, original %p.\n", ptr
, &data
);
104 ok(!size
, "Got unexpected data size.\n");
106 /* Load() is no-op. */
107 hr
= ID3DX11DataLoader_Load(loader
);
108 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
110 hr
= ID3DX11DataLoader_Destroy(loader
);
111 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
114 hr
= D3DX11CreateAsyncMemoryLoader(&data
, sizeof(data
), &loader
);
115 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
117 /* Load() is no-op. */
118 hr
= ID3DX11DataLoader_Load(loader
);
119 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
121 hr
= ID3DX11DataLoader_Decompress(loader
, &ptr
, &size
);
122 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
123 ok(ptr
== &data
, "Got data pointer %p, original %p.\n", ptr
, &data
);
124 ok(size
== sizeof(data
), "Got unexpected data size.\n");
126 hr
= ID3DX11DataLoader_Destroy(loader
);
127 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
130 static void create_testfile(WCHAR
*path
, const void *data
, int data_len
)
136 GetTempPathW(MAX_PATH
, path
);
137 lstrcatW(path
, L
"asyncloader.data");
139 file
= CreateFileW(path
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
140 ok(file
!= INVALID_HANDLE_VALUE
, "Test file creation failed, at %s, error %d.\n",
141 wine_dbgstr_w(path
), GetLastError());
143 ret
= WriteFile(file
, data
, data_len
, &written
, NULL
);
144 ok(ret
, "Write to test file failed.\n");
149 static void test_D3DX11CreateAsyncFileLoader(void)
151 static const char test_data1
[] = "test data";
152 static const char test_data2
[] = "more test data";
153 ID3DX11DataLoader
*loader
;
154 WCHAR path
[MAX_PATH
];
160 hr
= D3DX11CreateAsyncFileLoaderA(NULL
, NULL
);
161 ok(hr
== E_FAIL
, "Got unexpected hr %#x.\n", hr
);
163 hr
= D3DX11CreateAsyncFileLoaderA(NULL
, &loader
);
164 ok(hr
== E_FAIL
, "Got unexpected hr %#x.\n", hr
);
166 hr
= D3DX11CreateAsyncFileLoaderA("nonexistentfilename", &loader
);
167 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
169 hr
= ID3DX11DataLoader_Decompress(loader
, &ptr
, &size
);
170 ok(hr
== E_FAIL
, "Got unexpected hr %#x.\n", hr
);
172 hr
= ID3DX11DataLoader_Load(loader
);
173 ok(hr
== D3D11_ERROR_FILE_NOT_FOUND
, "Got unexpected hr %#x.\n", hr
);
175 hr
= ID3DX11DataLoader_Decompress(loader
, &ptr
, &size
);
176 ok(hr
== E_FAIL
, "Got unexpected hr %#x.\n", hr
);
178 hr
= ID3DX11DataLoader_Destroy(loader
);
179 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
181 /* Test file sharing using dummy empty file. */
182 create_testfile(path
, test_data1
, sizeof(test_data1
));
184 hr
= D3DX11CreateAsyncFileLoaderW(path
, &loader
);
185 ok(SUCCEEDED(hr
), "Failed to create file loader, hr %#x.\n", hr
);
187 ret
= DeleteFileW(path
);
188 ok(ret
, "DeleteFile() failed, ret %d, error %d.\n", ret
, GetLastError());
190 /* File was removed before Load(). */
191 hr
= ID3DX11DataLoader_Load(loader
);
192 ok(hr
== D3D11_ERROR_FILE_NOT_FOUND
, "Load() returned unexpected result, hr %#x.\n", hr
);
194 /* Create it again. */
195 create_testfile(path
, test_data1
, sizeof(test_data1
));
196 hr
= ID3DX11DataLoader_Load(loader
);
197 ok(SUCCEEDED(hr
), "Load() failed, hr %#x.\n", hr
);
199 /* Already loaded. */
200 hr
= ID3DX11DataLoader_Load(loader
);
201 ok(SUCCEEDED(hr
), "Load() failed, hr %#x.\n", hr
);
203 ret
= DeleteFileW(path
);
204 ok(ret
, "DeleteFile() failed, ret %d, error %d.\n", ret
, GetLastError());
206 /* Already loaded, file removed. */
207 hr
= ID3DX11DataLoader_Load(loader
);
208 ok(hr
== D3D11_ERROR_FILE_NOT_FOUND
, "Load() returned unexpected result, hr %#x.\n", hr
);
210 /* Decompress still works. */
212 hr
= ID3DX11DataLoader_Decompress(loader
, &ptr
, &size
);
213 ok(SUCCEEDED(hr
), "Decompress() failed, hr %#x.\n", hr
);
214 ok(ptr
!= NULL
, "Got unexpected ptr %p.\n", ptr
);
215 ok(size
== sizeof(test_data1
), "Got unexpected decompressed size.\n");
216 if (size
== sizeof(test_data1
))
217 ok(!memcmp(ptr
, test_data1
, size
), "Got unexpected file data.\n");
219 /* Create it again, with different data. */
220 create_testfile(path
, test_data2
, sizeof(test_data2
));
222 hr
= ID3DX11DataLoader_Load(loader
);
223 ok(SUCCEEDED(hr
), "Load() failed, hr %#x.\n", hr
);
226 hr
= ID3DX11DataLoader_Decompress(loader
, &ptr
, &size
);
227 ok(SUCCEEDED(hr
), "Decompress() failed, hr %#x.\n", hr
);
228 ok(ptr
!= NULL
, "Got unexpected ptr %p.\n", ptr
);
229 ok(size
== sizeof(test_data2
), "Got unexpected decompressed size.\n");
230 if (size
== sizeof(test_data2
))
231 ok(!memcmp(ptr
, test_data2
, size
), "Got unexpected file data.\n");
233 hr
= ID3DX11DataLoader_Destroy(loader
);
234 ok(SUCCEEDED(hr
), "Destroy() failed, hr %#x.\n", hr
);
236 ret
= DeleteFileW(path
);
237 ok(ret
, "DeleteFile() failed, ret %d, error %d.\n", ret
, GetLastError());
240 static void test_D3DX11CreateAsyncResourceLoader(void)
242 ID3DX11DataLoader
*loader
;
245 hr
= D3DX11CreateAsyncResourceLoaderA(NULL
, NULL
, NULL
);
246 ok(hr
== E_FAIL
, "Got unexpected hr %#x.\n", hr
);
248 hr
= D3DX11CreateAsyncResourceLoaderA(NULL
, NULL
, &loader
);
249 ok(hr
== D3DX11_ERR_INVALID_DATA
, "Got unexpected hr %#x.\n", hr
);
251 hr
= D3DX11CreateAsyncResourceLoaderA(NULL
, "noname", &loader
);
252 ok(hr
== D3DX11_ERR_INVALID_DATA
, "Got unexpected hr %#x.\n", hr
);
254 hr
= D3DX11CreateAsyncResourceLoaderW(NULL
, NULL
, NULL
);
255 ok(hr
== E_FAIL
, "Got unexpected hr %#x.\n", hr
);
257 hr
= D3DX11CreateAsyncResourceLoaderW(NULL
, NULL
, &loader
);
258 ok(hr
== D3DX11_ERR_INVALID_DATA
, "Got unexpected hr %#x.\n", hr
);
260 hr
= D3DX11CreateAsyncResourceLoaderW(NULL
, L
"noname", &loader
);
261 ok(hr
== D3DX11_ERR_INVALID_DATA
, "Got unexpected hr %#x.\n", hr
);
264 static HRESULT WINAPI
test_d3dinclude_open(ID3DInclude
*iface
, D3D_INCLUDE_TYPE include_type
,
265 const char *filename
, const void *parent_data
, const void **data
, UINT
*bytes
)
267 static const char include1
[] =
268 "#define LIGHT float4(0.0f, 0.2f, 0.5f, 1.0f)\n";
269 static const char include2
[] =
270 "#include \"include1.h\"\n"
271 "float4 light_color = LIGHT;\n";
274 trace("filename %s.\n", filename
);
275 trace("parent_data %p: %s.\n", parent_data
, parent_data
? (char *)parent_data
: "(null)");
277 if (!strcmp(filename
, "include1.h"))
279 buffer
= heap_alloc(strlen(include1
));
280 CopyMemory(buffer
, include1
, strlen(include1
));
281 *bytes
= strlen(include1
);
282 ok(include_type
== D3D_INCLUDE_LOCAL
, "Unexpected include type %d.\n", include_type
);
283 ok(!strncmp(include2
, parent_data
, strlen(include2
)),
284 "Unexpected parent_data value.\n");
286 else if (!strcmp(filename
, "include\\include2.h"))
288 buffer
= heap_alloc(strlen(include2
));
289 CopyMemory(buffer
, include2
, strlen(include2
));
290 *bytes
= strlen(include2
);
291 ok(!parent_data
, "Unexpected parent_data value.\n");
292 ok(include_type
== D3D_INCLUDE_LOCAL
, "Unexpected include type %d.\n", include_type
);
296 ok(0, "Unexpected #include for file %s.\n", filename
);
304 static HRESULT WINAPI
test_d3dinclude_close(ID3DInclude
*iface
, const void *data
)
306 heap_free((void *)data
);
310 static const struct ID3DIncludeVtbl test_d3dinclude_vtbl
=
312 test_d3dinclude_open
,
313 test_d3dinclude_close
316 struct test_d3dinclude
318 ID3DInclude ID3DInclude_iface
;
321 static void test_D3DX11CompileFromFile(void)
323 struct test_d3dinclude include
= {{&test_d3dinclude_vtbl
}};
324 WCHAR filename
[MAX_PATH
], directory
[MAX_PATH
];
325 ID3D10Blob
*blob
= NULL
, *errors
= NULL
;
326 CHAR filename_a
[MAX_PATH
];
329 static const char ps_code
[] =
330 "#include \"include\\include2.h\"\n"
332 "float4 main() : COLOR\n"
334 " return light_color;\n"
336 static const char include1
[] =
337 "#define LIGHT float4(0.0f, 0.2f, 0.5f, 1.0f)\n";
338 static const char include1_wrong
[] =
339 "#define LIGHT nope\n";
340 static const char include2
[] =
341 "#include \"include1.h\"\n"
342 "float4 light_color = LIGHT;\n";
344 create_file(L
"source.ps", ps_code
, strlen(ps_code
), filename
);
345 create_directory(L
"include");
346 create_file(L
"include\\include1.h", include1_wrong
, strlen(include1_wrong
), NULL
);
347 create_file(L
"include1.h", include1
, strlen(include1
), NULL
);
348 create_file(L
"include\\include2.h", include2
, strlen(include2
), NULL
);
350 hr
= D3DX11CompileFromFileW(filename
, NULL
, &include
.ID3DInclude_iface
, "main", "ps_2_0", 0, 0, NULL
, &blob
, &errors
, &result
);
351 todo_wine
ok(hr
== S_OK
&& hr
== result
, "Got hr %#x, result %#x.\n", hr
, result
);
352 todo_wine
ok(!!blob
, "Got unexpected blob.\n");
353 ok(!errors
, "Got unexpected errors.\n");
356 ID3D10Blob_Release(blob
);
360 /* Windows always seems to resolve includes from the initial file location
361 * instead of using the immediate parent, as it would be the case for
362 * standard C preprocessor includes. */
363 hr
= D3DX11CompileFromFileW(filename
, NULL
, NULL
, "main", "ps_2_0", 0, 0, NULL
, &blob
, &errors
, &result
);
364 todo_wine
ok(hr
== S_OK
&& hr
== result
, "Got hr %#x, result %#x.\n", hr
, result
);
365 todo_wine
ok(!!blob
, "Got unexpected blob.\n");
366 ok(!errors
, "Got unexpected errors.\n");
369 ID3D10Blob_Release(blob
);
373 len
= WideCharToMultiByte(CP_ACP
, 0, filename
, -1, NULL
, 0, NULL
, NULL
);
374 WideCharToMultiByte(CP_ACP
, 0, filename
, -1, filename_a
, len
, NULL
, NULL
);
375 hr
= D3DX11CompileFromFileA(filename_a
, NULL
, NULL
, "main", "ps_2_0", 0, 0, NULL
, &blob
, &errors
, &result
);
376 todo_wine
ok(hr
== S_OK
&& hr
== result
, "Got hr %#x, result %#x.\n", hr
, result
);
377 todo_wine
ok(!!blob
, "Got unexpected blob.\n");
378 ok(!errors
, "Got unexpected errors.\n");
381 ID3D10Blob_Release(blob
);
385 GetCurrentDirectoryW(MAX_PATH
, directory
);
386 SetCurrentDirectoryW(temp_dir
);
388 hr
= D3DX11CompileFromFileW(L
"source.ps", NULL
, NULL
, "main", "ps_2_0", 0, 0, NULL
, &blob
, &errors
, &result
);
389 todo_wine
ok(hr
== S_OK
&& hr
== result
, "Got hr %#x, result %#x.\n", hr
, result
);
390 todo_wine
ok(!!blob
, "Got unexpected blob.\n");
391 ok(!errors
, "Got unexpected errors.\n");
394 ID3D10Blob_Release(blob
);
398 SetCurrentDirectoryW(directory
);
400 delete_file(L
"source.ps");
401 delete_file(L
"include\\include1.h");
402 delete_file(L
"include1.h");
403 delete_file(L
"include\\include2.h");
404 delete_directory(L
"include");
409 test_D3DX11CreateAsyncMemoryLoader();
410 test_D3DX11CreateAsyncFileLoader();
411 test_D3DX11CreateAsyncResourceLoader();
412 test_D3DX11CompileFromFile();