1 // Copyright (c) 2011 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.
5 // Functions to enumerate the Dx Diagnostic Tool hierarchy and build up
6 // a tree of nodes with name / value properties.
12 #include "base/string_number_conversions.h"
13 #include "base/utf_string_conversions.h"
14 #include "base/win/scoped_com_initializer.h"
15 #include "content/gpu/gpu_info_collector.h"
17 // Functions in this file depend on functions exported from dxguid.dll.
18 #pragma comment(lib, "dxguid.lib")
22 // Traverses the IDxDiagContainer tree and populates a tree of DxDiagNode
23 // structures that contains property name / value pairs and subtrees of DirectX
24 // diagnostic information.
25 void RecurseDiagnosticTree(content::DxDiagNode
* output
,
26 IDxDiagContainer
* container
,
31 VariantInit(&variant
);
34 hr
= container
->GetNumberOfProps(&prop_count
);
36 for (DWORD i
= 0; i
< prop_count
; i
++) {
37 WCHAR prop_name16
[256];
38 hr
= container
->EnumPropNames(i
, prop_name16
, arraysize(prop_name16
));
40 std::string prop_name8
= WideToUTF8(prop_name16
);
42 hr
= container
->GetProp(prop_name16
, &variant
);
46 output
->values
[prop_name8
] = base::UintToString(variant
.ulVal
);
49 output
->values
[prop_name8
] = base::IntToString(variant
.lVal
);
52 output
->values
[prop_name8
] = variant
.boolVal
? "true" : "false";
55 output
->values
[prop_name8
] = WideToUTF8(variant
.bstrVal
);
61 // Clear the variant (this is needed to free BSTR memory).
62 VariantClear(&variant
);
70 hr
= container
->GetNumberOfChildContainers(&child_count
);
72 for (DWORD i
= 0; i
< child_count
; i
++) {
73 WCHAR child_name16
[256];
74 hr
= container
->EnumChildContainerNames(i
,
76 arraysize(child_name16
));
78 std::string child_name8
= WideToUTF8(child_name16
);
79 content::DxDiagNode
* output_child
=
80 &output
->children
[child_name8
];
82 IDxDiagContainer
* child_container
= NULL
;
83 hr
= container
->GetChildContainer(child_name16
, &child_container
);
85 RecurseDiagnosticTree(output_child
, child_container
, depth
- 1);
87 child_container
->Release();
94 } // namespace anonymous
96 namespace gpu_info_collector
{
98 bool GetDxDiagnostics(content::DxDiagNode
* output
) {
100 bool success
= false;
101 base::win::ScopedCOMInitializer com_initializer
;
103 IDxDiagProvider
* provider
= NULL
;
104 hr
= CoCreateInstance(CLSID_DxDiagProvider
,
106 CLSCTX_INPROC_SERVER
,
108 reinterpret_cast<void**>(&provider
));
110 DXDIAG_INIT_PARAMS params
= { sizeof(params
) };
111 params
.dwDxDiagHeaderVersion
= DXDIAG_DX9_SDK_VERSION
;
112 params
.bAllowWHQLChecks
= FALSE
;
113 params
.pReserved
= NULL
;
115 hr
= provider
->Initialize(¶ms
);
117 IDxDiagContainer
* root
= NULL
;
118 hr
= provider
->GetRootContainer(&root
);
120 // Limit to the DisplayDevices subtree. The tree in its entirity is
121 // enormous and only this branch contains useful information.
122 IDxDiagContainer
* display_devices
= NULL
;
123 hr
= root
->GetChildContainer(L
"DxDiag_DisplayDevices",
126 RecurseDiagnosticTree(output
, display_devices
, 1);
128 display_devices
->Release();
139 } // namespace gpu_info_collector