Superseded patch 182804.
Signed-off-by: Jactry Zeng jzeng@codeweavers.com --- dlls/d3dcompiler_43/compiler.c | 36 +++++++++++- dlls/d3dcompiler_43/tests/hlsl_d3d9.c | 85 ++++++++++++++++++++++++++- 2 files changed, 117 insertions(+), 4 deletions(-)
diff --git a/dlls/d3dcompiler_43/compiler.c b/dlls/d3dcompiler_43/compiler.c index 9fc7c1d773..8f00dfb16c 100644 --- a/dlls/d3dcompiler_43/compiler.c +++ b/dlls/d3dcompiler_43/compiler.c @@ -949,10 +949,42 @@ HRESULT WINAPI D3DDisassemble(const void *data, SIZE_T size, UINT flags, const c HRESULT WINAPI D3DCompileFromFile(const WCHAR *filename, const D3D_SHADER_MACRO *defines, ID3DInclude *includes, 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", + HANDLE file, mapping = NULL; + char *source = NULL; + SIZE_T source_size; + HRESULT hr; + + TRACE("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);
- return E_NOTIMPL; + 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) + goto error; + + mapping = CreateFileMappingW(file, NULL, PAGE_READONLY, 0, 0, NULL); + if (!mapping) + goto error; + + source = MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0); + if (!source) + goto error; + + hr = D3DCompile(source, source_size, NULL, defines, includes, entrypoint, target, flags1, flags2, code, errors); + CloseHandle(mapping); + CloseHandle(file); + return hr; + +error: + hr = HRESULT_FROM_WIN32(GetLastError()); + if (!mapping) + CloseHandle(mapping); + 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 b96ab16679..cd93aa497d 100644 --- a/dlls/d3dcompiler_43/tests/hlsl_d3d9.c +++ b/dlls/d3dcompiler_43/tests/hlsl_d3d9.c @@ -26,6 +26,8 @@ static pD3DCompile ppD3DCompile;
static HRESULT (WINAPI *pD3DXGetShaderConstantTable)(const DWORD *byte_code, ID3DXConstantTable **constant_table); +static HRESULT (WINAPI *pD3DCompileFromFile)(const WCHAR *filename, const D3D_SHADER_MACRO *defines, ID3DInclude *includes, + const char *entrypoint, const char *target, UINT flags1, UINT flags2, ID3DBlob **code, ID3DBlob **errors);
struct vec2 { @@ -37,10 +39,40 @@ struct vec4 float x, y, z, w; };
+static BOOL create_file(WCHAR *filename, const char *code, DWORD code_size) +{ + static WCHAR temp_dir[MAX_PATH]; + DWORD written; + HANDLE file; + + if (!temp_dir[0]) + GetTempPathW(ARRAY_SIZE(temp_dir), temp_dir); + GetTempFileNameW(temp_dir, NULL, 0, filename); + file = CreateFileW(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); + if (file == INVALID_HANDLE_VALUE) + return FALSE; + + if (code) + { + WriteFile(file, code, code_size, &written, NULL); + if (written != code_size) + { + CloseHandle(file); + DeleteFileW(filename); + return FALSE; + } + } + CloseHandle(file); + return TRUE; +} + #define compile_shader(a, b) compile_shader_(__LINE__, a, b) static ID3D10Blob *compile_shader_(unsigned int line, const char *source, const char *target) { - ID3D10Blob *blob = NULL, *errors = NULL; + ID3D10Blob *blob = NULL, *errors = NULL, *file_blob = NULL, *file_errors = NULL; + WCHAR filename[MAX_PATH] = {0}; + DWORD *data, *file_data; + SIZE_T size, file_size; HRESULT hr;
hr = ppD3DCompile(source, strlen(source), NULL, NULL, NULL, "main", target, 0, 0, &blob, &errors); @@ -49,8 +81,38 @@ static ID3D10Blob *compile_shader_(unsigned int line, const char *source, const { if (winetest_debug > 1) trace_(__FILE__, line)("%s\n", (char *)ID3D10Blob_GetBufferPointer(errors)); - ID3D10Blob_Release(errors); } + + if (SUCCEEDED(hr)) + { + if (!pD3DCompileFromFile || !create_file(filename, source, strlen(source))) + skip("D3DCompileFromFile() isn't supported or file creation failed.\n"); + else + { + hr = pD3DCompileFromFile(filename, NULL, NULL, "main", target, 0, 0, &file_blob, &file_errors); + ok_(__FILE__, line)(hr == D3D_OK, "Failed to compile shader from file, hr %#x.\n", hr); + size = ID3D10Blob_GetBufferSize(blob); + file_size = ID3D10Blob_GetBufferSize(blob); + ok_(__FILE__, line)(hr == D3D_OK, "Got unexpected buffer size: %lu vs %lu.\n", size, file_size); + data = ID3D10Blob_GetBufferPointer(blob); + file_data = ID3D10Blob_GetBufferPointer(file_blob); + ok_(__FILE__, line)(!memcmp(data, file_data, size), "Got unexpected data.\n"); + ok_(__FILE__, line)(!!file_errors == !!errors, "Got unexpected errors.\n"); + if (file_errors) + { + if (winetest_debug > 1) + trace_(__FILE__, line)("%s\n", (char *)ID3D10Blob_GetBufferPointer(file_errors)); + ID3D10Blob_Release(file_errors); + } + + ID3D10Blob_Release(file_blob); + DeleteFileW(filename); + } + } + + if (errors) + ID3D10Blob_Release(errors); + return blob; }
@@ -1003,6 +1065,7 @@ static BOOL load_d3dcompiler(void)
#if D3D_COMPILER_VERSION == 47 if (!(module = LoadLibraryA("d3dcompiler_47.dll"))) return FALSE; + pD3DCompileFromFile = (void*)GetProcAddress(module, "D3DCompileFromFile"); #else if (!(module = LoadLibraryA("d3dcompiler_43.dll"))) return FALSE; #endif @@ -1011,6 +1074,23 @@ static BOOL load_d3dcompiler(void) return TRUE; }
+static void test_compile(void) +{ + ID3D10Blob *blob = NULL, *errors = NULL; + HRESULT hr; + + if (!pD3DCompileFromFile) + { + skip("D3DCompileFromFile() isn't supported.\n"); + return; + } + + 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"); +} + START_TEST(hlsl_d3d9) { HMODULE mod; @@ -1038,4 +1118,5 @@ START_TEST(hlsl_d3d9) test_array_dimensions(); test_constant_table(); test_fail(); + test_compile(); }