mirror of
https://github.com/obsproject/obs-studio.git
synced 2026-03-22 00:12:06 -04:00
Code submissions have continually suffered from formatting inconsistencies that constantly have to be addressed. Using clang-format simplifies this by making code formatting more consistent, and allows automation of the code formatting so that maintainers can focus more on the code itself instead of code formatting.
127 lines
2.8 KiB
C++
127 lines
2.8 KiB
C++
#include <windows.h>
|
|
#include <d3d10.h>
|
|
#include <VersionHelpers.h>
|
|
#include <dxgi1_2.h>
|
|
#include "get-graphics-offsets.h"
|
|
|
|
typedef HRESULT(WINAPI *d3d10create_t)(IDXGIAdapter *, D3D10_DRIVER_TYPE,
|
|
HMODULE, UINT, UINT,
|
|
DXGI_SWAP_CHAIN_DESC *,
|
|
IDXGISwapChain **, IUnknown **);
|
|
typedef HRESULT(WINAPI *create_fac_t)(IID *id, void **);
|
|
|
|
struct dxgi_info {
|
|
HMODULE module;
|
|
HWND hwnd;
|
|
IDXGISwapChain *swap;
|
|
};
|
|
|
|
static const IID dxgiFactory2 = {0x50c83a1c,
|
|
0xe072,
|
|
0x4c48,
|
|
{0x87, 0xb0, 0x36, 0x30, 0xfa, 0x36, 0xa6,
|
|
0xd0}};
|
|
|
|
static inline bool dxgi_init(dxgi_info &info)
|
|
{
|
|
HMODULE d3d10_module;
|
|
d3d10create_t create;
|
|
create_fac_t create_factory;
|
|
IDXGIFactory1 *factory;
|
|
IDXGIAdapter1 *adapter;
|
|
IUnknown *device;
|
|
HRESULT hr;
|
|
|
|
info.hwnd = CreateWindowExA(0, DUMMY_WNDCLASS,
|
|
"d3d10 get-offset window", WS_POPUP, 0, 0,
|
|
2, 2, nullptr, nullptr,
|
|
GetModuleHandleA(nullptr), nullptr);
|
|
if (!info.hwnd) {
|
|
return false;
|
|
}
|
|
|
|
info.module = LoadLibraryA("dxgi.dll");
|
|
if (!info.module) {
|
|
return false;
|
|
}
|
|
|
|
create_factory =
|
|
(create_fac_t)GetProcAddress(info.module, "CreateDXGIFactory1");
|
|
|
|
d3d10_module = LoadLibraryA("d3d10.dll");
|
|
if (!d3d10_module) {
|
|
return false;
|
|
}
|
|
|
|
create = (d3d10create_t)GetProcAddress(d3d10_module,
|
|
"D3D10CreateDeviceAndSwapChain");
|
|
if (!create) {
|
|
return false;
|
|
}
|
|
|
|
IID factory_iid = IsWindows8OrGreater() ? dxgiFactory2
|
|
: __uuidof(IDXGIFactory1);
|
|
|
|
hr = create_factory(&factory_iid, (void **)&factory);
|
|
if (FAILED(hr)) {
|
|
return false;
|
|
}
|
|
|
|
hr = factory->EnumAdapters1(0, &adapter);
|
|
factory->Release();
|
|
if (FAILED(hr)) {
|
|
return false;
|
|
}
|
|
|
|
DXGI_SWAP_CHAIN_DESC desc = {};
|
|
desc.BufferCount = 2;
|
|
desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
|
desc.BufferDesc.Width = 2;
|
|
desc.BufferDesc.Height = 2;
|
|
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
|
desc.OutputWindow = info.hwnd;
|
|
desc.SampleDesc.Count = 1;
|
|
desc.Windowed = true;
|
|
|
|
hr = create(adapter, D3D10_DRIVER_TYPE_HARDWARE, nullptr, 0,
|
|
D3D10_SDK_VERSION, &desc, &info.swap, &device);
|
|
adapter->Release();
|
|
if (FAILED(hr)) {
|
|
return false;
|
|
}
|
|
|
|
device->Release();
|
|
return true;
|
|
}
|
|
|
|
static inline void dxgi_free(dxgi_info &info)
|
|
{
|
|
if (info.swap)
|
|
info.swap->Release();
|
|
if (info.hwnd)
|
|
DestroyWindow(info.hwnd);
|
|
}
|
|
|
|
void get_dxgi_offsets(struct dxgi_offsets *offsets)
|
|
{
|
|
dxgi_info info = {};
|
|
bool success = dxgi_init(info);
|
|
HRESULT hr;
|
|
|
|
if (success) {
|
|
offsets->present = vtable_offset(info.module, info.swap, 8);
|
|
offsets->resize = vtable_offset(info.module, info.swap, 13);
|
|
|
|
IDXGISwapChain1 *swap1;
|
|
hr = info.swap->QueryInterface(__uuidof(IDXGISwapChain1),
|
|
(void **)&swap1);
|
|
if (SUCCEEDED(hr)) {
|
|
offsets->present1 =
|
|
vtable_offset(info.module, swap1, 22);
|
|
swap1->Release();
|
|
}
|
|
}
|
|
|
|
dxgi_free(info);
|
|
}
|