[linux-port] Use cross-platform dynamic lib load (#1380)
LLVM includes a DynamicLibrary class that works on multiple platforms Rather than ifdefing between dlopen for non-Windows and LoadLibraryW on Windows, using this class allows us to abstract platform differences while using the same code. Changed DxilLibInitialize to attempt to initialize dxil.dll so the smart mutex inside the dynamic library object uses the same IMalloc as the other ManagedStatic objects so they can all be freed in order.
This commit is contained in:
Родитель
4aa0ac6c50
Коммит
3670c1372d
|
@ -13,27 +13,27 @@
|
|||
#define __DXCAPI_USE_H__
|
||||
|
||||
#include "dxc/dxcapi.h"
|
||||
#include "llvm/Support/DynamicLibrary.h"
|
||||
|
||||
namespace dxc {
|
||||
|
||||
// Helper class to dynamically load the dxcompiler or a compatible libraries.
|
||||
class DxcDllSupport {
|
||||
protected:
|
||||
HMODULE m_dll;
|
||||
using DynamicLibrary = llvm::sys::DynamicLibrary;
|
||||
DynamicLibrary m_dll;
|
||||
DxcCreateInstanceProc m_createFn;
|
||||
DxcCreateInstance2Proc m_createFn2;
|
||||
|
||||
HRESULT InitializeInternal(LPCWSTR dllName, LPCSTR fnName) {
|
||||
if (m_dll != nullptr) return S_OK;
|
||||
m_dll = LoadLibraryW(dllName);
|
||||
|
||||
if (m_dll == nullptr) return HRESULT_FROM_WIN32(GetLastError());
|
||||
m_createFn = (DxcCreateInstanceProc)GetProcAddress(m_dll, fnName);
|
||||
if (m_dll.isValid()) return S_OK;
|
||||
m_dll = DynamicLibrary::getPermanentLibrary(CW2A(dllName));
|
||||
if (!m_dll.isValid()) return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
|
||||
m_createFn = (DxcCreateInstanceProc)m_dll.getAddressOfSymbol(fnName);
|
||||
|
||||
if (m_createFn == nullptr) {
|
||||
HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
FreeLibrary(m_dll);
|
||||
m_dll = nullptr;
|
||||
m_dll = DynamicLibrary();
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
@ -45,18 +45,18 @@ protected:
|
|||
memcpy(fnName2, fnName, s);
|
||||
fnName2[s] = '2';
|
||||
fnName2[s + 1] = '\0';
|
||||
m_createFn2 = (DxcCreateInstance2Proc)GetProcAddress(m_dll, fnName2);
|
||||
m_createFn2 = (DxcCreateInstance2Proc)m_dll.getAddressOfSymbol(fnName2);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
public:
|
||||
DxcDllSupport() : m_dll(nullptr), m_createFn(nullptr), m_createFn2(nullptr) {
|
||||
DxcDllSupport() : m_dll(), m_createFn(nullptr), m_createFn2(nullptr) {
|
||||
}
|
||||
|
||||
DxcDllSupport(DxcDllSupport&& other) {
|
||||
m_dll = other.m_dll; other.m_dll = nullptr;
|
||||
m_dll = other.m_dll; other.m_dll = DynamicLibrary();
|
||||
m_createFn = other.m_createFn; other.m_createFn = nullptr;
|
||||
m_createFn2 = other.m_createFn2; other.m_createFn2 = nullptr;
|
||||
}
|
||||
|
@ -66,7 +66,13 @@ public:
|
|||
}
|
||||
|
||||
HRESULT Initialize() {
|
||||
#ifdef _WIN32
|
||||
return InitializeInternal(L"dxcompiler.dll", "DxcCreateInstance");
|
||||
#elif __APPLE__
|
||||
return InitializeInternal(L"libdxcompiler.dylib", "DxcCreateInstance");
|
||||
#else
|
||||
return InitializeInternal(L"libdxcompiler.so", "DxcCreateInstance");
|
||||
#endif
|
||||
}
|
||||
|
||||
HRESULT InitializeForDll(_In_z_ const wchar_t* dll, _In_z_ const char* entryPoint) {
|
||||
|
@ -80,7 +86,7 @@ public:
|
|||
|
||||
HRESULT CreateInstance(REFCLSID clsid, REFIID riid, _Outptr_ IUnknown **pResult) {
|
||||
if (pResult == nullptr) return E_POINTER;
|
||||
if (m_dll == nullptr) return E_FAIL;
|
||||
if (!m_dll.isValid()) return E_FAIL;
|
||||
HRESULT hr = m_createFn(clsid, riid, (LPVOID*)pResult);
|
||||
return hr;
|
||||
}
|
||||
|
@ -92,7 +98,7 @@ public:
|
|||
|
||||
HRESULT CreateInstance2(IMalloc *pMalloc, REFCLSID clsid, REFIID riid, _Outptr_ IUnknown **pResult) {
|
||||
if (pResult == nullptr) return E_POINTER;
|
||||
if (m_dll == nullptr) return E_FAIL;
|
||||
if (!m_dll.isValid()) return E_FAIL;
|
||||
if (m_createFn2 == nullptr) return E_FAIL;
|
||||
HRESULT hr = m_createFn2(pMalloc, clsid, riid, (LPVOID*)pResult);
|
||||
return hr;
|
||||
|
@ -103,21 +109,20 @@ public:
|
|||
}
|
||||
|
||||
bool IsEnabled() const {
|
||||
return m_dll != nullptr;
|
||||
return m_dll.isValid();
|
||||
}
|
||||
|
||||
void Cleanup() {
|
||||
if (m_dll != nullptr) {
|
||||
if (m_dll.isValid()) {
|
||||
m_createFn = nullptr;
|
||||
m_createFn2 = nullptr;
|
||||
FreeLibrary(m_dll);
|
||||
m_dll = nullptr;
|
||||
m_dll = DynamicLibrary();
|
||||
}
|
||||
}
|
||||
|
||||
HMODULE Detach() {
|
||||
HMODULE module = m_dll;
|
||||
m_dll = nullptr;
|
||||
DynamicLibrary Detach() {
|
||||
DynamicLibrary module = m_dll;
|
||||
m_dll = DynamicLibrary();
|
||||
return module;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -28,7 +28,7 @@ if( NOT MSVC )
|
|||
endif( NOT MSVC )
|
||||
|
||||
# HLSL Change - add ignored sources
|
||||
set(HLSL_IGNORE_SOURCES DynamicLibrary.cpp PluginLoader.cpp)
|
||||
set(HLSL_IGNORE_SOURCES PluginLoader.cpp)
|
||||
|
||||
add_llvm_library(LLVMSupport
|
||||
APFloat.cpp
|
||||
|
@ -52,6 +52,7 @@ add_llvm_library(LLVMSupport
|
|||
DeltaAlgorithm.cpp
|
||||
DAGDeltaAlgorithm.cpp
|
||||
Dwarf.cpp
|
||||
DynamicLibrary.cpp
|
||||
ErrorHandling.cpp
|
||||
FileUtilities.cpp
|
||||
FileOutputBuffer.cpp
|
||||
|
|
|
@ -25,6 +25,11 @@ static llvm::sys::Mutex *cs = nullptr;
|
|||
// This function is to prevent multiple attempts to load dxil.dll
|
||||
HRESULT DxilLibInitialize() {
|
||||
cs = new llvm::sys::Mutex;
|
||||
#if LLVM_ON_WIN32
|
||||
cs->lock();
|
||||
g_DllLibResult = g_DllSupport.InitializeForDll(L"dxil.dll", "DxcCreateInstance");
|
||||
cs->unlock();
|
||||
#endif
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче