d3dx9: D3DXPreprocessShader implementation with tests.

This commit is contained in:
Matteo Bruni 2010-09-09 18:41:39 +02:00 committed by Alexandre Julliard
parent 87f00d34fd
commit 8d7a0d5027
4 changed files with 286 additions and 6 deletions

View File

@ -236,11 +236,11 @@
@ stdcall D3DXPlaneNormalize(ptr ptr) @ stdcall D3DXPlaneNormalize(ptr ptr)
@ stdcall D3DXPlaneTransform(ptr ptr ptr) @ stdcall D3DXPlaneTransform(ptr ptr ptr)
@ stdcall D3DXPlaneTransformArray(ptr long ptr long ptr long) @ stdcall D3DXPlaneTransformArray(ptr long ptr long ptr long)
@ stub D3DXPreprocessShader @ stdcall D3DXPreprocessShader(ptr long ptr ptr ptr ptr)
@ stub D3DXPreprocessShaderFromFileA @ stdcall D3DXPreprocessShaderFromFileA(str ptr ptr ptr ptr)
@ stub D3DXPreprocessShaderFromFileW @ stdcall D3DXPreprocessShaderFromFileW(wstr ptr ptr ptr ptr)
@ stub D3DXPreprocessShaderFromResourceA @ stdcall D3DXPreprocessShaderFromResourceA(long str ptr ptr ptr ptr)
@ stub D3DXPreprocessShaderFromResourceW @ stdcall D3DXPreprocessShaderFromResourceW(long wstr ptr ptr ptr ptr)
@ stdcall D3DXQuaternionBaryCentric(ptr ptr ptr ptr float float) @ stdcall D3DXQuaternionBaryCentric(ptr ptr ptr ptr float float)
@ stdcall D3DXQuaternionExp(ptr ptr) @ stdcall D3DXQuaternionExp(ptr ptr)
@ stdcall D3DXQuaternionInverse(ptr ptr) @ stdcall D3DXQuaternionInverse(ptr ptr)

View File

@ -446,7 +446,7 @@ HRESULT WINAPI D3DXCompileShaderFromFileW(LPCWSTR filename,
} }
WideCharToMultiByte(CP_ACP, 0, filename, -1, filename_a, filename_len, NULL, NULL); WideCharToMultiByte(CP_ACP, 0, filename, -1, filename_a, filename_len, NULL, NULL);
hr = D3DCompile(buffer, len, filename_a, (D3D_SHADER_MACRO *)defines, hr = D3DCompile(buffer, len, filename_a, (const D3D_SHADER_MACRO *)defines,
(ID3DInclude *)include, entrypoint, profile, flags, 0, (ID3DInclude *)include, entrypoint, profile, flags, 0,
(ID3DBlob **)shader, (ID3DBlob **)error_messages); (ID3DBlob **)shader, (ID3DBlob **)error_messages);
@ -505,6 +505,121 @@ HRESULT WINAPI D3DXCompileShaderFromResourceW(HMODULE module,
flags, shader, error_messages, constant_table); flags, shader, error_messages, constant_table);
} }
HRESULT WINAPI D3DXPreprocessShader(LPCSTR data,
UINT data_len,
CONST D3DXMACRO* defines,
LPD3DXINCLUDE include,
LPD3DXBUFFER* shader,
LPD3DXBUFFER* error_messages)
{
TRACE("Forward to D3DPreprocess\n");
return D3DPreprocess(data, data_len, NULL,
(const D3D_SHADER_MACRO *)defines, (ID3DInclude *)include,
(ID3DBlob **)shader, (ID3DBlob **)error_messages);
}
HRESULT WINAPI D3DXPreprocessShaderFromFileA(LPCSTR filename,
CONST D3DXMACRO* defines,
LPD3DXINCLUDE include,
LPD3DXBUFFER* shader,
LPD3DXBUFFER* error_messages)
{
WCHAR *filename_w = NULL;
DWORD len;
HRESULT ret;
if (!filename) return D3DXERR_INVALIDDATA;
len = MultiByteToWideChar(CP_ACP, 0, filename, -1, NULL, 0);
filename_w = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
if (!filename_w) return E_OUTOFMEMORY;
MultiByteToWideChar(CP_ACP, 0, filename, -1, filename_w, len);
ret = D3DXPreprocessShaderFromFileW(filename_w, defines, include, shader, error_messages);
HeapFree(GetProcessHeap(), 0, filename_w);
return ret;
}
HRESULT WINAPI D3DXPreprocessShaderFromFileW(LPCWSTR filename,
CONST D3DXMACRO* defines,
LPD3DXINCLUDE include,
LPD3DXBUFFER* shader,
LPD3DXBUFFER* error_messages)
{
void *buffer;
DWORD len, filename_len;
HRESULT hr;
struct D3DXIncludeImpl includefromfile;
char *filename_a;
if (FAILED(map_view_of_file(filename, &buffer, &len)))
return D3DXERR_INVALIDDATA;
if (!include)
{
includefromfile.lpVtbl = &D3DXInclude_Vtbl;
include = (LPD3DXINCLUDE)&includefromfile;
}
filename_len = WideCharToMultiByte(CP_ACP, 0, filename, -1, NULL, 0, NULL, NULL);
filename_a = HeapAlloc(GetProcessHeap(), 0, filename_len * sizeof(char));
if (!filename_a)
{
UnmapViewOfFile(buffer);
return E_OUTOFMEMORY;
}
WideCharToMultiByte(CP_ACP, 0, filename, -1, filename_a, filename_len, NULL, NULL);
hr = D3DPreprocess(buffer, len, NULL,
(const D3D_SHADER_MACRO *)defines,
(ID3DInclude *) include,
(ID3DBlob **)shader, (ID3DBlob **)error_messages);
HeapFree(GetProcessHeap(), 0, filename_a);
UnmapViewOfFile(buffer);
return hr;
}
HRESULT WINAPI D3DXPreprocessShaderFromResourceA(HMODULE module,
LPCSTR resource,
CONST D3DXMACRO* defines,
LPD3DXINCLUDE include,
LPD3DXBUFFER* shader,
LPD3DXBUFFER* error_messages)
{
HRSRC res;
const char *buffer;
DWORD len;
if (!(res = FindResourceA(module, resource, (LPCSTR)RT_RCDATA)))
return D3DXERR_INVALIDDATA;
if (FAILED(load_resource_into_memory(module, res, (LPVOID *)&buffer, &len)))
return D3DXERR_INVALIDDATA;
return D3DXPreprocessShader(buffer, len, defines, include,
shader, error_messages);
}
HRESULT WINAPI D3DXPreprocessShaderFromResourceW(HMODULE module,
LPCWSTR resource,
CONST D3DXMACRO* defines,
LPD3DXINCLUDE include,
LPD3DXBUFFER* shader,
LPD3DXBUFFER* error_messages)
{
HRSRC res;
const char *buffer;
DWORD len;
if (!(res = FindResourceW(module, resource, (const WCHAR *)RT_RCDATA)))
return D3DXERR_INVALIDDATA;
if (FAILED(load_resource_into_memory(module, res, (void **)&buffer, &len)))
return D3DXERR_INVALIDDATA;
return D3DXPreprocessShader(buffer, len, defines, include,
shader, error_messages);
}
static const struct ID3DXConstantTableVtbl ID3DXConstantTable_Vtbl; static const struct ID3DXConstantTableVtbl ID3DXConstantTable_Vtbl;
typedef struct ID3DXConstantTableImpl { typedef struct ID3DXConstantTableImpl {

View File

@ -325,7 +325,139 @@ static void assembleshader_test(void) {
} }
} }
static void d3dxpreprocess_test(void) {
const char testincl[] = {
"#define REGISTER r0\n"
"vs.1.1\n"
};
const char testshader[] = {
"#include \"incl.vsh\"\n"
"mov REGISTER, v0\n"
};
const char testshader3[] = {
"#include \"include/incl3.vsh\"\n"
"mov REGISTER, v0\n"
};
const char testincl3[] = {
"#include \"incl4.vsh\"\n"
};
const char testincl4_ok[] = {
"#define REGISTER r0\n"
"vs.1.1\n"
};
const char testincl4_wrong[] = {
"#error \"wrong include\"\n"
};
HRESULT hr;
LPD3DXBUFFER shader, messages;
HRESULT shader_vsh_res;
struct D3DXIncludeImpl include = {&D3DXInclude_Vtbl};
shader_vsh_res = create_file("shader.vsh", testshader, sizeof(testshader) - 1);
if(SUCCEEDED(shader_vsh_res)) {
create_file("incl.vsh", testincl, sizeof(testincl) - 1);
create_file("shader3.vsh", testshader3, sizeof(testshader3) - 1);
create_file("incl4.vsh", testincl4_wrong, sizeof(testincl4_wrong) - 1);
if(CreateDirectoryA("include", NULL)) {
create_file("include/incl3.vsh", testincl3, sizeof(testincl3) - 1);
create_file("include/incl4.vsh", testincl4_ok, sizeof(testincl4_ok) - 1);
/* path search #include test */
shader = NULL;
messages = NULL;
hr = D3DXPreprocessShaderFromFileA("shader3.vsh", NULL, NULL,
&shader, &messages);
ok(hr == D3D_OK, "D3DXPreprocessShaderFromFile path search test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF);
if(messages) {
trace("D3DXPreprocessShaderFromFile path search messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
ID3DXBuffer_Release(messages);
}
if(shader) ID3DXBuffer_Release(shader);
} else skip("Couldn't create \"include\" directory\n");
/* D3DXPreprocessShaderFromFile + #include test */
shader = NULL;
messages = NULL;
hr = D3DXPreprocessShaderFromFileA("shader.vsh",
NULL, NULL,
&shader, &messages);
ok(hr == D3D_OK, "D3DXPreprocessShaderFromFile test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF);
if(messages) {
trace("D3DXPreprocessShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
ID3DXBuffer_Release(messages);
}
if(shader) ID3DXBuffer_Release(shader);
/* D3DXPreprocessShaderFromFile + pInclude test */
shader = NULL;
messages = NULL;
hr = D3DXPreprocessShaderFromFileA("shader.vsh",
NULL, (LPD3DXINCLUDE)&include,
&shader, &messages);
ok(hr == D3D_OK, "D3DXPreprocessShaderFromFile + pInclude test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF);
if(messages) {
trace("D3DXPreprocessShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
ID3DXBuffer_Release(messages);
}
if(shader) ID3DXBuffer_Release(shader);
} else skip("Couldn't create \"shader.vsh\"\n");
/* NULL shader tests */
shader = NULL;
messages = NULL;
hr = D3DXPreprocessShaderFromFileA("nonexistent.vsh",
NULL, NULL,
&shader, &messages);
ok(hr == D3DXERR_INVALIDDATA || hr == E_FAIL, /* I get this on WinXP */
"D3DXPreprocessShaderFromFile nonexistent file test failed with error 0x%x - %d\n",
hr, hr & 0x0000FFFF);
if(messages) {
trace("D3DXPreprocessShaderFromFile messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
ID3DXBuffer_Release(messages);
}
if(shader) ID3DXBuffer_Release(shader);
/* D3DXPreprocessShaderFromResource test */
shader = NULL;
messages = NULL;
hr = D3DXPreprocessShaderFromResourceA(NULL, MAKEINTRESOURCEA(IDB_ASMSHADER),
NULL, NULL,
&shader, &messages);
ok(hr == D3D_OK, "D3DXPreprocessShaderFromResource test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF);
if(messages) {
trace("D3DXPreprocessShaderFromResource messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
ID3DXBuffer_Release(messages);
}
if(shader) ID3DXBuffer_Release(shader);
/* D3DXPreprocessShaderFromResource with missing shader resource test */
shader = NULL;
messages = NULL;
hr = D3DXPreprocessShaderFromResourceA(NULL, "notexisting",
NULL, NULL,
&shader, &messages);
ok(hr == D3DXERR_INVALIDDATA, "D3DXPreprocessShaderFromResource NULL shader test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF);
if(messages) {
trace("D3DXPreprocessShaderFromResource messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
ID3DXBuffer_Release(messages);
}
if(shader) ID3DXBuffer_Release(shader);
/* cleanup */
if(SUCCEEDED(shader_vsh_res)) {
DeleteFileA("shader.vsh");
DeleteFileA("incl.vsh");
DeleteFileA("shader3.vsh");
DeleteFileA("incl4.vsh");
DeleteFileA("include/incl3.vsh");
DeleteFileA("include/incl4.vsh");
RemoveDirectoryA("include");
}
}
START_TEST(asm) START_TEST(asm)
{ {
assembleshader_test(); assembleshader_test();
d3dxpreprocess_test();
} }

View File

@ -349,6 +349,39 @@ HRESULT WINAPI D3DXCompileShaderFromResourceW(HMODULE module,
LPD3DXCONSTANTTABLE* constant_table); LPD3DXCONSTANTTABLE* constant_table);
#define D3DXCompileShaderFromResource WINELIB_NAME_AW(D3DXCompileShaderFromResource) #define D3DXCompileShaderFromResource WINELIB_NAME_AW(D3DXCompileShaderFromResource)
HRESULT WINAPI D3DXPreprocessShader(LPCSTR data,
UINT data_len,
CONST D3DXMACRO* defines,
LPD3DXINCLUDE include,
LPD3DXBUFFER* shader,
LPD3DXBUFFER* error_messages);
HRESULT WINAPI D3DXPreprocessShaderFromFileA(LPCSTR filename,
CONST D3DXMACRO* defines,
LPD3DXINCLUDE include,
LPD3DXBUFFER* shader,
LPD3DXBUFFER* error_messages);
HRESULT WINAPI D3DXPreprocessShaderFromFileW(LPCWSTR filename,
CONST D3DXMACRO* defines,
LPD3DXINCLUDE include,
LPD3DXBUFFER* shader,
LPD3DXBUFFER* error_messages);
#define D3DXPreprocessShaderFromFile WINELIB_NAME_AW(D3DXPreprocessShaderFromFile)
HRESULT WINAPI D3DXPreprocessShaderFromResourceA(HMODULE module,
LPCSTR resource,
CONST D3DXMACRO* defines,
LPD3DXINCLUDE include,
LPD3DXBUFFER* shader,
LPD3DXBUFFER* error_messages);
HRESULT WINAPI D3DXPreprocessShaderFromResourceW(HMODULE module,
LPCWSTR resource,
CONST D3DXMACRO* defines,
LPD3DXINCLUDE include,
LPD3DXBUFFER* shader,
LPD3DXBUFFER* error_messages);
#define D3DXPreprocessShaderFromResource WINELIB_NAME_AW(D3DXPreprocessShaderFromResource)
HRESULT WINAPI D3DXGetShaderConstantTableEx(CONST DWORD* byte_code, HRESULT WINAPI D3DXGetShaderConstantTableEx(CONST DWORD* byte_code,
DWORD flags, DWORD flags,
LPD3DXCONSTANTTABLE* constant_table); LPD3DXCONSTANTTABLE* constant_table);