dxgi-offsets.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. #include <windows.h>
  2. #include <d3d10.h>
  3. #include <VersionHelpers.h>
  4. #include <dxgi1_2.h>
  5. #include "get-graphics-offsets.h"
  6. typedef HRESULT (WINAPI *d3d10create_t)(IDXGIAdapter*, D3D10_DRIVER_TYPE,
  7. HMODULE, UINT, UINT, DXGI_SWAP_CHAIN_DESC*,
  8. IDXGISwapChain**, IUnknown**);
  9. typedef HRESULT (WINAPI *create_fac_t)(IID *id, void**);
  10. struct dxgi_info {
  11. HMODULE module;
  12. HWND hwnd;
  13. IDXGISwapChain *swap;
  14. };
  15. static const IID dxgiFactory2 =
  16. {0x50c83a1c, 0xe072, 0x4c48, {0x87, 0xb0, 0x36, 0x30, 0xfa, 0x36, 0xa6, 0xd0}};
  17. static inline bool dxgi_init(dxgi_info &info)
  18. {
  19. HMODULE d3d10_module;
  20. d3d10create_t create;
  21. create_fac_t create_factory;
  22. IDXGIFactory1 *factory;
  23. IDXGIAdapter1 *adapter;
  24. IUnknown *device;
  25. HRESULT hr;
  26. info.hwnd = CreateWindowExA(0, DUMMY_WNDCLASS, "d3d10 get-offset window",
  27. WS_POPUP, 0, 0, 2, 2, nullptr, nullptr,
  28. GetModuleHandleA(nullptr), nullptr);
  29. if (!info.hwnd) {
  30. return false;
  31. }
  32. info.module = LoadLibraryA("dxgi.dll");
  33. if (!info.module) {
  34. return false;
  35. }
  36. create_factory = (create_fac_t)GetProcAddress(info.module,
  37. "CreateDXGIFactory1");
  38. d3d10_module = LoadLibraryA("d3d10.dll");
  39. if (!d3d10_module) {
  40. return false;
  41. }
  42. create = (d3d10create_t)GetProcAddress(d3d10_module,
  43. "D3D10CreateDeviceAndSwapChain");
  44. if (!create) {
  45. return false;
  46. }
  47. IID factory_iid = IsWindows8OrGreater()
  48. ? dxgiFactory2
  49. : __uuidof(IDXGIFactory1);
  50. hr = create_factory(&factory_iid, (void**)&factory);
  51. if (FAILED(hr)) {
  52. return false;
  53. }
  54. hr = factory->EnumAdapters1(0, &adapter);
  55. factory->Release();
  56. if (FAILED(hr)) {
  57. return false;
  58. }
  59. DXGI_SWAP_CHAIN_DESC desc = {};
  60. desc.BufferCount = 2;
  61. desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  62. desc.BufferDesc.Width = 2;
  63. desc.BufferDesc.Height = 2;
  64. desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
  65. desc.OutputWindow = info.hwnd;
  66. desc.SampleDesc.Count = 1;
  67. desc.Windowed = true;
  68. hr = create(adapter, D3D10_DRIVER_TYPE_HARDWARE, nullptr, 0,
  69. D3D10_SDK_VERSION, &desc, &info.swap, &device);
  70. adapter->Release();
  71. if (FAILED(hr)) {
  72. return false;
  73. }
  74. device->Release();
  75. return true;
  76. }
  77. static inline void dxgi_free(dxgi_info &info)
  78. {
  79. if (info.swap)
  80. info.swap->Release();
  81. if (info.hwnd)
  82. DestroyWindow(info.hwnd);
  83. }
  84. void get_dxgi_offsets(struct dxgi_offsets *offsets)
  85. {
  86. dxgi_info info = {};
  87. bool success = dxgi_init(info);
  88. HRESULT hr;
  89. if (success) {
  90. offsets->present = vtable_offset(info.module, info.swap, 8);
  91. offsets->resize = vtable_offset(info.module, info.swap, 13);
  92. IDXGISwapChain1 *swap1;
  93. hr = info.swap->QueryInterface(__uuidof(IDXGISwapChain1),
  94. (void**)&swap1);
  95. if (SUCCEEDED(hr)) {
  96. offsets->present1 =
  97. vtable_offset(info.module, swap1, 22);
  98. swap1->Release();
  99. }
  100. }
  101. dxgi_free(info);
  102. }