kiero.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750
  1. #include "../include/kiero.h"
  2. #include <Windows.h>
  3. #ifdef KIERO_USE_MINHOOK
  4. #include "../include/minhook.h"
  5. #endif
  6. //#include <MinHook.h>
  7. // Uncomment a needed graphical library (you can include all)
  8. #include <d3d9.h> // D3D9
  9. #include <dxgi.h> // D3D10/D3D11/D3D12 (must be included for d3d12 hook)
  10. #include <d3d10_1.h> // D3D10
  11. #include <d3d10.h> // D3D10
  12. #define KIERO_D3D10_USAGE // This need because d3d11.h includes d3d10.h
  13. #include <d3d11.h> // D3D11
  14. //#include <d3d12.h> // D3D12
  15. //#include <gl/GL.h> // OpenGL
  16. //#include <vulkan/vulkan.h> // Vulkan
  17. #include <string>
  18. #if defined(KIERO_D3D10_USAGE) && !defined(__d3d10_h__)
  19. # error KIERO_D3D10_USAGE defined, but d3d10.h not included
  20. #endif
  21. #if defined(__d3d12_h__) && !defined(__dxgi_h__)
  22. # error d3d12.h included, but dxgi.h not included
  23. #endif
  24. static kiero::RenderType::Enum g_renderType = kiero::RenderType::None;
  25. // See METHODSTABLE.txt for more information
  26. #if KIERO_ARCH_X64
  27. static uint64_t* g_methodsTable = NULL;
  28. #else
  29. static uint32_t* g_methodsTable = NULL;
  30. #endif
  31. HMODULE GetSystemModule(const char* module) {
  32. static std::string systemPath;
  33. if (systemPath.empty()) {
  34. systemPath.resize(2048);
  35. uint32_t res = GetSystemDirectoryA(&systemPath[0], systemPath.size());
  36. systemPath.resize(res);
  37. }
  38. std::string basePath = systemPath + "\\" + module;
  39. //MessageBoxA(NULL, basePath.data(), "", 0);
  40. return GetModuleHandleA(basePath.c_str());
  41. }
  42. kiero::Status::Enum kiero::init(int _renderType)
  43. {
  44. if (_renderType != RenderType::None)
  45. {
  46. if (_renderType >= RenderType::D3D9 && _renderType <= RenderType::D3D12)
  47. {
  48. WNDCLASSEX windowClass;
  49. windowClass.cbSize = sizeof(WNDCLASSEX);
  50. windowClass.style = CS_HREDRAW | CS_VREDRAW;
  51. windowClass.lpfnWndProc = DefWindowProc;
  52. windowClass.cbClsExtra = 0;
  53. windowClass.cbWndExtra = 0;
  54. windowClass.hInstance = GetModuleHandle(NULL);
  55. windowClass.hIcon = NULL;
  56. windowClass.hCursor = NULL;
  57. windowClass.hbrBackground = NULL;
  58. windowClass.lpszMenuName = NULL;
  59. windowClass.lpszClassName = KIERO_TEXT("Kiero");
  60. windowClass.hIconSm = NULL;
  61. ::RegisterClassEx(&windowClass);
  62. HWND window = ::CreateWindow(windowClass.lpszClassName, KIERO_TEXT("Kiero DirectX Window"), WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, NULL, NULL, windowClass.hInstance, NULL);
  63. if (_renderType == RenderType::D3D9)
  64. {
  65. #ifdef _D3D9_H_
  66. HMODULE libD3D9;
  67. if ((libD3D9 = ::GetModuleHandle(KIERO_TEXT("d3d9.dll"))) == NULL)
  68. {
  69. ::DestroyWindow(window);
  70. ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
  71. return Status::ModuleNotFoundError;
  72. }
  73. void* Direct3DCreate9;
  74. if ((Direct3DCreate9 = ::GetProcAddress(libD3D9, "Direct3DCreate9")) == NULL)
  75. {
  76. ::DestroyWindow(window);
  77. ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
  78. return Status::UnknownError;
  79. }
  80. LPDIRECT3D9 direct3D9;
  81. if ((direct3D9 = ((LPDIRECT3D9(__stdcall*)(uint32_t))(Direct3DCreate9))(D3D_SDK_VERSION)) == NULL)
  82. {
  83. ::DestroyWindow(window);
  84. ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
  85. return Status::UnknownError;
  86. }
  87. D3DDISPLAYMODE displayMode;
  88. if (direct3D9->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode) < 0)
  89. {
  90. ::DestroyWindow(window);
  91. ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
  92. return Status::UnknownError;
  93. }
  94. D3DPRESENT_PARAMETERS params;
  95. params.BackBufferWidth = 0;
  96. params.BackBufferHeight = 0;
  97. params.BackBufferFormat = displayMode.Format;
  98. params.BackBufferCount = 0;
  99. params.MultiSampleType = D3DMULTISAMPLE_NONE;
  100. params.MultiSampleQuality = NULL;
  101. params.SwapEffect = D3DSWAPEFFECT_DISCARD;
  102. params.hDeviceWindow = window;
  103. params.Windowed = 1;
  104. params.EnableAutoDepthStencil = 0;
  105. params.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
  106. params.Flags = NULL;
  107. params.FullScreen_RefreshRateInHz = 0;
  108. params.PresentationInterval = 0;
  109. LPDIRECT3DDEVICE9 device;
  110. if (direct3D9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window, D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_DISABLE_DRIVER_MANAGEMENT, &params, &device) < 0)
  111. {
  112. direct3D9->Release();
  113. ::DestroyWindow(window);
  114. ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
  115. return Status::UnknownError;
  116. }
  117. #if KIERO_ARCH_X64
  118. g_methodsTable = (uint64_t*)::calloc(119, sizeof(uint64_t));
  119. ::memcpy(g_methodsTable, *(uint64_t**)device, 119 * sizeof(uint64_t));
  120. #else
  121. g_methodsTable = (uint32_t*)::calloc(119, sizeof(uint32_t));
  122. ::memcpy(g_methodsTable, *(uint32_t**)device, 119 * sizeof(uint32_t));
  123. #endif
  124. #ifdef KIERO_USE_MINHOOK
  125. MH_Initialize();
  126. #endif
  127. direct3D9->Release();
  128. direct3D9 = NULL;
  129. device->Release();
  130. device = NULL;
  131. g_renderType = RenderType::D3D9;
  132. ::DestroyWindow(window);
  133. ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
  134. return Status::Success;
  135. #endif // _D3D9_H_
  136. }
  137. else if (_renderType == RenderType::D3D10)
  138. {
  139. #if defined(__d3d10_h__) && defined(KIERO_D3D10_USAGE)
  140. HMODULE libDXGI;
  141. HMODULE libD3D10;
  142. if ((libDXGI = ::GetModuleHandle(KIERO_TEXT("dxgi.dll"))) == NULL || (libD3D10 = ::GetModuleHandle(KIERO_TEXT("d3d10.dll"))) == NULL)
  143. {
  144. ::DestroyWindow(window);
  145. ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
  146. return Status::ModuleNotFoundError;
  147. }
  148. void* CreateDXGIFactory;
  149. if ((CreateDXGIFactory = ::GetProcAddress(libDXGI, "CreateDXGIFactory")) == NULL)
  150. {
  151. ::DestroyWindow(window);
  152. ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
  153. return Status::UnknownError;
  154. }
  155. IDXGIFactory* factory;
  156. if (((long(__stdcall*)(const IID&, void**))(CreateDXGIFactory))(__uuidof(IDXGIFactory), (void**)&factory) < 0)
  157. {
  158. ::DestroyWindow(window);
  159. ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
  160. return Status::UnknownError;
  161. }
  162. IDXGIAdapter* adapter;
  163. if (factory->EnumAdapters(0, &adapter) == DXGI_ERROR_NOT_FOUND)
  164. {
  165. ::DestroyWindow(window);
  166. ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
  167. return Status::UnknownError;
  168. }
  169. void* D3D10CreateDeviceAndSwapChain;
  170. if ((D3D10CreateDeviceAndSwapChain = ::GetProcAddress(libD3D10, "D3D10CreateDeviceAndSwapChain")) == NULL)
  171. {
  172. ::DestroyWindow(window);
  173. ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
  174. return Status::UnknownError;
  175. }
  176. DXGI_RATIONAL refreshRate;
  177. refreshRate.Numerator = 60;
  178. refreshRate.Denominator = 1;
  179. DXGI_MODE_DESC bufferDesc;
  180. bufferDesc.Width = 100;
  181. bufferDesc.Height = 100;
  182. bufferDesc.RefreshRate = refreshRate;
  183. bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  184. bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
  185. bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
  186. DXGI_SAMPLE_DESC sampleDesc;
  187. sampleDesc.Count = 1;
  188. sampleDesc.Quality = 0;
  189. DXGI_SWAP_CHAIN_DESC swapChainDesc;
  190. swapChainDesc.BufferDesc = bufferDesc;
  191. swapChainDesc.SampleDesc = sampleDesc;
  192. swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
  193. swapChainDesc.BufferCount = 1;
  194. swapChainDesc.OutputWindow = window;
  195. swapChainDesc.Windowed = 1;
  196. swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
  197. swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
  198. IDXGISwapChain* swapChain;
  199. ID3D10Device* device;
  200. if (((long(__stdcall*)(
  201. IDXGIAdapter*,
  202. D3D10_DRIVER_TYPE,
  203. HMODULE,
  204. UINT,
  205. UINT,
  206. DXGI_SWAP_CHAIN_DESC*,
  207. IDXGISwapChain**,
  208. ID3D10Device**))(D3D10CreateDeviceAndSwapChain))(adapter, D3D10_DRIVER_TYPE_HARDWARE, NULL, 0, D3D10_SDK_VERSION, &swapChainDesc, &swapChain, &device) < 0)
  209. {
  210. ::DestroyWindow(window);
  211. ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
  212. return Status::UnknownError;
  213. }
  214. #if KIERO_ARCH_X64
  215. g_methodsTable = (uint64_t*)::calloc(116, sizeof(uint64_t));
  216. ::memcpy(g_methodsTable, *(uint64_t**)swapChain, 18 * sizeof(uint64_t));
  217. ::memcpy(g_methodsTable + 18, *(uint64_t**)device, 98 * sizeof(uint64_t));
  218. #else
  219. g_methodsTable = (uint32_t*)::calloc(116, sizeof(uint32_t));
  220. ::memcpy(g_methodsTable, *(uint32_t**)swapChain, 18 * sizeof(uint32_t));
  221. ::memcpy(g_methodsTable + 18, *(uint32_t**)device, 98 * sizeof(uint32_t));
  222. #endif
  223. #ifdef KIERO_USE_MINHOOK
  224. MH_Initialize();
  225. #endif
  226. swapChain->Release();
  227. swapChain = NULL;
  228. device->Release();
  229. device = NULL;
  230. ::DestroyWindow(window);
  231. ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
  232. g_renderType = RenderType::D3D10;
  233. return Status::Success;
  234. #endif // __d3d10_h__
  235. }
  236. else if (_renderType == RenderType::D3D11)
  237. {
  238. #ifdef __d3d11_h__
  239. HMODULE libD3D11;
  240. if ((libD3D11 = ::GetModuleHandle(KIERO_TEXT("d3d11.dll"))) == NULL)
  241. {
  242. ::DestroyWindow(window);
  243. ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
  244. return Status::ModuleNotFoundError;
  245. }
  246. void* D3D11CreateDeviceAndSwapChain;
  247. if ((D3D11CreateDeviceAndSwapChain = ::GetProcAddress(libD3D11, "D3D11CreateDeviceAndSwapChain")) == NULL)
  248. {
  249. ::DestroyWindow(window);
  250. ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
  251. return Status::UnknownError;
  252. }
  253. D3D_FEATURE_LEVEL featureLevel;
  254. const D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_11_0 };
  255. DXGI_RATIONAL refreshRate;
  256. refreshRate.Numerator = 60;
  257. refreshRate.Denominator = 1;
  258. DXGI_MODE_DESC bufferDesc;
  259. bufferDesc.Width = 100;
  260. bufferDesc.Height = 100;
  261. bufferDesc.RefreshRate = refreshRate;
  262. bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  263. bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
  264. bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
  265. DXGI_SAMPLE_DESC sampleDesc;
  266. sampleDesc.Count = 1;
  267. sampleDesc.Quality = 0;
  268. DXGI_SWAP_CHAIN_DESC swapChainDesc;
  269. swapChainDesc.BufferDesc = bufferDesc;
  270. swapChainDesc.SampleDesc = sampleDesc;
  271. swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
  272. swapChainDesc.BufferCount = 1;
  273. swapChainDesc.OutputWindow = window;
  274. swapChainDesc.Windowed = 1;
  275. swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
  276. swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
  277. IDXGISwapChain* swapChain;
  278. ID3D11Device* device;
  279. ID3D11DeviceContext* context;
  280. if (((long(__stdcall*)(
  281. IDXGIAdapter*,
  282. D3D_DRIVER_TYPE,
  283. HMODULE,
  284. UINT,
  285. const D3D_FEATURE_LEVEL*,
  286. UINT,
  287. UINT,
  288. const DXGI_SWAP_CHAIN_DESC*,
  289. IDXGISwapChain**,
  290. ID3D11Device**,
  291. D3D_FEATURE_LEVEL*,
  292. ID3D11DeviceContext**))(D3D11CreateDeviceAndSwapChain))(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, featureLevels, 1, D3D11_SDK_VERSION, &swapChainDesc, &swapChain, &device, &featureLevel, &context) < 0)
  293. {
  294. ::DestroyWindow(window);
  295. ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
  296. return Status::UnknownError;
  297. }
  298. #if KIERO_ARCH_X64
  299. g_methodsTable = (uint64_t*)::calloc(205, sizeof(uint64_t));
  300. ::memcpy(g_methodsTable, *(uint64_t**)swapChain, 18 * sizeof(uint64_t));
  301. ::memcpy(g_methodsTable + 18, *(uint64_t**)device, 43 * sizeof(uint64_t));
  302. ::memcpy(g_methodsTable + 18 + 43, *(uint64_t**)context, 144 * sizeof(uint64_t));
  303. #else
  304. g_methodsTable = (uint32_t*)::calloc(205, sizeof(uint32_t));
  305. ::memcpy(g_methodsTable, *(uint32_t**)swapChain, 18 * sizeof(uint32_t));
  306. ::memcpy(g_methodsTable + 18, *(uint32_t**)device, 43 * sizeof(uint32_t));
  307. ::memcpy(g_methodsTable + 18 + 43, *(uint32_t**)context, 144 * sizeof(uint32_t));
  308. #endif
  309. #ifdef KIERO_USE_MINHOOK
  310. MH_Initialize();
  311. #endif
  312. swapChain->Release();
  313. swapChain = NULL;
  314. device->Release();
  315. device = NULL;
  316. context->Release();
  317. context = NULL;
  318. ::DestroyWindow(window);
  319. ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
  320. g_renderType = RenderType::D3D11;
  321. return Status::Success;
  322. #endif // __d3d11_h__
  323. }
  324. else if (_renderType == RenderType::D3D12)
  325. {
  326. #if defined(__d3d12_h__) && defined(__dxgi_h__)
  327. HMODULE libDXGI;
  328. HMODULE libD3D12;
  329. if ((libDXGI = ::GetModuleHandle(KIERO_TEXT("dxgi.dll"))) == NULL || (libD3D12 = ::GetModuleHandle(KIERO_TEXT("d3d12.dll"))) == NULL)
  330. {
  331. ::DestroyWindow(window);
  332. ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
  333. return Status::ModuleNotFoundError;
  334. }
  335. void* CreateDXGIFactory;
  336. if ((CreateDXGIFactory = ::GetProcAddress(libDXGI, "CreateDXGIFactory")) == NULL)
  337. {
  338. ::DestroyWindow(window);
  339. ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
  340. return Status::UnknownError;
  341. }
  342. IDXGIFactory* factory;
  343. if (((long(__stdcall*)(const IID&, void**))(CreateDXGIFactory))(__uuidof(IDXGIFactory), (void**)&factory) < 0)
  344. {
  345. ::DestroyWindow(window);
  346. ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
  347. return Status::UnknownError;
  348. }
  349. IDXGIAdapter* adapter;
  350. if (factory->EnumAdapters(0, &adapter) == DXGI_ERROR_NOT_FOUND)
  351. {
  352. ::DestroyWindow(window);
  353. ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
  354. return Status::UnknownError;
  355. }
  356. void* D3D12CreateDevice;
  357. if ((D3D12CreateDevice = ::GetProcAddress(libD3D12, "D3D12CreateDevice")) == NULL)
  358. {
  359. ::DestroyWindow(window);
  360. ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
  361. return Status::UnknownError;
  362. }
  363. ID3D12Device* device;
  364. if (((long(__stdcall*)(IUnknown*, D3D_FEATURE_LEVEL, const IID&, void**))(D3D12CreateDevice))(adapter, D3D_FEATURE_LEVEL_11_0, __uuidof(ID3D12Device), (void**)&device) < 0)
  365. {
  366. ::DestroyWindow(window);
  367. ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
  368. return Status::UnknownError;
  369. }
  370. D3D12_COMMAND_QUEUE_DESC queueDesc;
  371. queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
  372. queueDesc.Priority = 0;
  373. queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
  374. queueDesc.NodeMask = 0;
  375. ID3D12CommandQueue* commandQueue;
  376. if (device->CreateCommandQueue(&queueDesc, __uuidof(ID3D12CommandQueue), (void**)&commandQueue) < 0)
  377. {
  378. ::DestroyWindow(window);
  379. ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
  380. return Status::UnknownError;
  381. }
  382. ID3D12CommandAllocator* commandAllocator;
  383. if (device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, __uuidof(ID3D12CommandAllocator), (void**)&commandAllocator) < 0)
  384. {
  385. ::DestroyWindow(window);
  386. ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
  387. return Status::UnknownError;
  388. }
  389. ID3D12GraphicsCommandList* commandList;
  390. if (device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, commandAllocator, NULL, __uuidof(ID3D12GraphicsCommandList), (void**)&commandList) < 0)
  391. {
  392. ::DestroyWindow(window);
  393. ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
  394. return Status::UnknownError;
  395. }
  396. DXGI_RATIONAL refreshRate;
  397. refreshRate.Numerator = 60;
  398. refreshRate.Denominator = 1;
  399. DXGI_MODE_DESC bufferDesc;
  400. bufferDesc.Width = 100;
  401. bufferDesc.Height = 100;
  402. bufferDesc.RefreshRate = refreshRate;
  403. bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  404. bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
  405. bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
  406. DXGI_SAMPLE_DESC sampleDesc;
  407. sampleDesc.Count = 1;
  408. sampleDesc.Quality = 0;
  409. DXGI_SWAP_CHAIN_DESC swapChainDesc = {};
  410. swapChainDesc.BufferDesc = bufferDesc;
  411. swapChainDesc.SampleDesc = sampleDesc;
  412. swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
  413. swapChainDesc.BufferCount = 2;
  414. swapChainDesc.OutputWindow = window;
  415. swapChainDesc.Windowed = 1;
  416. swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
  417. swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
  418. IDXGISwapChain* swapChain;
  419. if (factory->CreateSwapChain(commandQueue, &swapChainDesc, &swapChain) < 0)
  420. {
  421. ::DestroyWindow(window);
  422. ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
  423. return Status::UnknownError;
  424. }
  425. #if KIERO_ARCH_X64
  426. g_methodsTable = (uint64_t*)::calloc(150, sizeof(uint64_t));
  427. memcpy(g_methodsTable, *(uint64_t**)device, 44 * sizeof(uint64_t));
  428. memcpy(g_methodsTable + 44, *(uint64_t**)commandQueue, 19 * sizeof(uint64_t));
  429. memcpy(g_methodsTable + 44 + 19, *(uint64_t**)commandAllocator, 9 * sizeof(uint64_t));
  430. memcpy(g_methodsTable + 44 + 19 + 9, *(uint64_t**)commandList, 60 * sizeof(uint64_t));
  431. memcpy(g_methodsTable + 44 + 19 + 9 + 60, *(uint64_t**)swapChain, 18 * sizeof(uint64_t));
  432. #else
  433. g_methodsTable = (uint32_t*)::calloc(150, sizeof(uint32_t));
  434. memcpy(g_methodsTable, *(uint32_t**)device, 44 * sizeof(uint32_t));
  435. memcpy(g_methodsTable + 44, *(uint32_t**)commandQueue, 19 * sizeof(uint32_t));
  436. memcpy(g_methodsTable + 44 + 19, *(uint32_t**)commandAllocator, 9 * sizeof(uint32_t));
  437. memcpy(g_methodsTable + 44 + 19 + 9, *(uint32_t**)commandList, 60 * sizeof(uint32_t));
  438. memcpy(g_methodsTable + 44 + 19 + 9 + 60, *(uint32_t**)swapChain, 18 * sizeof(uint32_t));
  439. #endif
  440. #ifdef KIERO_USE_MINHOOK
  441. MH_Initialize();
  442. #endif
  443. device->Release();
  444. device = NULL;
  445. commandQueue->Release();
  446. commandQueue = NULL;
  447. commandAllocator->Release();
  448. commandAllocator = NULL;
  449. commandList->Release();
  450. commandList = NULL;
  451. swapChain->Release();
  452. swapChain = NULL;
  453. ::DestroyWindow(window);
  454. ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
  455. g_renderType = RenderType::D3D12;
  456. return Status::Success;
  457. #endif // __d3d12_h__
  458. }
  459. return Status::NotSupportedError;
  460. }
  461. else if (_renderType == RenderType::OpenGL)
  462. {
  463. HMODULE libOpenGL32 = GetSystemModule("opengl32.dll");
  464. if (libOpenGL32 == NULL)
  465. {
  466. return Status::ModuleNotFoundError;
  467. }
  468. const char* const methodsNames[] = {
  469. "glBegin","glEnd","wglSwapBuffers","glFinish"
  470. };
  471. const size_t size = KIERO_ARRAY_SIZE(methodsNames);
  472. #if KIERO_ARCH_X64
  473. g_methodsTable = (uint64_t*)::calloc(size, sizeof(uint64_t));
  474. for (int i = 0; i < size; i++)
  475. {
  476. g_methodsTable[i] = (uint64_t)::GetProcAddress(libOpenGL32, methodsNames[i]);
  477. }
  478. #else
  479. g_methodsTable = (uint32_t*)::calloc(size, sizeof(uint32_t));
  480. for (int i = 0; i < size; i++)
  481. {
  482. g_methodsTable[i] = (uint32_t)::GetProcAddress(libOpenGL32, methodsNames[i]);
  483. }
  484. #endif
  485. #ifdef KIERO_USE_MINHOOK
  486. MH_Initialize();
  487. #endif
  488. g_renderType = RenderType::OpenGL;
  489. return Status::Success;
  490. //#endif // __gl_h_
  491. }
  492. else if (_renderType == RenderType::OpenglES) {
  493. HMODULE libegl = GetModuleHandleW(L"libEGL.dll");
  494. if (libegl == NULL)
  495. {
  496. return Status::ModuleNotFoundError;
  497. }
  498. const char* const methodsNames[] = {
  499. "eglSwapBuffers"
  500. };
  501. const size_t size = KIERO_ARRAY_SIZE(methodsNames);
  502. #if KIERO_ARCH_X64
  503. g_methodsTable = (uint64_t*)::calloc(size, sizeof(uint64_t));
  504. for (int i = 0; i < size; i++)
  505. {
  506. g_methodsTable[i] = (uint64_t)::GetProcAddress(libegl, methodsNames[i]);
  507. }
  508. #else
  509. g_methodsTable = (uint32_t*)::calloc(size, sizeof(uint32_t));
  510. for (int i = 0; i < size; i++)
  511. {
  512. g_methodsTable[i] = (uint32_t)::GetProcAddress(libegl, methodsNames[i]);
  513. }
  514. #endif
  515. #ifdef KIERO_USE_MINHOOK
  516. MH_Initialize();
  517. #endif
  518. g_renderType = RenderType::OpenglES;
  519. return Status::Success;
  520. }
  521. else if (_renderType == RenderType::Vulkan)
  522. {
  523. #ifdef VULKAN_H_
  524. HMODULE libVulkan;
  525. if ((libVulkan = GetModuleHandle(KIERO_TEXT("vulcan-1.dll"))) == NULL)
  526. {
  527. return Status::ModuleNotFoundError;
  528. }
  529. const char* const methodsNames[] = {
  530. "vkCreateInstance", "vkDestroyInstance", "vkEnumeratePhysicalDevices", "vkGetPhysicalDeviceFeatures", "vkGetPhysicalDeviceFormatProperties", "vkGetPhysicalDeviceImageFormatProperties",
  531. "vkGetPhysicalDeviceProperties", "vkGetPhysicalDeviceQueueFamilyProperties", "vkGetPhysicalDeviceMemoryProperties", "vkGetInstanceProcAddr", "vkGetDeviceProcAddr", "vkCreateDevice",
  532. "vkDestroyDevice", "vkEnumerateInstanceExtensionProperties", "vkEnumerateDeviceExtensionProperties", "vkEnumerateDeviceLayerProperties", "vkGetDeviceQueue", "vkQueueSubmit", "vkQueueWaitIdle",
  533. "vkDeviceWaitIdle", "vkAllocateMemory", "vkFreeMemory", "vkMapMemory", "vkUnmapMemory", "vkFlushMappedMemoryRanges", "vkInvalidateMappedMemoryRanges", "vkGetDeviceMemoryCommitment",
  534. "vkBindBufferMemory", "vkBindImageMemory", "vkGetBufferMemoryRequirements", "vkGetImageMemoryRequirements", "vkGetImageSparseMemoryRequirements", "vkGetPhysicalDeviceSparseImageFormatProperties",
  535. "vkQueueBindSparse", "vkCreateFence", "vkDestroyFence", "vkResetFences", "vkGetFenceStatus", "vkWaitForFences", "vkCreateSemaphore", "vkDestroySemaphore", "vkCreateEvent", "vkDestroyEvent",
  536. "vkGetEventStatus", "vkSetEvent", "vkResetEvent", "vkCreateQueryPool", "vkDestroyQueryPool", "vkGetQueryPoolResults", "vkCreateBuffer", "vkDestroyBuffer", "vkCreateBufferView", "vkDestroyBufferView",
  537. "vkCreateImage", "vkDestroyImage", "vkGetImageSubresourceLayout", "vkCreateImageView", "vkDestroyImageView", "vkCreateShaderModule", "vkDestroyShaderModule", "vkCreatePipelineCache",
  538. "vkDestroyPipelineCache", "vkGetPipelineCacheData", "vkMergePipelineCaches", "vkCreateGraphicsPipelines", "vkCreateComputePipelines", "vkDestroyPipeline", "vkCreatePipelineLayout",
  539. "vkDestroyPipelineLayout", "vkCreateSampler", "vkDestroySampler", "vkCreateDescriptorSetLayout", "vkDestroyDescriptorSetLayout", "vkCreateDescriptorPool", "vkDestroyDescriptorPool",
  540. "vkResetDescriptorPool", "vkAllocateDescriptorSets", "vkFreeDescriptorSets", "vkUpdateDescriptorSets", "vkCreateFramebuffer", "vkDestroyFramebuffer", "vkCreateRenderPass", "vkDestroyRenderPass",
  541. "vkGetRenderAreaGranularity", "vkCreateCommandPool", "vkDestroyCommandPool", "vkResetCommandPool", "vkAllocateCommandBuffers", "vkFreeCommandBuffers", "vkBeginCommandBuffer", "vkEndCommandBuffer",
  542. "vkResetCommandBuffer", "vkCmdBindPipeline", "vkCmdSetViewport", "vkCmdSetScissor", "vkCmdSetLineWidth", "vkCmdSetDepthBias", "vkCmdSetBlendConstants", "vkCmdSetDepthBounds",
  543. "vkCmdSetStencilCompareMask", "vkCmdSetStencilWriteMask", "vkCmdSetStencilReference", "vkCmdBindDescriptorSets", "vkCmdBindIndexBuffer", "vkCmdBindVertexBuffers", "vkCmdDraw", "vkCmdDrawIndexed",
  544. "vkCmdDrawIndirect", "vkCmdDrawIndexedIndirect", "vkCmdDispatch", "vkCmdDispatchIndirect", "vkCmdCopyBuffer", "vkCmdCopyImage", "vkCmdBlitImage", "vkCmdCopyBufferToImage", "vkCmdCopyImageToBuffer",
  545. "vkCmdUpdateBuffer", "vkCmdFillBuffer", "vkCmdClearColorImage", "vkCmdClearDepthStencilImage", "vkCmdClearAttachments", "vkCmdResolveImage", "vkCmdSetEvent", "vkCmdResetEvent", "vkCmdWaitEvents",
  546. "vkCmdPipelineBarrier", "vkCmdBeginQuery", "vkCmdEndQuery", "vkCmdResetQueryPool", "vkCmdWriteTimestamp", "vkCmdCopyQueryPoolResults", "vkCmdPushConstants", "vkCmdBeginRenderPass", "vkCmdNextSubpass",
  547. "vkCmdEndRenderPass", "vkCmdExecuteCommands"
  548. };
  549. size_t size = KIERO_ARRAY_SIZE(methodsNames);
  550. #if KIERO_ARCH_X64
  551. g_methodsTable = (uint64_t*)::calloc(size, sizeof(uint64_t));
  552. for (int i = 0; i < size; i++)
  553. {
  554. g_methodsTable[i] = (uint64_t)::GetProcAddress(libVulkan, methodsNames[i]);
  555. }
  556. #else
  557. g_methodsTable = (uint32_t*)::calloc(size, sizeof(uint32_t));
  558. for (int i = 0; i < size; i++)
  559. {
  560. g_methodsTable[i] = (uint32_t)::GetProcAddress(libVulkan, methodsNames[i]);
  561. }
  562. #endif
  563. #ifdef KIERO_USE_MINHOOK
  564. MH_Initialize();
  565. #endif
  566. g_renderType = RenderType::Vulkan;
  567. return Status::Success;
  568. #endif // VULKAN_H_
  569. }
  570. return Status::NotSupportedError;
  571. }
  572. return Status::Success;
  573. }
  574. void kiero::shutdown()
  575. {
  576. if (g_renderType > 0)
  577. {
  578. #ifdef KIERO_USE_MINHOOK
  579. MH_Uninitialize();
  580. #endif
  581. ::free(g_methodsTable);
  582. g_methodsTable = NULL;
  583. g_renderType = RenderType::None;
  584. }
  585. }
  586. kiero::RenderType::Enum kiero::getRenderType()
  587. {
  588. return g_renderType;
  589. }
  590. #if KIERO_ARCH_X64
  591. uint64_t* kiero::getMethodsTable()
  592. {
  593. return g_methodsTable;
  594. }
  595. #else
  596. uint32_t* kiero::getMethodsTable()
  597. {
  598. return g_methodsTable;
  599. }
  600. #endif
  601. //void kiero::bind(uint16_t _index, void* _original, void* _function)
  602. int kiero::bind(uint16_t _index, void** _original, void* _function)
  603. {
  604. // TODO: Need own detour function
  605. #ifdef KIERO_USE_MINHOOK
  606. if (g_renderType > 0)
  607. {
  608. //MH_CreateHook((void*)g_methodsTable[_index], _function, &_original);
  609. int r1 = MH_CreateHook((void*)g_methodsTable[_index], _function, _original);
  610. int r2 = MH_EnableHook((void*)g_methodsTable[_index]);
  611. return r1 == MH_OK && r2 == MH_OK ? 1 : 0;
  612. }
  613. return 0;
  614. #endif
  615. }
  616. int kiero::unbind() {
  617. int ret = -1;
  618. if (g_renderType > 0)
  619. {
  620. MH_DisableHook(MH_ALL_HOOKS);
  621. ret = MH_RemoveHook(MH_ALL_HOOKS);
  622. kiero::shutdown();
  623. //MessageBoxA(NULL, MH_StatusToString((MH_STATUS)ret), "", 0);
  624. //MH_DisableHook((void*)g_methodsTable[_index]);
  625. //MH_RemoveHook((void*)g_methodsTable[_index]);
  626. //MH_CreateHook((void*)g_methodsTable[_index], _function, &_original);
  627. }
  628. return ret;
  629. }