dxgi-offsets.cpp 2.9 KB

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