DirectXShaderCompiler/include/dxc/Support/dxcapi.use.h

183 строки
5.7 KiB
C++

//////////////////////////////////////////////////////////////////////////////
// //
// dxcapi.use.h //
// Copyright (C) Microsoft Corporation. All rights reserved. //
// This file is distributed under the University of Illinois Open Source //
// License. See LICENSE.TXT for details. //
// //
// Provides support for DXC API users. //
// //
///////////////////////////////////////////////////////////////////////////////
#ifndef __DXCAPI_USE_H__
#define __DXCAPI_USE_H__
#include "dxc/dxcapi.h"
namespace dxc {
// Helper class to dynamically load the dxcompiler or a compatible libraries.
class DxcDllSupport {
protected:
HMODULE m_dll;
DxcCreateInstanceProc m_createFn;
DxcCreateInstance2Proc m_createFn2;
HRESULT InitializeInternal(LPCWSTR dllName, LPCSTR fnName) {
if (m_dll != nullptr) return S_OK;
#ifdef _WIN32
m_dll = LoadLibraryW(dllName);
#else
char nameStr[256];
std::wcstombs(nameStr, dllName, 256);
m_dll = ::dlopen(nameStr, RTLD_LAZY);
#endif
if (m_dll == nullptr) return HRESULT_FROM_WIN32(GetLastError());
#ifdef _WIN32
m_createFn = (DxcCreateInstanceProc)GetProcAddress(m_dll, fnName);
#else
m_createFn = (DxcCreateInstanceProc)::dlsym(m_dll, fnName);
#endif
if (m_createFn == nullptr) {
HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
#ifdef _WIN32
FreeLibrary(m_dll);
#else
::dlclose(m_dll);
#endif
m_dll = nullptr;
return hr;
}
// Only basic functions used to avoid requiring additional headers.
m_createFn2 = nullptr;
char fnName2[128];
size_t s = strlen(fnName);
if (s < sizeof(fnName2) - 2) {
memcpy(fnName2, fnName, s);
fnName2[s] = '2';
fnName2[s + 1] = '\0';
#ifdef _WIN32
m_createFn2 = (DxcCreateInstance2Proc)GetProcAddress(m_dll, fnName2);
#else
m_createFn2 = (DxcCreateInstance2Proc)::dlsym(m_dll, fnName2);
#endif
}
return S_OK;
}
public:
DxcDllSupport() : m_dll(nullptr), m_createFn(nullptr), m_createFn2(nullptr) {
}
DxcDllSupport(DxcDllSupport&& other) {
m_dll = other.m_dll; other.m_dll = nullptr;
m_createFn = other.m_createFn; other.m_createFn = nullptr;
m_createFn2 = other.m_createFn2; other.m_createFn2 = nullptr;
}
~DxcDllSupport() {
Cleanup();
}
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) {
return InitializeInternal(dll, entryPoint);
}
template <typename TInterface>
HRESULT CreateInstance(REFCLSID clsid, _Outptr_ TInterface** pResult) {
return CreateInstance(clsid, __uuidof(TInterface), (IUnknown**)pResult);
}
HRESULT CreateInstance(REFCLSID clsid, REFIID riid, _Outptr_ IUnknown **pResult) {
if (pResult == nullptr) return E_POINTER;
if (m_dll == nullptr) return E_FAIL;
HRESULT hr = m_createFn(clsid, riid, (LPVOID*)pResult);
return hr;
}
template <typename TInterface>
HRESULT CreateInstance2(IMalloc *pMalloc, REFCLSID clsid, _Outptr_ TInterface** pResult) {
return CreateInstance2(pMalloc, clsid, __uuidof(TInterface), (IUnknown**)pResult);
}
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_createFn2 == nullptr) return E_FAIL;
HRESULT hr = m_createFn2(pMalloc, clsid, riid, (LPVOID*)pResult);
return hr;
}
bool HasCreateWithMalloc() const {
return m_createFn2 != nullptr;
}
bool IsEnabled() const {
return m_dll != nullptr;
}
void Cleanup() {
if (m_dll != nullptr) {
m_createFn = nullptr;
m_createFn2 = nullptr;
#ifdef _WIN32
FreeLibrary(m_dll);
#else
::dlclose(m_dll);
#endif
m_dll = nullptr;
}
}
HMODULE Detach() {
HMODULE module = m_dll;
m_dll = nullptr;
return module;
}
};
inline DxcDefine GetDefine(_In_ LPCWSTR name, LPCWSTR value) {
DxcDefine result;
result.Name = name;
result.Value = value;
return result;
}
// Checks an HRESULT and formats an error message with the appended data.
void IFT_Data(HRESULT hr, _In_opt_ LPCWSTR data);
void EnsureEnabled(DxcDllSupport &dxcSupport);
void ReadFileIntoBlob(DxcDllSupport &dxcSupport, _In_ LPCWSTR pFileName,
_Outptr_ IDxcBlobEncoding **ppBlobEncoding);
void WriteBlobToConsole(_In_opt_ IDxcBlob *pBlob, DWORD streamType = STD_OUTPUT_HANDLE);
void WriteBlobToFile(_In_opt_ IDxcBlob *pBlob, _In_ LPCWSTR pFileName);
void WriteBlobToHandle(_In_opt_ IDxcBlob *pBlob, HANDLE hFile, _In_opt_ LPCWSTR pFileName);
void WriteUtf8ToConsole(_In_opt_count_(charCount) const char *pText,
int charCount, DWORD streamType = STD_OUTPUT_HANDLE);
void WriteUtf8ToConsoleSizeT(_In_opt_count_(charCount) const char *pText,
size_t charCount, DWORD streamType = STD_OUTPUT_HANDLE);
void WriteOperationErrorsToConsole(_In_ IDxcOperationResult *pResult,
bool outputWarnings);
void WriteOperationResultToConsole(_In_ IDxcOperationResult *pRewriteResult,
bool outputWarnings);
} // namespace dxc
#endif