bool DCGPAProfiler::GetAllComputeCounters(CounterList& counterList) { bool retVal = true; // Loading dxgi.dll has a side effect of initializing Real_CreateDXGIFactory1 LIB_HANDLE hDxgiDll = OSUtils::Instance()->GenericLoadLibrary("dxgi.dll"); if (NULL == hDxgiDll) { retVal = false; } else { if (NULL == Real_CreateDXGIFactory1) { retVal = false; } else { // Make sure this isn't called from DllMain (or a detoured LoadLibrary call) // See this note on MSDN https://msdn.microsoft.com/en-us/library/windows/desktop/bb205075%28v=vs.85%29.aspx#DXGI_Responses_From_DLLMain // DXGI Responses from DLLMain // Because a DllMain function can't guarantee the order in which it loads and unloads DLLs, we recommend that your app's DllMain function not call // Direct3D or DXGI functions or methods, including functions or methods that create or release objects.If your app's DllMain function calls into a // particular component, that component might call another DLL that isn't present on the operating system, which causes the operating system to crash. // Direct3D and DXGI might load a set of DLLs, typically a set of drivers, that differs from computer to computer. Therefore, even if your app doesn’t // crash on your development and test computers when its DllMain function calls Direct3D or DXGI functions or methods, it might crash when it runs on // another computer. // // To prevent you from creating an app that might cause the operating system to crash, DXGI provides the following responses in the specified situations : // If your app's DllMain function releases its last reference to a DXGI factory, DXGI raises an exception. // If your app's DllMain function creates a DXGI factory, DXGI returns an error code. IDXGIFactory* pDxgiFactory = NULL; HRESULT hr = Real_CreateDXGIFactory1(__uuidof(IDXGIFactory), reinterpret_cast<void**>(&pDxgiFactory)); if (S_OK != hr) { retVal = false; } else { typedef std::unordered_set<CounterList::value_type> CounterNames; CounterNames counterNames; CounterList adapterCounters; UINT adapterIndex = 0; while (retVal && (S_OK == hr)) { IDXGIAdapter* pDxgiAdapter = NULL; hr = pDxgiFactory->EnumAdapters(adapterIndex, &pDxgiAdapter); if (S_OK == hr) { DXGI_ADAPTER_DESC adapterDesc; hr = pDxgiAdapter->GetDesc(&adapterDesc); if (S_OK == hr) { GDT_HW_GENERATION hwGen; bool hwGenFound = AMDTDeviceInfoUtils::Instance()->GetHardwareGeneration(adapterDesc.DeviceId, hwGen); if (hwGenFound) { adapterCounters.clear(); m_GPAUtils.GetAvailableCountersGdt(hwGen, adapterCounters); m_GPAUtils.FilterNonComputeCountersGdt(hwGen, adapterCounters); for (CounterList::iterator aci = adapterCounters.begin() ; adapterCounters.end() != aci; ++aci) { if (counterNames.end() == counterNames.find(*aci)) { counterNames.insert(*aci); } } } } pDxgiAdapter->Release(); } ++adapterIndex; } // DXGI_ERROR_NOT_FOUND marks that EnumAdapters reached the last adapter in the system if (DXGI_ERROR_NOT_FOUND != hr) { retVal = false; } else { for (CounterNames::iterator cni = counterNames.begin() ; counterNames.end() != cni ; ++cni) { counterList.push_back(*cni); } } pDxgiFactory->Release(); } } } return retVal; }
counter_ptr addCounter(std::wstring name) { counter_ptr counter = counter_ptr(new PDHCounter(name)); counters_.push_back(counter); return counter; }