HRESULT InitializeD3DEx(HWND hWnd, D3DPRESENT_PARAMETERS d3dpp, IDirect3D9*& d3d, IDirect3DDevice9*& d3dDevice, D3DEXCreateFn createFn ) { d3d = NULL; d3dDevice = NULL; IDirect3D9Ex* d3dEx = NULL; // initialize Direct3D using the Ex function HRESULT result = createFn( D3D_SDK_VERSION, &d3dEx ); if ( FAILED( result ) ) return result; result = d3dEx->QueryInterface(__uuidof(IDirect3D9), reinterpret_cast<void **>(&d3d) ); if ( FAILED( result ) ) { d3dEx->Release(); return result; } // determine what type of vertex processing to use based on the device capabilities DWORD dwVertexProcessing = GetVertexProcessingCaps(d3d); // create the D3D device using the Ex function IDirect3DDevice9Ex* deviceEx = NULL; result = d3dEx->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, dwVertexProcessing | D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE, &d3dpp, NULL, &deviceEx); if ( FAILED(result) ) { d3dEx->Release(); d3d->Release(); return result; } // obtain the standard D3D device interface deviceEx->QueryInterface(__uuidof(IDirect3DDevice9), reinterpret_cast<void **>(&d3dDevice) ); deviceEx->Release(); d3dEx->Release(); return 0; }
static HRESULT __stdcall myCreateDeviceEx(IDirect3D9Ex * id3d, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS *pPresentationParameters, D3DDISPLAYMODEEX* pFullscreenDisplayMode, IDirect3DDevice9Ex** ppReturnedDeviceInterface) { Mutex m; ods("D3D9: Chaining CreateDeviceEx"); // BehaviorFlags &= ~D3DCREATE_PUREDEVICE; //TODO: Move logic to HardHook. // Call base without active hook in case of no trampoline. CreateDeviceExType oCreateDeviceEx = (CreateDeviceExType) hhCreateDeviceEx.call; hhCreateDeviceEx.restore(); HRESULT hr = oCreateDeviceEx(id3d, Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, pFullscreenDisplayMode, ppReturnedDeviceInterface); hhCreateDeviceEx.inject(); if (FAILED(hr)) return hr; IDirect3DDevice9Ex *idd = *ppReturnedDeviceInterface; DevState *ds = new DevState; ds->dev = idd; idd->AddRef(); ds->initRefCount = idd->Release(); devMap[idd] = ds; // The offsets are dependent on the declaration order of the struct. // See IDirect3DDevice9 (2nd, 3rd, 17th, 18th functions) const unsigned int offsetAddref = 1; const unsigned int offsetRelease = 2; const unsigned int offsetReset = 16; const unsigned int offsetPresent = 17; if (bIsWin8) { hhAddRef.setupInterface(idd, offsetAddref, reinterpret_cast<voidFunc>(myWin8AddRef)); hhRelease.setupInterface(idd, offsetRelease, reinterpret_cast<voidFunc>(myWin8Release)); } else { hhAddRef.setupInterface(idd, offsetAddref, reinterpret_cast<voidFunc>(myAddRef)); hhRelease.setupInterface(idd, offsetRelease, reinterpret_cast<voidFunc>(myRelease)); } hhReset.setupInterface(idd, offsetReset, reinterpret_cast<voidFunc>(myReset)); hhPresent.setupInterface(idd, offsetPresent, reinterpret_cast<voidFunc>(myPresent)); IDirect3DSwapChain9 *pSwap = NULL; idd->GetSwapChain(0, &pSwap); if (pSwap) { // The offset is dependent on the declaration order of the struct. // See IDirect3DSwapChain9 (Present is the fourth function) const unsigned int offsetPresent = 3; hhSwapPresent.setupInterface(pSwap, offsetPresent, reinterpret_cast<voidFunc>(mySwapPresent)); pSwap->Release(); } else { ods("D3D9: Failed to get swapchain for DevEx"); } ds->createCleanState(); return hr; }
static HRESULT __stdcall myCreateDeviceEx(IDirect3D9Ex * id3d, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS *pPresentationParameters, D3DDISPLAYMODEEX* pFullscreenDisplayMode, IDirect3DDevice9Ex** ppReturnedDeviceInterface) { Mutex m; ods("D3D9: Chaining CreateDeviceEx"); // BehaviorFlags &= ~D3DCREATE_PUREDEVICE; CreateDeviceExType oCreateDeviceEx = (CreateDeviceExType) hhCreateDeviceEx.call; hhCreateDeviceEx.restore(); HRESULT hr=oCreateDeviceEx(id3d, Adapter,DeviceType,hFocusWindow,BehaviorFlags,pPresentationParameters,pFullscreenDisplayMode,ppReturnedDeviceInterface); hhCreateDeviceEx.inject(); if (FAILED(hr)) return hr; IDirect3DDevice9Ex *idd = *ppReturnedDeviceInterface; DevState *ds = new DevState; ds->dev = idd; idd->AddRef(); ds->initRefCount = idd->Release(); devMap[idd] = ds; if (bIsWin8) { hhAddRef.setupInterface(idd, 1, reinterpret_cast<voidFunc>(myWin8AddRef)); hhRelease.setupInterface(idd, 2, reinterpret_cast<voidFunc>(myWin8Release)); } else { hhAddRef.setupInterface(idd, 1, reinterpret_cast<voidFunc>(myAddRef)); hhRelease.setupInterface(idd, 2, reinterpret_cast<voidFunc>(myRelease)); } hhReset.setupInterface(idd, 16, reinterpret_cast<voidFunc>(myReset)); hhPresent.setupInterface(idd, 17, reinterpret_cast<voidFunc>(myPresent)); IDirect3DSwapChain9 *pSwap = NULL; idd->GetSwapChain(0, &pSwap); if (pSwap) { hhSwapPresent.setupInterface(pSwap, 3, reinterpret_cast<voidFunc>(mySwapPresent)); pSwap->Release(); } else { ods("D3D9: Failed to get swapchain for DevEx"); } ds->createCleanState(); return hr; }
void D3D9CaptureSetup(IDirect3DDevice9* device) { IDirect3DSwapChain9* swap_chain = NULL; //通过交换链信息来获取相关信息 if (SUCCEEDED(device->GetSwapChain(0, &swap_chain))) { D3DPRESENT_PARAMETERS d3dpp; if (SUCCEEDED(swap_chain->GetPresentParameters(&d3dpp))) { if (d3d9_format != d3dpp.BackBufferFormat || d3d9_captureinfo.oWidth != d3dpp.BackBufferWidth || d3d9_captureinfo.oHeight != d3dpp.BackBufferHeight || reinterpret_cast<HWND>(d3d9_captureinfo.sNative) != d3dpp.hDeviceWindow) { //todo printf prsents info d3d11_format = ConverDXGIFormat(d3dpp.BackBufferFormat); d3d9_format = d3dpp.BackBufferFormat; d3d9_captureinfo.oWidth = d3dpp.BackBufferWidth; d3d9_captureinfo.oHeight = d3dpp.BackBufferHeight; d3d9_captureinfo.sNative = reinterpret_cast<unsigned __int64>(d3dpp.hDeviceWindow); d3d9_captureinfo.Reserved1 = ConvertFormat(d3dpp.BackBufferFormat); d3d9_captureinfo.Flip = 0; } } else logstream << "Don't have enough infomation to hook(failed to get present params)" << std::endl; //todo D3D9EX/PresentEx IDirect3DDevice9Ex* deviceEx = NULL; if (d3d9ex_support && SUCCEEDED(device->QueryInterface(__uuidof(IDirect3DDevice9Ex), reinterpret_cast<void**>(&deviceEx)))) { presentex.Do(h3d::GetVirtual(device, D3D9PRESENTEX_OFFSET), (h3d::WINAPIPROC)PresentEx); resetex.Do(h3d::GetVirtual(device, D3D9RESETEX_OFFSET), (h3d::WINAPIPROC)ResetEx); deviceEx->Release(); } present.Do(h3d::GetVirtual(device, D3D9PRESENT_OFFSET), (h3d::WINAPIPROC)Present); reset.Do(h3d::GetVirtual(device, D3D9RESET_OFFSET), (h3d::WINAPIPROC)Reset); swap_present.Do(h3d::GetVirtual(swap_chain, SWAPCHAINPRESENT_OFFSET), (h3d::WINAPIPROC)SwapPresent); swap_chain->Release(); logstream << "D3D9Capture Succesfully Set Up D3D9 HOOKS" << std::endl; } else logstream << "D3D9Capture Faild to get SwapCahin to initialize hooks" << std::endl; }
// Set required graphics adapter for output bool spoutDirectX::SetAdapter(int index) { char adaptername[128]; IDXGIAdapter* pAdapter = nullptr; g_AdapterIndex = D3DADAPTER_DEFAULT; // DX9 g_pAdapterDX11 = nullptr; // DX11 // Reset if(index == -1) { return true; } // printf("spoutDirectX::SetAdapter(%d)\n", index); // Is the requested adapter available if(index > GetNumAdapters()-1) { // printf("Index greater than number of adapters\n"); return false; } if(!GetAdapterName(index, adaptername, 128)) { // printf("Incompatible adapter\n"); return false; } // Set the global adapter pointer for DX11 pAdapter = GetAdapterPointer(index); if(pAdapter == nullptr) { // printf("Could not get pointer for adapter %d\n", index); return false; } // Set the global adapter pointer for DX11 g_pAdapterDX11 = pAdapter; // Set the global adapter index for DX9 g_AdapterIndex = index; // LJ DEBUG - in case of incompatibility - test everything here // 2.005 what is the directX mode ? DWORD dwDX9 = 0; ReadDwordFromRegistry(&dwDX9, "Software\\Leading Edge\\Spout", "DX9"); if(dwDX9 == 1) { // Try to create a DX9 object and device IDirect3D9Ex* pD3D; // DX9 object IDirect3DDevice9Ex* pDevice; // DX9 device pD3D = CreateDX9object(); if(pD3D == NULL) { // printf("SetAdapter - could not create DX9 object\n"); g_AdapterIndex = D3DADAPTER_DEFAULT; // DX9 g_pAdapterDX11 = nullptr; // DX11 return false; } pDevice = CreateDX9device(pD3D, NULL); if(pDevice == NULL) { // printf("SetAdapter - could not create DX9 device\n"); pD3D->Release(); g_AdapterIndex = D3DADAPTER_DEFAULT; // DX9 g_pAdapterDX11 = nullptr; // DX11 return false; } pD3D->Release(); pDevice->Release(); // printf("SetAdapter - created DX9 device OK\n"); } else { // Try to create a DirectX 11 device ID3D11Device* pd3dDevice; pd3dDevice = CreateDX11device(); if(pd3dDevice == NULL) { // printf("SetAdapter - could not create DX11 device\n"); // Close it because not initialized yet and is just a test pd3dDevice->Release(); g_AdapterIndex = D3DADAPTER_DEFAULT; // DX9 g_pAdapterDX11 = nullptr; // DX11 return false; } // printf("SetAdapter - created DX11 device OK\n"); } return true; }
static bool manually_get_d3d9_addrs(HMODULE d3d9_module, void **present_addr, void **present_ex_addr, void **present_swap_addr) { d3d9create_ex_t create_ex; D3DPRESENT_PARAMETERS pp; HRESULT hr; IDirect3DDevice9Ex *device; IDirect3D9Ex *d3d9ex; hlog("D3D9 values invalid, manually obtaining"); create_ex = (d3d9create_ex_t)GetProcAddress(d3d9_module, "Direct3DCreate9Ex"); if (!create_ex) { hlog("Failed to load Direct3DCreate9Ex"); return false; } if (FAILED(create_ex(D3D_SDK_VERSION, &d3d9ex))) { hlog("Failed to create D3D9 context"); return false; } memset(&pp, 0, sizeof(pp)); pp.Windowed = 1; pp.SwapEffect = D3DSWAPEFFECT_FLIP; pp.BackBufferFormat = D3DFMT_A8R8G8B8; pp.BackBufferCount = 1; pp.hDeviceWindow = (HWND)dummy_window; pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; hr = d3d9ex->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, dummy_window, D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_NOWINDOWCHANGES, &pp, NULL, &device); d3d9ex->Release(); if (SUCCEEDED(hr)) { uintptr_t *vtable = *(uintptr_t**)device; IDirect3DSwapChain9 *swap; *present_addr = (void*)vtable[17]; *present_ex_addr = (void*)vtable[121]; hr = device->GetSwapChain(0, &swap); if (SUCCEEDED(hr)) { vtable = *(uintptr_t**)swap; *present_swap_addr = (void*)vtable[3]; swap->Release(); } device->Release(); } else { hlog("Failed to create D3D9 device"); return false; } return true; }