summaryrefslogtreecommitdiffstats
path: root/chrome/gpu/gpu_dx_diagnostics_win.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/gpu/gpu_dx_diagnostics_win.cc')
-rw-r--r--chrome/gpu/gpu_dx_diagnostics_win.cc132
1 files changed, 132 insertions, 0 deletions
diff --git a/chrome/gpu/gpu_dx_diagnostics_win.cc b/chrome/gpu/gpu_dx_diagnostics_win.cc
new file mode 100644
index 0000000..f6ee3c0
--- /dev/null
+++ b/chrome/gpu/gpu_dx_diagnostics_win.cc
@@ -0,0 +1,132 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Functions to enumerate the Dx Diagnostic Tool hierarchy and build up
+// a tree of nodes with name / value properties.
+
+#define INITGUID
+#include <dxdiag.h>
+#include <windows.h>
+
+#include "chrome/gpu/gpu_info_collector.h"
+
+#include "base/string_number_conversions.h"
+#include "base/utf_string_conversions.h"
+
+namespace {
+
+// Traverses the IDxDiagContainer tree and populates a tree of DxDiagNode
+// structures that contains property name / value pairs and subtrees of DirectX
+// diagnostic information.
+void RecurseDiagnosticTree(DxDiagNode* output,
+ IDxDiagContainer* container) {
+ HRESULT hr;
+
+ VARIANT variant;
+ VariantInit(&variant);
+
+ DWORD prop_count;
+ hr = container->GetNumberOfProps(&prop_count);
+ if (SUCCEEDED(hr)) {
+ for (DWORD i = 0; i < prop_count; i++) {
+ WCHAR prop_name16[256];
+ hr = container->EnumPropNames(i, prop_name16, arraysize(prop_name16));
+ if (SUCCEEDED(hr)) {
+ std::string prop_name8 = WideToUTF8(prop_name16);
+
+ hr = container->GetProp(prop_name16, &variant);
+ if (SUCCEEDED(hr)) {
+ switch (variant.vt) {
+ case VT_UI4:
+ output->values[prop_name8] = base::UintToString(variant.ulVal);
+ break;
+ case VT_I4:
+ output->values[prop_name8] = base::IntToString(variant.lVal);
+ break;
+ case VT_BOOL:
+ output->values[prop_name8] = variant.boolVal ? "true" : "false";
+ break;
+ case VT_BSTR:
+ output->values[prop_name8] = WideToUTF8(variant.bstrVal);
+ break;
+ default:
+ break;
+ }
+
+ // Clear the variant (this is needed to free BSTR memory).
+ VariantClear(&variant);
+ }
+ }
+ }
+ }
+
+ DWORD child_count;
+ hr = container->GetNumberOfChildContainers(&child_count);
+ if (SUCCEEDED(hr)) {
+ for (DWORD i = 0; i < child_count; i++) {
+ WCHAR child_name16[256];
+ hr = container->EnumChildContainerNames(i,
+ child_name16,
+ arraysize(child_name16));
+ if (SUCCEEDED(hr)) {
+ std::string child_name8 = WideToUTF8(child_name16);
+ DxDiagNode* output_child =
+ &output->children[child_name8];
+
+ IDxDiagContainer* child_container = NULL;
+ hr = container->GetChildContainer(child_name16, &child_container);
+ if (SUCCEEDED(hr)) {
+ RecurseDiagnosticTree(output_child, child_container);
+
+ child_container->Release();
+ }
+ }
+ }
+ }
+}
+} // namespace anonymous
+
+namespace gpu_info_collector {
+
+bool GetDxDiagnostics(DxDiagNode* output) {
+ HRESULT hr;
+ bool success = false;
+
+ IDxDiagProvider* provider = NULL;
+ hr = CoCreateInstance(CLSID_DxDiagProvider,
+ NULL,
+ CLSCTX_INPROC_SERVER,
+ IID_IDxDiagProvider,
+ reinterpret_cast<void**>(&provider));
+ if (SUCCEEDED(hr)) {
+ DXDIAG_INIT_PARAMS params = { sizeof(params) };
+ params.dwDxDiagHeaderVersion = DXDIAG_DX9_SDK_VERSION;
+ params.bAllowWHQLChecks = FALSE;
+ params.pReserved = NULL;
+
+ hr = provider->Initialize(&params);
+ if (SUCCEEDED(hr)) {
+ IDxDiagContainer* root = NULL;
+ hr = provider->GetRootContainer(&root);
+ if (SUCCEEDED(hr)) {
+ // Limit to the DisplayDevices subtree. The tree in its entirity is
+ // enormous and only this branch contains useful information.
+ IDxDiagContainer* display_devices = NULL;
+ hr = root->GetChildContainer(L"DxDiag_DisplayDevices",
+ &display_devices);
+ if (SUCCEEDED(hr)) {
+ RecurseDiagnosticTree(output, display_devices);
+ success = true;
+ display_devices->Release();
+ }
+
+ root->Release();
+ }
+ }
+ provider->Release();
+ }
+
+ return success;
+}
+} // namespace gpu_info_collector