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
20 #include "wine/test.h"
24 #include "resources.h"
26 static HRESULT
create_file(const char *filename
, const char *data
, const unsigned int size
)
31 hfile
= CreateFileA(filename
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, 0);
32 if(hfile
== INVALID_HANDLE_VALUE
) return HRESULT_FROM_WIN32(GetLastError());
34 if(WriteFile(hfile
, data
, size
, &received
, NULL
))
41 return D3DERR_INVALIDCALL
;
44 static HRESULT WINAPI
testD3DXInclude_open(ID3DXInclude
*iface
,
45 D3DXINCLUDE_TYPE include_type
,
46 LPCSTR filename
, LPCVOID parent_data
,
47 LPCVOID
*data
, UINT
*bytes
) {
49 const char include
[] = "#define REGISTER r0\nvs.1.1\n";
50 const char include2
[] = "#include \"incl3.vsh\"\n";
51 const char include3
[] = "vs.1.1\n";
53 trace("filename = %s\n", filename
);
54 trace("parent_data = (%p) -> %s\n", parent_data
, (char *)parent_data
);
56 if(!strcmp(filename
,"incl.vsh")) {
57 buffer
= HeapAlloc(GetProcessHeap(), 0, sizeof(include
));
58 CopyMemory(buffer
, include
, sizeof(include
));
59 *bytes
= sizeof(include
);
60 /* Also check for the correct parent_data content */
61 ok(parent_data
== NULL
, "wrong parent_data value\n");
63 else if(!strcmp(filename
,"incl3.vsh")) {
64 buffer
= HeapAlloc(GetProcessHeap(), 0, sizeof(include3
));
65 CopyMemory(buffer
, include3
, sizeof(include3
));
66 *bytes
= sizeof(include3
);
67 /* Also check for the correct parent_data content */
68 ok(parent_data
!= NULL
&& !strncmp(include2
, parent_data
, strlen(include2
)), "wrong parent_data value\n");
71 buffer
= HeapAlloc(GetProcessHeap(), 0, sizeof(include2
));
72 CopyMemory(buffer
, include2
, sizeof(include2
));
73 *bytes
= sizeof(include2
);
79 static HRESULT WINAPI
testD3DXInclude_close(ID3DXInclude
*iface
, LPCVOID data
) {
80 HeapFree(GetProcessHeap(), 0, (LPVOID
)data
);
84 static const struct ID3DXIncludeVtbl D3DXInclude_Vtbl
= {
89 struct D3DXIncludeImpl
{
90 const ID3DXIncludeVtbl
*lpVtbl
;
93 static void assembleshader_test(void) {
94 const char test1
[] = {
98 const char testincl
[] = {
99 "#define REGISTER r0\n"
102 const char testshader
[] = {
103 "#include \"incl.vsh\"\n"
106 const char testshader2
[] = {
107 "#include \"incl2.vsh\"\n"
110 const char testshader3
[] = {
111 "#include \"include/incl3.vsh\"\n"
114 const char testincl3
[] = {
115 "#include \"incl4.vsh\"\n"
117 const char testincl4_ok
[] = {
118 "#define REGISTER r0\n"
121 const char testincl4_wrong
[] = {
122 "#error \"wrong include\"\n"
125 LPD3DXBUFFER shader
, messages
;
126 D3DXMACRO defines
[] = {
137 struct D3DXIncludeImpl include
;
138 HRESULT shader_vsh_res
;
143 hr
= D3DXAssembleShader(test1
, strlen(test1
),
144 defines
, NULL
, D3DXSHADER_SKIPVALIDATION
,
146 ok(hr
== D3D_OK
, "pDefines test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
148 trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
149 ID3DXBuffer_Release(messages
);
151 if(shader
) ID3DXBuffer_Release(shader
);
153 /* NULL messages test */
155 hr
= D3DXAssembleShader(test1
, strlen(test1
),
156 defines
, NULL
, D3DXSHADER_SKIPVALIDATION
,
158 ok(hr
== D3D_OK
, "NULL messages test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
159 if(shader
) ID3DXBuffer_Release(shader
);
161 /* NULL shader test */
163 hr
= D3DXAssembleShader(test1
, strlen(test1
),
164 defines
, NULL
, D3DXSHADER_SKIPVALIDATION
,
166 ok(hr
== D3D_OK
, "NULL shader test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
168 trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
169 ID3DXBuffer_Release(messages
);
175 include
.lpVtbl
= &D3DXInclude_Vtbl
;
176 hr
= D3DXAssembleShader(testshader
, strlen(testshader
),
177 NULL
, (LPD3DXINCLUDE
)&include
, D3DXSHADER_SKIPVALIDATION
,
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
),
203 NULL
, (LPD3DXINCLUDE
)&include
, D3DXSHADER_SKIPVALIDATION
,
205 ok(hr
== D3D_OK
, "D3DXAssembleShader test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
207 trace("recursive D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
208 ID3DXBuffer_Release(messages
);
210 if(shader
) ID3DXBuffer_Release(shader
);
212 shader_vsh_res
= create_file("shader.vsh", testshader
, sizeof(testshader
) - 1);
213 if(SUCCEEDED(shader_vsh_res
)) {
214 create_file("incl.vsh", testincl
, sizeof(testincl
) - 1);
216 /* D3DXAssembleShaderFromFile + #include test */
219 hr
= D3DXAssembleShaderFromFileA("shader.vsh",
220 NULL
, NULL
, D3DXSHADER_SKIPVALIDATION
,
222 ok(hr
== D3D_OK
, "D3DXAssembleShaderFromFile test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
224 trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
225 ID3DXBuffer_Release(messages
);
227 if(shader
) ID3DXBuffer_Release(shader
);
229 /* D3DXAssembleShaderFromFile + pInclude test */
232 hr
= D3DXAssembleShaderFromFileA("shader.vsh",
233 NULL
, (LPD3DXINCLUDE
)&include
, D3DXSHADER_SKIPVALIDATION
,
235 ok(hr
== D3D_OK
, "D3DXAssembleShaderFromFile + pInclude test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
237 trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
238 ID3DXBuffer_Release(messages
);
240 if(shader
) ID3DXBuffer_Release(shader
);
242 create_file("shader3.vsh", testshader3
, sizeof(testshader3
) - 1);
243 create_file("incl4.vsh", testincl4_wrong
, sizeof(testincl4_wrong
) - 1);
244 if(CreateDirectoryA("include", NULL
)) {
245 create_file("include/incl3.vsh", testincl3
, sizeof(testincl3
) - 1);
246 create_file("include/incl4.vsh", testincl4_ok
, sizeof(testincl4_ok
) - 1);
248 /* path search #include test */
251 hr
= D3DXAssembleShaderFromFileA("shader3.vsh", NULL
, NULL
,
252 D3DXSHADER_SKIPVALIDATION
,
254 ok(hr
== D3D_OK
, "D3DXAssembleShaderFromFile path search test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
256 trace("D3DXAssembleShaderFromFile path search messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
257 ID3DXBuffer_Release(messages
);
259 if(shader
) ID3DXBuffer_Release(shader
);
260 } else skip("Couldn't create \"include\" directory\n");
261 } else skip("Couldn't create \"shader.vsh\"\n");
263 /* NULL shader tests */
266 hr
= D3DXAssembleShader(NULL
, 0,
267 NULL
, NULL
, D3DXSHADER_SKIPVALIDATION
,
269 ok(hr
== D3DXERR_INVALIDDATA
, "NULL shader test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
271 trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
272 ID3DXBuffer_Release(messages
);
274 if(shader
) ID3DXBuffer_Release(shader
);
278 hr
= D3DXAssembleShaderFromFileA("nonexistent.vsh",
279 NULL
, NULL
, D3DXSHADER_SKIPVALIDATION
,
281 ok(hr
== D3DXERR_INVALIDDATA
|| hr
== E_FAIL
, /* I get this on WinXP */
282 "D3DXAssembleShaderFromFile nonexistent file test failed with error 0x%x - %d\n",
283 hr
, hr
& 0x0000FFFF);
285 trace("D3DXAssembleShaderFromFile messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
286 ID3DXBuffer_Release(messages
);
288 if(shader
) ID3DXBuffer_Release(shader
);
290 /* D3DXAssembleShaderFromResource test */
293 hr
= D3DXAssembleShaderFromResourceA(NULL
, MAKEINTRESOURCEA(IDB_ASMSHADER
),
294 NULL
, NULL
, D3DXSHADER_SKIPVALIDATION
,
296 ok(hr
== D3D_OK
, "D3DXAssembleShaderFromResource test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
298 trace("D3DXAssembleShaderFromResource messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
299 ID3DXBuffer_Release(messages
);
301 if(shader
) ID3DXBuffer_Release(shader
);
303 /* D3DXAssembleShaderFromResource with missing shader resource test */
306 hr
= D3DXAssembleShaderFromResourceA(NULL
, "notexisting",
307 NULL
, NULL
, D3DXSHADER_SKIPVALIDATION
,
309 ok(hr
== D3DXERR_INVALIDDATA
, "D3DXAssembleShaderFromResource NULL shader test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
311 trace("D3DXAssembleShaderFromResource messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
312 ID3DXBuffer_Release(messages
);
314 if(shader
) ID3DXBuffer_Release(shader
);
317 if(SUCCEEDED(shader_vsh_res
)) {
318 DeleteFileA("shader.vsh");
319 DeleteFileA("incl.vsh");
320 DeleteFileA("shader3.vsh");
321 DeleteFileA("incl4.vsh");
322 DeleteFileA("include/incl3.vsh");
323 DeleteFileA("include/incl4.vsh");
324 RemoveDirectoryA("include");
328 static void d3dxpreprocess_test(void) {
329 const char testincl
[] = {
330 "#define REGISTER r0\n"
333 const char testshader
[] = {
334 "#include \"incl.vsh\"\n"
337 const char testshader3
[] = {
338 "#include \"include/incl3.vsh\"\n"
341 const char testincl3
[] = {
342 "#include \"incl4.vsh\"\n"
344 const char testincl4_ok
[] = {
345 "#define REGISTER r0\n"
348 const char testincl4_wrong
[] = {
349 "#error \"wrong include\"\n"
352 LPD3DXBUFFER shader
, messages
;
353 HRESULT shader_vsh_res
;
354 struct D3DXIncludeImpl include
= {&D3DXInclude_Vtbl
};
356 shader_vsh_res
= create_file("shader.vsh", testshader
, sizeof(testshader
) - 1);
357 if(SUCCEEDED(shader_vsh_res
)) {
358 create_file("incl.vsh", testincl
, sizeof(testincl
) - 1);
359 create_file("shader3.vsh", testshader3
, sizeof(testshader3
) - 1);
360 create_file("incl4.vsh", testincl4_wrong
, sizeof(testincl4_wrong
) - 1);
361 if(CreateDirectoryA("include", NULL
)) {
362 create_file("include/incl3.vsh", testincl3
, sizeof(testincl3
) - 1);
363 create_file("include/incl4.vsh", testincl4_ok
, sizeof(testincl4_ok
) - 1);
365 /* path search #include test */
368 hr
= D3DXPreprocessShaderFromFileA("shader3.vsh", NULL
, NULL
,
370 ok(hr
== D3D_OK
, "D3DXPreprocessShaderFromFile path search test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
372 trace("D3DXPreprocessShaderFromFile path search messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
373 ID3DXBuffer_Release(messages
);
375 if(shader
) ID3DXBuffer_Release(shader
);
376 } else skip("Couldn't create \"include\" directory\n");
378 /* D3DXPreprocessShaderFromFile + #include test */
381 hr
= D3DXPreprocessShaderFromFileA("shader.vsh",
384 ok(hr
== D3D_OK
, "D3DXPreprocessShaderFromFile test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
386 trace("D3DXPreprocessShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
387 ID3DXBuffer_Release(messages
);
389 if(shader
) ID3DXBuffer_Release(shader
);
391 /* D3DXPreprocessShaderFromFile + pInclude test */
394 hr
= D3DXPreprocessShaderFromFileA("shader.vsh",
395 NULL
, (LPD3DXINCLUDE
)&include
,
397 ok(hr
== D3D_OK
, "D3DXPreprocessShaderFromFile + pInclude test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
399 trace("D3DXPreprocessShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
400 ID3DXBuffer_Release(messages
);
402 if(shader
) ID3DXBuffer_Release(shader
);
403 } else skip("Couldn't create \"shader.vsh\"\n");
405 /* NULL shader tests */
408 hr
= D3DXPreprocessShaderFromFileA("nonexistent.vsh",
411 ok(hr
== D3DXERR_INVALIDDATA
|| hr
== E_FAIL
, /* I get this on WinXP */
412 "D3DXPreprocessShaderFromFile nonexistent file test failed with error 0x%x - %d\n",
413 hr
, hr
& 0x0000FFFF);
415 trace("D3DXPreprocessShaderFromFile messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
416 ID3DXBuffer_Release(messages
);
418 if(shader
) ID3DXBuffer_Release(shader
);
420 /* D3DXPreprocessShaderFromResource test */
423 hr
= D3DXPreprocessShaderFromResourceA(NULL
, MAKEINTRESOURCEA(IDB_ASMSHADER
),
426 ok(hr
== D3D_OK
, "D3DXPreprocessShaderFromResource test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
428 trace("D3DXPreprocessShaderFromResource messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
429 ID3DXBuffer_Release(messages
);
431 if(shader
) ID3DXBuffer_Release(shader
);
433 /* D3DXPreprocessShaderFromResource with missing shader resource test */
436 hr
= D3DXPreprocessShaderFromResourceA(NULL
, "notexisting",
439 ok(hr
== D3DXERR_INVALIDDATA
, "D3DXPreprocessShaderFromResource NULL shader test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
441 trace("D3DXPreprocessShaderFromResource messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
442 ID3DXBuffer_Release(messages
);
444 if(shader
) ID3DXBuffer_Release(shader
);
447 if(SUCCEEDED(shader_vsh_res
)) {
448 DeleteFileA("shader.vsh");
449 DeleteFileA("incl.vsh");
450 DeleteFileA("shader3.vsh");
451 DeleteFileA("incl4.vsh");
452 DeleteFileA("include/incl3.vsh");
453 DeleteFileA("include/incl4.vsh");
454 RemoveDirectoryA("include");
460 assembleshader_test();
462 d3dxpreprocess_test();