loader: Dynamically load DXGI

Avoids recursively having DXGI and the loader call eachother back and forth when DXVK is in use.
Fixes #253
diff --git a/loader/CMakeLists.txt b/loader/CMakeLists.txt
index 5013439..f357100 100644
--- a/loader/CMakeLists.txt
+++ b/loader/CMakeLists.txt
@@ -174,7 +174,7 @@
 endif()
 
 if(WIN32)
-    add_library(loader-norm OBJECT ${NORMAL_LOADER_SRCS} dirent_on_windows.c)
+    add_library(loader-norm OBJECT ${NORMAL_LOADER_SRCS} dirent_on_windows.c dxgi_loader.c)
     target_compile_options(loader-norm PUBLIC "$<$<CONFIG:DEBUG>:${LOCAL_C_FLAGS_DBG}>")
     target_compile_options(loader-norm PUBLIC ${MSVC_LOADER_COMPILE_OPTIONS})
     target_include_directories(loader-norm PRIVATE "$<TARGET_PROPERTY:Vulkan::Headers,INTERFACE_INCLUDE_DIRECTORIES>")
@@ -213,10 +213,10 @@
     endif()
 
     if(ENABLE_WIN10_ONECORE)
-        target_link_libraries(vulkan OneCoreUAP.lib LIBCMT.LIB LIBCMTD.LIB LIBVCRUNTIME.LIB LIBUCRT.LIB Dxgi)
+        target_link_libraries(vulkan OneCoreUAP.lib LIBCMT.LIB LIBCMTD.LIB LIBVCRUNTIME.LIB LIBUCRT.LIB)
         set_target_properties(vulkan PROPERTIES LINK_FLAGS "/NODEFAULTLIB")
     else()
-        target_link_libraries(vulkan Cfgmgr32 Dxgi)
+        target_link_libraries(vulkan Cfgmgr32)
     endif()
 
     add_dependencies(vulkan loader_asm_gen_files)
diff --git a/loader/dxgi_loader.c b/loader/dxgi_loader.c
new file mode 100644
index 0000000..c2a3fa5
--- /dev/null
+++ b/loader/dxgi_loader.c
@@ -0,0 +1,23 @@
+#include "dxgi_loader.h"
+
+#include <strsafe.h>
+
+static HMODULE load_dxgi_module() {
+    TCHAR systemPath[MAX_PATH] = "";
+    GetSystemDirectory(systemPath, MAX_PATH);
+    StringCchCat(systemPath, MAX_PATH, TEXT("\\dxgi.dll"));
+
+    return LoadLibrary(systemPath);
+}
+
+typedef HRESULT (APIENTRY *PFN_CreateDXGIFactory1)(REFIID riid, void **ppFactory);
+
+HRESULT dyn_CreateDXGIFactory1(REFIID riid, void **ppFactory) {
+    PFN_CreateDXGIFactory1 fpCreateDXGIFactory1 =
+        (PFN_CreateDXGIFactory1)GetProcAddress(load_dxgi_module(), "CreateDXGIFactory1");
+
+    if (fpCreateDXGIFactory1 != NULL)
+        return fpCreateDXGIFactory1(riid, ppFactory);
+
+    return DXGI_ERROR_NOT_FOUND;
+}
\ No newline at end of file
diff --git a/loader/dxgi_loader.h b/loader/dxgi_loader.h
new file mode 100644
index 0000000..00daf08
--- /dev/null
+++ b/loader/dxgi_loader.h
@@ -0,0 +1,8 @@
+#ifndef DXGI_LOADER_H
+#define DXGI_LOADER_H
+
+#include <dxgi1_2.h>
+
+HRESULT dyn_CreateDXGIFactory1(REFIID riid, void **ppFactory);
+
+#endif
\ No newline at end of file
diff --git a/loader/loader.c b/loader/loader.c
index 405b083..39ccc25 100644
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -71,7 +71,7 @@
 #include <devpkey.h>
 #include <winternl.h>
 #include <d3dkmthk.h>
-#include <dxgi1_2.h>
+#include "dxgi_loader.h"
 
 typedef _Check_return_ NTSTATUS (APIENTRY *PFN_D3DKMTEnumAdapters2)(const D3DKMT_ENUMADAPTERS2*);
 typedef _Check_return_ NTSTATUS (APIENTRY *PFN_D3DKMTQueryAdapterInfo)(const D3DKMT_QUERYADAPTERINFO*);
@@ -873,7 +873,7 @@
     }
 
     if (is_driver) {
-        HRESULT hres = CreateDXGIFactory1(&IID_IDXGIFactory1, &dxgi_factory);
+        HRESULT hres = dyn_CreateDXGIFactory1(&IID_IDXGIFactory1, &dxgi_factory);
         if (hres != S_OK) {
             loader_log(
                 inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,