[PATCH] d3dcompiler: Implement D3DReadFileToBlob().

Matteo Bruni mbruni at codeweavers.com
Tue May 7 14:43:10 CDT 2019


From: Jactry Zeng <jzeng at codeweavers.com>

Signed-off-by: Jactry Zeng <jzeng at codeweavers.com>
Signed-off-by: Matteo Bruni <mbruni at codeweavers.com>
---
 dlls/d3dcompiler_43/blob.c                |  50 +++++++-
 dlls/d3dcompiler_43/d3dcompiler_private.h |   1 +
 dlls/d3dcompiler_43/tests/blob.c          | 132 +++++++++++++++++++++-
 3 files changed, 175 insertions(+), 8 deletions(-)

diff --git a/dlls/d3dcompiler_43/blob.c b/dlls/d3dcompiler_43/blob.c
index f22dc7183d5..6c925af8a44 100644
--- a/dlls/d3dcompiler_43/blob.c
+++ b/dlls/d3dcompiler_43/blob.c
@@ -466,9 +466,55 @@ HRESULT WINAPI D3DStripShader(const void *data, SIZE_T data_size, UINT flags, ID
 
 HRESULT WINAPI D3DReadFileToBlob(const WCHAR *filename, ID3DBlob **contents)
 {
-    FIXME("filename %s, contents %p\n", debugstr_w(filename), contents);
+    struct d3dcompiler_blob *object;
+    SIZE_T data_size;
+    DWORD read_size;
+    HANDLE file;
+    HRESULT hr;
 
-    return E_NOTIMPL;
+    TRACE("filename %s, contents %p.\n", debugstr_w(filename), contents);
+
+    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());
+
+    data_size = GetFileSize(file, NULL);
+    if (data_size == INVALID_FILE_SIZE)
+    {
+        CloseHandle(file);
+        return HRESULT_FROM_WIN32(GetLastError());
+    }
+
+    if (!(object = heap_alloc_zero(sizeof(*object))))
+    {
+        CloseHandle(file);
+        return E_OUTOFMEMORY;
+    }
+
+    if (FAILED(hr = d3dcompiler_blob_init(object, data_size)))
+    {
+        WARN("Failed to initialize blob, hr %#x.\n", hr);
+        CloseHandle(file);
+        heap_free(object);
+        return hr;
+    }
+
+    if (!ReadFile(file, object->data, data_size, &read_size, NULL) || (read_size != data_size))
+    {
+        WARN("Failed to read file contents.\n");
+        CloseHandle(file);
+        heap_free(object->data);
+        heap_free(object);
+        return E_FAIL;
+    }
+    CloseHandle(file);
+    object->size = read_size;
+
+    *contents = &object->ID3DBlob_iface;
+
+    TRACE("Returning ID3DBlob %p.\n", *contents);
+
+    return S_OK;
 }
 
 HRESULT WINAPI D3DWriteBlobToFile(ID3DBlob* blob, const WCHAR *filename, BOOL overwrite)
diff --git a/dlls/d3dcompiler_43/d3dcompiler_private.h b/dlls/d3dcompiler_43/d3dcompiler_private.h
index 68ff9623287..dabe0dacc30 100644
--- a/dlls/d3dcompiler_43/d3dcompiler_private.h
+++ b/dlls/d3dcompiler_43/d3dcompiler_private.h
@@ -25,6 +25,7 @@
 #include "wine/debug.h"
 #include "wine/list.h"
 #include "wine/rbtree.h"
+#include "wine/heap.h"
 
 #define COBJMACROS
 #include "windef.h"
diff --git a/dlls/d3dcompiler_43/tests/blob.c b/dlls/d3dcompiler_43/tests/blob.c
index 443ed2754c1..78b210d8dc7 100644
--- a/dlls/d3dcompiler_43/tests/blob.c
+++ b/dlls/d3dcompiler_43/tests/blob.c
@@ -35,6 +35,7 @@
 
 static HRESULT (WINAPI *pD3DCreateBlob)(SIZE_T, ID3DBlob **);
 static HRESULT (WINAPI *pD3DGetBlobPart)(const void *, SIZE_T, D3D_BLOB_PART, UINT, ID3DBlob **);
+static HRESULT (WINAPI *pD3DReadFileToBlob)(const WCHAR *, ID3DBlob **);
 static HRESULT (WINAPI *pD3DStripShader)(const void *, SIZE_T, UINT, ID3DBlob **);
 
 #define MAKE_TAG(ch0, ch1, ch2, ch3) \
@@ -740,7 +741,7 @@ static void test_get_blob_part2(void)
     ok(!refcount, "ID3DBlob has %u references left\n", refcount);
 }
 
-static BOOL load_d3dcompiler(void)
+static BOOL load_d3dcompiler_43(void)
 {
     HMODULE module;
 
@@ -752,15 +753,134 @@ static BOOL load_d3dcompiler(void)
     return TRUE;
 }
 
+static BOOL load_d3dcompiler_47(void)
+{
+    HMODULE module;
+
+    if (!(module = LoadLibraryA("d3dcompiler_47.dll")))
+        return FALSE;
+
+    pD3DReadFileToBlob = (void *)GetProcAddress(module, "D3DReadFileToBlob");
+    return TRUE;
+}
+
+static BOOL create_file(WCHAR *filename, const DWORD *data, DWORD data_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 (data)
+    {
+        WriteFile(file, data, data_size, &written, NULL);
+        if (written != data_size)
+        {
+            CloseHandle(file);
+            DeleteFileW(filename);
+            return FALSE;
+        }
+    }
+    CloseHandle(file);
+    return TRUE;
+}
+
+/* test_cso_data - fxc.exe file.hlsl /Fo file.cso */
+static const DWORD test_cso_data[] =
+{
+#if 0
+    struct PSInput
+    {
+        float4 value : SV_POSITION;
+    };
+
+    PSInput main(float4 position : POSITION)
+    {
+        PSInput result;
+        result.value = position;
+        return result;
+    }
+#endif
+    0xfffe0200, 0x0014fffe, 0x42415443, 0x0000001c, 0x00000023, 0xfffe0200, 0x00000000, 0x00000000,
+    0x00000100, 0x0000001c, 0x325f7376, 0x4d00305f, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820,
+    0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x30312072, 0xab00312e, 0x0200001f, 0x80000000,
+    0x900f0000, 0x02000001, 0xc00f0000, 0x90e40000, 0x0000ffff
+};
+
+static void test_D3DReadFileToBlob(void)
+{
+    WCHAR filename[MAX_PATH];
+    ID3DBlob *blob = NULL;
+    SIZE_T data_size;
+    DWORD *data;
+    HRESULT hr;
+
+    hr = pD3DReadFileToBlob(filename, NULL);
+    ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Got unexpected hr %#x.\n", hr);
+
+    hr = pD3DReadFileToBlob(filename, &blob);
+    ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Got unexpected hr %#x.\n", hr);
+
+    if (0)
+    {
+        /* Crashes on Windows. */
+        create_file(filename, test_cso_data, ARRAY_SIZE(test_cso_data));
+        pD3DReadFileToBlob(filename, NULL);
+        DeleteFileW(filename);
+    }
+
+    if (!create_file(filename, NULL, 0))
+    {
+        win_skip("File creation failed.\n");
+        return;
+    }
+    hr = pD3DReadFileToBlob(filename, &blob);
+    ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+    data_size = ID3D10Blob_GetBufferSize(blob);
+    ok(!data_size, "Got unexpected data size.\n");
+    DeleteFileW(filename);
+    ID3D10Blob_Release(blob);
+
+    if (!create_file(filename, test_cso_data, ARRAY_SIZE(test_cso_data)))
+    {
+        win_skip("File creation failed.\n");
+        return;
+    }
+    hr = pD3DReadFileToBlob(filename, &blob);
+    ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+    data_size = ID3D10Blob_GetBufferSize(blob);
+    ok(data_size == ARRAY_SIZE(test_cso_data), "Got unexpected data size.\n");
+    data = ID3D10Blob_GetBufferPointer(blob);
+    ok(!memcmp(data, test_cso_data, ARRAY_SIZE(test_cso_data)), "Got unexpected data.\n");
+    DeleteFileW(filename);
+    ID3D10Blob_Release(blob);
+}
+
 START_TEST(blob)
 {
-    if (!load_d3dcompiler())
+    if (load_d3dcompiler_43())
+    {
+        test_create_blob();
+        test_get_blob_part();
+        test_get_blob_part2();
+    }
+    else
     {
         win_skip("Could not load d3dcompiler_43.dll\n");
-        return;
     }
 
-    test_create_blob();
-    test_get_blob_part();
-    test_get_blob_part2();
+    if (load_d3dcompiler_47())
+    {
+        test_D3DReadFileToBlob();
+    }
+    else
+    {
+        win_skip("Could not load d3dcompiler_47.dll.\n");
+    }
 }
-- 
2.21.0




More information about the wine-devel mailing list