Signed-off-by: Jactry Zeng <jzeng(a)codeweavers.com>
---
dlls/d3dcompiler_43/compiler.c | 41 ++++++++++++-
dlls/d3dcompiler_43/tests/hlsl_d3d9.c | 85 ++++++++++++++++++++++++++-
2 files changed, 122 insertions(+), 4 deletions(-)
diff --git a/dlls/d3dcompiler_43/compiler.c b/dlls/d3dcompiler_43/compiler.c
index 9fc7c1d773..06e8fb2534 100644
--- a/dlls/d3dcompiler_43/compiler.c
+++ b/dlls/d3dcompiler_43/compiler.c
@@ -949,10 +949,47 @@ 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",
+ char *source = NULL;
+ SIZE_T source_size;
+ DWORD read_size;
+ HANDLE file;
+ 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)
+ {
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ goto end;
+ }
+
+ if (!(source = heap_alloc_zero(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;
+ }
+
+ hr = D3DCompile(source, strlen(source), NULL, defines, includes, entrypoint, target, flags1, flags2, code, errors);
+
+end:
+ CloseHandle(file);
+ if (source)
+ heap_free(source);
+
+ 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();
}
--
2.26.0