2 * Copyright (C) 2008 Stefan Dösinger
3 * Copyright (C) 2009 Matteo Bruni
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "wine/test.h"
25 #include "resources.h"
27 static HRESULT
create_file(const char *filename
, const char *data
, const unsigned int size
)
32 hfile
= CreateFileA(filename
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, 0);
33 if(hfile
== INVALID_HANDLE_VALUE
) return HRESULT_FROM_WIN32(GetLastError());
35 if(WriteFile(hfile
, data
, size
, &received
, NULL
))
42 return D3DERR_INVALIDCALL
;
45 static HRESULT WINAPI
testD3DXInclude_open(ID3DXInclude
*iface
,
46 D3DXINCLUDE_TYPE include_type
,
47 LPCSTR filename
, LPCVOID parent_data
,
48 LPCVOID
*data
, UINT
*bytes
) {
50 const char include
[] = "#define REGISTER r0\nvs.1.1\n";
51 const char include2
[] = "#include \"incl3.vsh\"\n";
52 const char include3
[] = "vs.1.1\n";
54 trace("filename = %s\n", filename
);
55 trace("parent_data (%p) -> %s\n", parent_data
, parent_data
? (char *)parent_data
: "(null)");
57 if(!strcmp(filename
,"incl.vsh")) {
58 buffer
= HeapAlloc(GetProcessHeap(), 0, sizeof(include
));
59 CopyMemory(buffer
, include
, sizeof(include
));
60 *bytes
= sizeof(include
);
61 /* Also check for the correct parent_data content */
62 ok(parent_data
== NULL
, "wrong parent_data value\n");
64 else if(!strcmp(filename
,"incl3.vsh")) {
65 buffer
= HeapAlloc(GetProcessHeap(), 0, sizeof(include3
));
66 CopyMemory(buffer
, include3
, sizeof(include3
));
67 *bytes
= sizeof(include3
);
68 /* Also check for the correct parent_data content */
69 ok(parent_data
!= NULL
&& !strncmp(include2
, parent_data
, strlen(include2
)), "wrong parent_data value\n");
72 buffer
= HeapAlloc(GetProcessHeap(), 0, sizeof(include2
));
73 CopyMemory(buffer
, include2
, sizeof(include2
));
74 *bytes
= sizeof(include2
);
80 static HRESULT WINAPI
testD3DXInclude_close(ID3DXInclude
*iface
, LPCVOID data
) {
81 HeapFree(GetProcessHeap(), 0, (LPVOID
)data
);
85 static const struct ID3DXIncludeVtbl D3DXInclude_Vtbl
= {
90 struct D3DXIncludeImpl
{
91 ID3DXInclude ID3DXInclude_iface
;
94 static void assembleshader_test(void) {
95 const char test1
[] = {
99 const char testincl
[] = {
100 "#define REGISTER r0\n"
103 const char testshader
[] = {
104 "#include \"incl.vsh\"\n"
107 const char testshader2
[] = {
108 "#include \"incl2.vsh\"\n"
111 const char testshader3
[] = {
112 "#include \"include/incl3.vsh\"\n"
115 const char testincl3
[] = {
116 "#include \"incl4.vsh\"\n"
118 const char testincl4_ok
[] = {
119 "#define REGISTER r0\n"
122 const char testincl4_wrong
[] = {
123 "#error \"wrong include\"\n"
126 LPD3DXBUFFER shader
, messages
;
127 D3DXMACRO defines
[] = {
138 struct D3DXIncludeImpl include
;
139 HRESULT shader_vsh_res
;
144 hr
= D3DXAssembleShader(test1
, strlen(test1
),
145 defines
, NULL
, D3DXSHADER_SKIPVALIDATION
,
147 ok(hr
== D3D_OK
, "pDefines test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
149 trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
150 ID3DXBuffer_Release(messages
);
152 if(shader
) ID3DXBuffer_Release(shader
);
154 /* NULL messages test */
156 hr
= D3DXAssembleShader(test1
, strlen(test1
),
157 defines
, NULL
, D3DXSHADER_SKIPVALIDATION
,
159 ok(hr
== D3D_OK
, "NULL messages test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
160 if(shader
) ID3DXBuffer_Release(shader
);
162 /* NULL shader test */
164 hr
= D3DXAssembleShader(test1
, strlen(test1
),
165 defines
, NULL
, D3DXSHADER_SKIPVALIDATION
,
167 ok(hr
== D3D_OK
, "NULL shader test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
169 trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
170 ID3DXBuffer_Release(messages
);
176 include
.ID3DXInclude_iface
.lpVtbl
= &D3DXInclude_Vtbl
;
177 hr
= D3DXAssembleShader(testshader
, strlen(testshader
), NULL
, &include
.ID3DXInclude_iface
,
178 D3DXSHADER_SKIPVALIDATION
, &shader
, &messages
);
179 ok(hr
== D3D_OK
, "pInclude test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
181 trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
182 ID3DXBuffer_Release(messages
);
184 if(shader
) ID3DXBuffer_Release(shader
);
186 /* "unexpected #include file from memory" test */
189 hr
= D3DXAssembleShader(testshader
, strlen(testshader
),
190 NULL
, NULL
, D3DXSHADER_SKIPVALIDATION
,
192 ok(hr
== D3DXERR_INVALIDDATA
, "D3DXAssembleShader test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
194 trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
195 ID3DXBuffer_Release(messages
);
197 if(shader
) ID3DXBuffer_Release(shader
);
199 /* recursive #include test */
202 hr
= D3DXAssembleShader(testshader2
, strlen(testshader2
), NULL
, &include
.ID3DXInclude_iface
,
203 D3DXSHADER_SKIPVALIDATION
, &shader
, &messages
);
204 ok(hr
== D3D_OK
, "D3DXAssembleShader test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
206 trace("recursive D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
207 ID3DXBuffer_Release(messages
);
209 if(shader
) ID3DXBuffer_Release(shader
);
211 shader_vsh_res
= create_file("shader.vsh", testshader
, sizeof(testshader
) - 1);
212 if(SUCCEEDED(shader_vsh_res
)) {
213 create_file("incl.vsh", testincl
, sizeof(testincl
) - 1);
215 /* D3DXAssembleShaderFromFile + #include test */
218 hr
= D3DXAssembleShaderFromFileA("shader.vsh",
219 NULL
, NULL
, D3DXSHADER_SKIPVALIDATION
,
221 ok(hr
== D3D_OK
, "D3DXAssembleShaderFromFile test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
223 trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
224 ID3DXBuffer_Release(messages
);
226 if(shader
) ID3DXBuffer_Release(shader
);
228 /* D3DXAssembleShaderFromFile + pInclude test */
231 hr
= D3DXAssembleShaderFromFileA("shader.vsh", NULL
, &include
.ID3DXInclude_iface
,
232 D3DXSHADER_SKIPVALIDATION
, &shader
, &messages
);
233 ok(hr
== D3D_OK
, "D3DXAssembleShaderFromFile + pInclude test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
235 trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
236 ID3DXBuffer_Release(messages
);
238 if(shader
) ID3DXBuffer_Release(shader
);
240 create_file("shader3.vsh", testshader3
, sizeof(testshader3
) - 1);
241 create_file("incl4.vsh", testincl4_wrong
, sizeof(testincl4_wrong
) - 1);
242 if(CreateDirectoryA("include", NULL
)) {
243 create_file("include/incl3.vsh", testincl3
, sizeof(testincl3
) - 1);
244 create_file("include/incl4.vsh", testincl4_ok
, sizeof(testincl4_ok
) - 1);
246 /* path search #include test */
249 hr
= D3DXAssembleShaderFromFileA("shader3.vsh", NULL
, NULL
,
250 D3DXSHADER_SKIPVALIDATION
,
252 ok(hr
== D3D_OK
, "D3DXAssembleShaderFromFile path search test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
254 trace("D3DXAssembleShaderFromFile path search messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
255 ID3DXBuffer_Release(messages
);
257 if(shader
) ID3DXBuffer_Release(shader
);
258 } else skip("Couldn't create \"include\" directory\n");
259 } else skip("Couldn't create \"shader.vsh\"\n");
261 /* NULL shader tests */
264 hr
= D3DXAssembleShader(NULL
, 0,
265 NULL
, NULL
, D3DXSHADER_SKIPVALIDATION
,
267 ok(hr
== D3DXERR_INVALIDDATA
, "NULL shader test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
269 trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
270 ID3DXBuffer_Release(messages
);
272 if(shader
) ID3DXBuffer_Release(shader
);
276 hr
= D3DXAssembleShaderFromFileA("nonexistent.vsh",
277 NULL
, NULL
, D3DXSHADER_SKIPVALIDATION
,
279 ok(hr
== D3DXERR_INVALIDDATA
|| hr
== E_FAIL
, /* I get this on WinXP */
280 "D3DXAssembleShaderFromFile nonexistent file test failed with error 0x%x - %d\n",
281 hr
, hr
& 0x0000FFFF);
283 trace("D3DXAssembleShaderFromFile messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
284 ID3DXBuffer_Release(messages
);
286 if(shader
) ID3DXBuffer_Release(shader
);
288 /* D3DXAssembleShaderFromResource test */
291 hr
= D3DXAssembleShaderFromResourceA(NULL
, MAKEINTRESOURCEA(IDB_ASMSHADER
),
292 NULL
, NULL
, D3DXSHADER_SKIPVALIDATION
,
294 ok(hr
== D3D_OK
, "D3DXAssembleShaderFromResource test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
296 trace("D3DXAssembleShaderFromResource messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
297 ID3DXBuffer_Release(messages
);
299 if(shader
) ID3DXBuffer_Release(shader
);
301 /* D3DXAssembleShaderFromResource with missing shader resource test */
304 hr
= D3DXAssembleShaderFromResourceA(NULL
, "notexisting",
305 NULL
, NULL
, D3DXSHADER_SKIPVALIDATION
,
307 ok(hr
== D3DXERR_INVALIDDATA
, "D3DXAssembleShaderFromResource NULL shader test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
309 trace("D3DXAssembleShaderFromResource messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
310 ID3DXBuffer_Release(messages
);
312 if(shader
) ID3DXBuffer_Release(shader
);
315 if(SUCCEEDED(shader_vsh_res
)) {
316 DeleteFileA("shader.vsh");
317 DeleteFileA("incl.vsh");
318 DeleteFileA("shader3.vsh");
319 DeleteFileA("incl4.vsh");
320 DeleteFileA("include/incl3.vsh");
321 DeleteFileA("include/incl4.vsh");
322 RemoveDirectoryA("include");
326 static void d3dxpreprocess_test(void) {
327 const char testincl
[] = {
328 "#define REGISTER r0\n"
331 const char testshader
[] = {
332 "#include \"incl.vsh\"\n"
335 const char testshader3
[] = {
336 "#include \"include/incl3.vsh\"\n"
339 const char testincl3
[] = {
340 "#include \"incl4.vsh\"\n"
342 const char testincl4_ok
[] = {
343 "#define REGISTER r0\n"
346 const char testincl4_wrong
[] = {
347 "#error \"wrong include\"\n"
350 LPD3DXBUFFER shader
, messages
;
351 HRESULT shader_vsh_res
;
352 struct D3DXIncludeImpl include
= {{&D3DXInclude_Vtbl
}};
354 shader_vsh_res
= create_file("shader.vsh", testshader
, sizeof(testshader
) - 1);
355 if(SUCCEEDED(shader_vsh_res
)) {
356 create_file("incl.vsh", testincl
, sizeof(testincl
) - 1);
357 create_file("shader3.vsh", testshader3
, sizeof(testshader3
) - 1);
358 create_file("incl4.vsh", testincl4_wrong
, sizeof(testincl4_wrong
) - 1);
359 if(CreateDirectoryA("include", NULL
)) {
360 create_file("include/incl3.vsh", testincl3
, sizeof(testincl3
) - 1);
361 create_file("include/incl4.vsh", testincl4_ok
, sizeof(testincl4_ok
) - 1);
363 /* path search #include test */
366 hr
= D3DXPreprocessShaderFromFileA("shader3.vsh", NULL
, NULL
,
368 ok(hr
== D3D_OK
, "D3DXPreprocessShaderFromFile path search test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
370 trace("D3DXPreprocessShaderFromFile path search messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
371 ID3DXBuffer_Release(messages
);
373 if(shader
) ID3DXBuffer_Release(shader
);
374 } else skip("Couldn't create \"include\" directory\n");
376 /* D3DXPreprocessShaderFromFile + #include test */
379 hr
= D3DXPreprocessShaderFromFileA("shader.vsh",
382 ok(hr
== D3D_OK
, "D3DXPreprocessShaderFromFile test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
384 trace("D3DXPreprocessShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
385 ID3DXBuffer_Release(messages
);
387 if(shader
) ID3DXBuffer_Release(shader
);
389 /* D3DXPreprocessShaderFromFile + pInclude test */
392 hr
= D3DXPreprocessShaderFromFileA("shader.vsh", NULL
, &include
.ID3DXInclude_iface
,
394 ok(hr
== D3D_OK
, "D3DXPreprocessShaderFromFile + pInclude test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
396 trace("D3DXPreprocessShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
397 ID3DXBuffer_Release(messages
);
399 if(shader
) ID3DXBuffer_Release(shader
);
400 } else skip("Couldn't create \"shader.vsh\"\n");
402 /* NULL shader tests */
405 hr
= D3DXPreprocessShaderFromFileA("nonexistent.vsh",
408 ok(hr
== D3DXERR_INVALIDDATA
|| hr
== E_FAIL
, /* I get this on WinXP */
409 "D3DXPreprocessShaderFromFile nonexistent file test failed with error 0x%x - %d\n",
410 hr
, hr
& 0x0000FFFF);
412 trace("D3DXPreprocessShaderFromFile messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
413 ID3DXBuffer_Release(messages
);
415 if(shader
) ID3DXBuffer_Release(shader
);
417 /* D3DXPreprocessShaderFromResource test */
420 hr
= D3DXPreprocessShaderFromResourceA(NULL
, MAKEINTRESOURCEA(IDB_ASMSHADER
),
423 ok(hr
== D3D_OK
, "D3DXPreprocessShaderFromResource test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
425 trace("D3DXPreprocessShaderFromResource messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
426 ID3DXBuffer_Release(messages
);
428 if(shader
) ID3DXBuffer_Release(shader
);
430 /* D3DXPreprocessShaderFromResource with missing shader resource test */
433 hr
= D3DXPreprocessShaderFromResourceA(NULL
, "notexisting",
436 ok(hr
== D3DXERR_INVALIDDATA
, "D3DXPreprocessShaderFromResource NULL shader test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
438 trace("D3DXPreprocessShaderFromResource messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
439 ID3DXBuffer_Release(messages
);
441 if(shader
) ID3DXBuffer_Release(shader
);
444 if(SUCCEEDED(shader_vsh_res
)) {
445 DeleteFileA("shader.vsh");
446 DeleteFileA("incl.vsh");
447 DeleteFileA("shader3.vsh");
448 DeleteFileA("incl4.vsh");
449 DeleteFileA("include/incl3.vsh");
450 DeleteFileA("include/incl4.vsh");
451 RemoveDirectoryA("include");
457 assembleshader_test();
459 d3dxpreprocess_test();