diff --git a/dlls/d3dcompiler_43/compiler.c b/dlls/d3dcompiler_43/compiler.c index 02e74198e93..f60585a36d1 100644 --- a/dlls/d3dcompiler_43/compiler.c +++ b/dlls/d3dcompiler_43/compiler.c @@ -1003,13 +1003,51 @@ HRESULT WINAPI D3DDisassemble(const void *data, SIZE_T size, UINT flags, const c return E_NOTIMPL; } -HRESULT WINAPI D3DCompileFromFile(const WCHAR *filename, const D3D_SHADER_MACRO *defines, ID3DInclude *includes, +HRESULT WINAPI D3DCompileFromFile(const WCHAR *filename, const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint, const char *target, UINT flags1, UINT flags2, ID3DBlob **code, ID3DBlob **errors) { - FIXME("filename %s, defines %p, includes %p, entrypoint %s, target %s, flags1 %x, flags2 %x, code %p, errors %p\n", - debugstr_w(filename), defines, includes, debugstr_a(entrypoint), debugstr_a(target), flags1, flags2, code, errors); + char filename_a[MAX_PATH], *source = NULL; + DWORD source_size, read_size; + HANDLE file; + HRESULT hr; - return E_NOTIMPL; + TRACE("filename %s, defines %p, include %p, entrypoint %s, target %s, flags1 %#x, flags2 %#x, " + "code %p, errors %p.\n", debugstr_w(filename), defines, include, debugstr_a(entrypoint), + debugstr_a(target), flags1, flags2, code, errors); + + file = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (file == INVALID_HANDLE_VALUE) + return HRESULT_FROM_WIN32(GetLastError()); + + source_size = GetFileSize(file, NULL); + if (source_size == INVALID_FILE_SIZE) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + goto end; + } + + if (!(source = heap_alloc(source_size))) + { + hr = E_OUTOFMEMORY; + goto end; + } + + if (!ReadFile(file, source, source_size, &read_size, NULL) || read_size != source_size) + { + WARN("Failed to read file contents.\n"); + hr = E_FAIL; + goto end; + } + + WideCharToMultiByte(CP_ACP, 0, filename, -1, filename_a, sizeof(filename_a), NULL, NULL); + + hr = D3DCompile(source, source_size, filename_a, defines, include, entrypoint, target, + flags1, flags2, code, errors); + +end: + heap_free(source); + CloseHandle(file); + return hr; } HRESULT WINAPI D3DLoadModule(const void *data, SIZE_T size, ID3D11Module **module) diff --git a/dlls/d3dcompiler_43/tests/hlsl_d3d9.c b/dlls/d3dcompiler_43/tests/hlsl_d3d9.c index f6b389ccdf3..8443406402e 100644 --- a/dlls/d3dcompiler_43/tests/hlsl_d3d9.c +++ b/dlls/d3dcompiler_43/tests/hlsl_d3d9.c @@ -29,6 +29,9 @@ static pD3DCompile ppD3DCompile; static HRESULT (WINAPI *pD3DCompile2)(const void *data, SIZE_T data_size, const char *filename, const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint, const char *target, UINT sflags, UINT eflags, UINT secondary_flags, const void *secondary_data, SIZE_T secondary_data_size, ID3DBlob **shader, ID3DBlob **error_messages); +static HRESULT (WINAPI *pD3DCompileFromFile)(const WCHAR *filename, const D3D_SHADER_MACRO *defines, + ID3DInclude *include, const char *entrypoint, const char *target, UINT flags1, UINT flags2, + ID3DBlob **code, ID3DBlob **errors); static HRESULT (WINAPI *pD3DXGetShaderConstantTable)(const DWORD *byte_code, ID3DXConstantTable **constant_table); struct vec2 @@ -1331,6 +1334,7 @@ static BOOL load_d3dcompiler(void) #if D3D_COMPILER_VERSION == 47 if (!(module = LoadLibraryA("d3dcompiler_47.dll"))) return FALSE; pD3DCompile2 = (void*)GetProcAddress(module, "D3DCompile2"); + pD3DCompileFromFile = (void*)GetProcAddress(module, "D3DCompileFromFile"); #else if (!(module = LoadLibraryA("d3dcompiler_43.dll"))) return FALSE; #endif @@ -1490,6 +1494,42 @@ static void test_d3dcompile(void) blob = NULL; } + hr = pD3DCompileFromFile(L"nonexistent", NULL, NULL, "main", "vs_2_0", 0, 0, &blob, &errors); + ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Got hr %#x.\n", hr); + ok(!blob, "Got unexpected blob.\n"); + ok(!errors, "Got unexpected errors.\n"); + + hr = pD3DCompileFromFile(filename, NULL, NULL, "main", "ps_2_0", 0, 0, &blob, &errors); + ok(hr == E_FAIL, "Got hr %#x.\n", hr); + ok(!blob, "Got unexpected blob.\n"); + ok(!!errors, "Got unexpected errors.\n"); + trace("%s.\n", (char *)ID3D10Blob_GetBufferPointer(errors)); + ID3D10Blob_Release(errors); + errors = NULL; + + hr = pD3DCompileFromFile(filename, NULL, &include.ID3DInclude_iface, "main", "ps_2_0", 0, 0, &blob, &errors); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + todo_wine ok(!!blob, "Got unexpected blob.\n"); + ok(!errors, "Got unexpected errors.\n"); + if (blob) + { + ID3D10Blob_Release(blob); + blob = NULL; + } + + /* Windows always seems to resolve includes from the initial file location + * instead of using the immediate parent, as it would be the case for + * standard C preprocessor includes. */ + hr = pD3DCompileFromFile(filename, NULL, D3D_COMPILE_STANDARD_FILE_INCLUDE, "main", "ps_2_0", 0, 0, &blob, &errors); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + todo_wine ok(!!blob, "Got unexpected blob.\n"); + ok(!errors, "Got unexpected errors.\n"); + if (blob) + { + ID3D10Blob_Release(blob); + blob = NULL; + } + GetCurrentDirectoryW(MAX_PATH, directory); SetCurrentDirectoryW(temp_dir); @@ -1515,6 +1555,16 @@ static void test_d3dcompile(void) blob = NULL; } + hr = pD3DCompileFromFile(L"source.ps", NULL, D3D_COMPILE_STANDARD_FILE_INCLUDE, "main", "ps_2_0", 0, 0, &blob, &errors); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + todo_wine ok(!!blob, "Got unexpected blob.\n"); + ok(!errors, "Got unexpected errors.\n"); + if (blob) + { + ID3D10Blob_Release(blob); + blob = NULL; + } + SetCurrentDirectoryW(directory); cleanup: