blob: 8c1960d6eadcd0c8b04d5474fd15b0616c020cda [file] [log] [blame]
[email protected]81f85b32010-10-08 18:03:211// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4//
5// Functions to enumerate the Dx Diagnostic Tool hierarchy and build up
6// a tree of nodes with name / value properties.
7
8#define INITGUID
9#include <dxdiag.h>
10#include <windows.h>
11
12#include "chrome/gpu/gpu_info_collector.h"
13
14#include "base/string_number_conversions.h"
15#include "base/utf_string_conversions.h"
16
17namespace {
18
19// Traverses the IDxDiagContainer tree and populates a tree of DxDiagNode
20// structures that contains property name / value pairs and subtrees of DirectX
21// diagnostic information.
22void RecurseDiagnosticTree(DxDiagNode* output,
[email protected]206c5b02010-10-11 19:54:4423 IDxDiagContainer* container,
24 int depth) {
[email protected]81f85b32010-10-08 18:03:2125 HRESULT hr;
26
27 VARIANT variant;
28 VariantInit(&variant);
29
30 DWORD prop_count;
31 hr = container->GetNumberOfProps(&prop_count);
32 if (SUCCEEDED(hr)) {
33 for (DWORD i = 0; i < prop_count; i++) {
34 WCHAR prop_name16[256];
35 hr = container->EnumPropNames(i, prop_name16, arraysize(prop_name16));
36 if (SUCCEEDED(hr)) {
37 std::string prop_name8 = WideToUTF8(prop_name16);
38
39 hr = container->GetProp(prop_name16, &variant);
40 if (SUCCEEDED(hr)) {
41 switch (variant.vt) {
42 case VT_UI4:
43 output->values[prop_name8] = base::UintToString(variant.ulVal);
44 break;
45 case VT_I4:
46 output->values[prop_name8] = base::IntToString(variant.lVal);
47 break;
48 case VT_BOOL:
49 output->values[prop_name8] = variant.boolVal ? "true" : "false";
50 break;
51 case VT_BSTR:
52 output->values[prop_name8] = WideToUTF8(variant.bstrVal);
53 break;
54 default:
55 break;
56 }
57
58 // Clear the variant (this is needed to free BSTR memory).
59 VariantClear(&variant);
60 }
61 }
62 }
63 }
64
[email protected]206c5b02010-10-11 19:54:4465 if (depth > 0) {
66 DWORD child_count;
67 hr = container->GetNumberOfChildContainers(&child_count);
68 if (SUCCEEDED(hr)) {
69 for (DWORD i = 0; i < child_count; i++) {
70 WCHAR child_name16[256];
71 hr = container->EnumChildContainerNames(i,
72 child_name16,
73 arraysize(child_name16));
[email protected]81f85b32010-10-08 18:03:2174 if (SUCCEEDED(hr)) {
[email protected]206c5b02010-10-11 19:54:4475 std::string child_name8 = WideToUTF8(child_name16);
76 DxDiagNode* output_child =
77 &output->children[child_name8];
[email protected]81f85b32010-10-08 18:03:2178
[email protected]206c5b02010-10-11 19:54:4479 IDxDiagContainer* child_container = NULL;
80 hr = container->GetChildContainer(child_name16, &child_container);
81 if (SUCCEEDED(hr)) {
82 RecurseDiagnosticTree(output_child, child_container, depth - 1);
83
84 child_container->Release();
85 }
[email protected]81f85b32010-10-08 18:03:2186 }
87 }
88 }
89 }
90}
91} // namespace anonymous
92
93namespace gpu_info_collector {
94
95bool GetDxDiagnostics(DxDiagNode* output) {
96 HRESULT hr;
97 bool success = false;
98
99 IDxDiagProvider* provider = NULL;
100 hr = CoCreateInstance(CLSID_DxDiagProvider,
101 NULL,
102 CLSCTX_INPROC_SERVER,
103 IID_IDxDiagProvider,
104 reinterpret_cast<void**>(&provider));
105 if (SUCCEEDED(hr)) {
106 DXDIAG_INIT_PARAMS params = { sizeof(params) };
107 params.dwDxDiagHeaderVersion = DXDIAG_DX9_SDK_VERSION;
108 params.bAllowWHQLChecks = FALSE;
109 params.pReserved = NULL;
110
111 hr = provider->Initialize(&params);
112 if (SUCCEEDED(hr)) {
113 IDxDiagContainer* root = NULL;
114 hr = provider->GetRootContainer(&root);
115 if (SUCCEEDED(hr)) {
116 // Limit to the DisplayDevices subtree. The tree in its entirity is
117 // enormous and only this branch contains useful information.
118 IDxDiagContainer* display_devices = NULL;
119 hr = root->GetChildContainer(L"DxDiag_DisplayDevices",
120 &display_devices);
121 if (SUCCEEDED(hr)) {
[email protected]206c5b02010-10-11 19:54:44122 RecurseDiagnosticTree(output, display_devices, 1);
[email protected]81f85b32010-10-08 18:03:21123 success = true;
124 display_devices->Release();
125 }
126
127 root->Release();
128 }
129 }
130 provider->Release();
131 }
132
133 return success;
134}
135} // namespace gpu_info_collector