blob: 9d9125c271a213d9c0d7ab297ff1b82f41b7b9ea [file] [log] [blame]
[email protected]623c0bd2011-03-12 01:00:411// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]81f85b32010-10-08 18:03:212// 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
[email protected]81f85b32010-10-08 18:03:2112#include "base/string_number_conversions.h"
13#include "base/utf_string_conversions.h"
[email protected]623c0bd2011-03-12 01:00:4114#include "content/gpu/gpu_info_collector.h"
[email protected]81f85b32010-10-08 18:03:2115
[email protected]99ff9932011-09-07 14:14:5416// Functions in this file depend on functions exported from dxguid.dll.
17#pragma comment(lib, "dxguid.lib")
18
[email protected]81f85b32010-10-08 18:03:2119namespace {
20
21// Traverses the IDxDiagContainer tree and populates a tree of DxDiagNode
22// structures that contains property name / value pairs and subtrees of DirectX
23// diagnostic information.
24void RecurseDiagnosticTree(DxDiagNode* output,
[email protected]206c5b02010-10-11 19:54:4425 IDxDiagContainer* container,
26 int depth) {
[email protected]81f85b32010-10-08 18:03:2127 HRESULT hr;
28
29 VARIANT variant;
30 VariantInit(&variant);
31
32 DWORD prop_count;
33 hr = container->GetNumberOfProps(&prop_count);
34 if (SUCCEEDED(hr)) {
35 for (DWORD i = 0; i < prop_count; i++) {
36 WCHAR prop_name16[256];
37 hr = container->EnumPropNames(i, prop_name16, arraysize(prop_name16));
38 if (SUCCEEDED(hr)) {
39 std::string prop_name8 = WideToUTF8(prop_name16);
40
41 hr = container->GetProp(prop_name16, &variant);
42 if (SUCCEEDED(hr)) {
43 switch (variant.vt) {
44 case VT_UI4:
45 output->values[prop_name8] = base::UintToString(variant.ulVal);
46 break;
47 case VT_I4:
48 output->values[prop_name8] = base::IntToString(variant.lVal);
49 break;
50 case VT_BOOL:
51 output->values[prop_name8] = variant.boolVal ? "true" : "false";
52 break;
53 case VT_BSTR:
54 output->values[prop_name8] = WideToUTF8(variant.bstrVal);
55 break;
56 default:
57 break;
58 }
59
60 // Clear the variant (this is needed to free BSTR memory).
61 VariantClear(&variant);
62 }
63 }
64 }
65 }
66
[email protected]206c5b02010-10-11 19:54:4467 if (depth > 0) {
68 DWORD child_count;
69 hr = container->GetNumberOfChildContainers(&child_count);
70 if (SUCCEEDED(hr)) {
71 for (DWORD i = 0; i < child_count; i++) {
72 WCHAR child_name16[256];
73 hr = container->EnumChildContainerNames(i,
74 child_name16,
75 arraysize(child_name16));
[email protected]81f85b32010-10-08 18:03:2176 if (SUCCEEDED(hr)) {
[email protected]206c5b02010-10-11 19:54:4477 std::string child_name8 = WideToUTF8(child_name16);
78 DxDiagNode* output_child =
79 &output->children[child_name8];
[email protected]81f85b32010-10-08 18:03:2180
[email protected]206c5b02010-10-11 19:54:4481 IDxDiagContainer* child_container = NULL;
82 hr = container->GetChildContainer(child_name16, &child_container);
83 if (SUCCEEDED(hr)) {
84 RecurseDiagnosticTree(output_child, child_container, depth - 1);
85
86 child_container->Release();
87 }
[email protected]81f85b32010-10-08 18:03:2188 }
89 }
90 }
91 }
92}
93} // namespace anonymous
94
95namespace gpu_info_collector {
96
97bool GetDxDiagnostics(DxDiagNode* output) {
98 HRESULT hr;
99 bool success = false;
100
101 IDxDiagProvider* provider = NULL;
102 hr = CoCreateInstance(CLSID_DxDiagProvider,
103 NULL,
104 CLSCTX_INPROC_SERVER,
105 IID_IDxDiagProvider,
106 reinterpret_cast<void**>(&provider));
107 if (SUCCEEDED(hr)) {
108 DXDIAG_INIT_PARAMS params = { sizeof(params) };
109 params.dwDxDiagHeaderVersion = DXDIAG_DX9_SDK_VERSION;
110 params.bAllowWHQLChecks = FALSE;
111 params.pReserved = NULL;
112
113 hr = provider->Initialize(&params);
114 if (SUCCEEDED(hr)) {
115 IDxDiagContainer* root = NULL;
116 hr = provider->GetRootContainer(&root);
117 if (SUCCEEDED(hr)) {
118 // Limit to the DisplayDevices subtree. The tree in its entirity is
119 // enormous and only this branch contains useful information.
120 IDxDiagContainer* display_devices = NULL;
121 hr = root->GetChildContainer(L"DxDiag_DisplayDevices",
122 &display_devices);
123 if (SUCCEEDED(hr)) {
[email protected]206c5b02010-10-11 19:54:44124 RecurseDiagnosticTree(output, display_devices, 1);
[email protected]81f85b32010-10-08 18:03:21125 success = true;
126 display_devices->Release();
127 }
128
129 root->Release();
130 }
131 }
132 provider->Release();
133 }
134
135 return success;
136}
137} // namespace gpu_info_collector