| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "gpu/config/gpu_info_collector.h" | 5 #include "gpu/config/gpu_info_collector.h" |
| 6 | 6 |
| 7 // This has to be included before windows.h. | 7 // This has to be included before windows.h. |
| 8 #include "third_party/re2/re2/re2.h" | 8 #include "third_party/re2/re2/re2.h" |
| 9 | 9 |
| 10 #include <windows.h> | 10 #include <windows.h> |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 | 203 |
| 204 if (key.OpenKey(L"Lenovo", KEY_READ | KEY_WOW64_64KEY)) | 204 if (key.OpenKey(L"Lenovo", KEY_READ | KEY_WOW64_64KEY)) |
| 205 return false; | 205 return false; |
| 206 | 206 |
| 207 if (key.OpenKey(L"Lenovo dCute", KEY_READ | KEY_WOW64_64KEY)) | 207 if (key.OpenKey(L"Lenovo dCute", KEY_READ | KEY_WOW64_64KEY)) |
| 208 return false; | 208 return false; |
| 209 | 209 |
| 210 return true; | 210 return true; |
| 211 } | 211 } |
| 212 | 212 |
| 213 // Determines whether D3D11 won't work, either because it is not supported on | |
| 214 // the machine or because it is known it is likely to crash. | |
| 215 bool D3D11ShouldWork(const GPUInfo& gpu_info) { | |
| 216 // TODO(apatrick): This is a temporary change to see what impact disabling | |
| 217 // D3D11 stats collection has on Canary. | |
| 218 #if 1 | |
| 219 return false; | |
| 220 #else | |
| 221 // Windows XP never supports D3D11. It seems to be less stable that D3D9 on | |
| 222 // Vista. | |
| 223 if (base::win::GetVersion() <= base::win::VERSION_VISTA) | |
| 224 return false; | |
| 225 | |
| 226 // http://crbug.com/175525. | |
| 227 if (gpu_info.display_link_version.IsValid()) | |
| 228 return false; | |
| 229 | |
| 230 return true; | |
| 231 #endif | |
| 232 } | |
| 233 | |
| 234 // Collects information about the level of D3D11 support and records it in | |
| 235 // the UMA stats. Records no stats when D3D11 in not supported at all. | |
| 236 void CollectD3D11SupportOnWorkerThread() { | |
| 237 TRACE_EVENT0("gpu", "CollectD3D11Support"); | |
| 238 | |
| 239 typedef HRESULT (WINAPI *D3D11CreateDeviceFunc)( | |
| 240 IDXGIAdapter* adapter, | |
| 241 D3D_DRIVER_TYPE driver_type, | |
| 242 HMODULE software, | |
| 243 UINT flags, | |
| 244 const D3D_FEATURE_LEVEL* feature_levels, | |
| 245 UINT num_feature_levels, | |
| 246 UINT sdk_version, | |
| 247 ID3D11Device** device, | |
| 248 D3D_FEATURE_LEVEL* feature_level, | |
| 249 ID3D11DeviceContext** immediate_context); | |
| 250 | |
| 251 // This enumeration must be kept in sync with histograms.xml. Do not reorder | |
| 252 // the members; always add to the end. | |
| 253 enum FeatureLevel { | |
| 254 FEATURE_LEVEL_UNKNOWN, | |
| 255 FEATURE_LEVEL_NO_D3D11_DLL, | |
| 256 FEATURE_LEVEL_NO_CREATE_DEVICE_ENTRY_POINT, | |
| 257 FEATURE_LEVEL_DEVICE_CREATION_FAILED, | |
| 258 FEATURE_LEVEL_9_1, | |
| 259 FEATURE_LEVEL_9_2, | |
| 260 FEATURE_LEVEL_9_3, | |
| 261 FEATURE_LEVEL_10_0, | |
| 262 FEATURE_LEVEL_10_1, | |
| 263 FEATURE_LEVEL_11_0, | |
| 264 NUM_FEATURE_LEVELS | |
| 265 }; | |
| 266 | |
| 267 FeatureLevel feature_level = FEATURE_LEVEL_UNKNOWN; | |
| 268 UINT bgra_support = 0; | |
| 269 | |
| 270 // This module is leaked in case it is hooked by third party software. | |
| 271 base::NativeLibrary d3d11_module = base::LoadNativeLibrary( | |
| 272 base::FilePath(L"d3d11.dll"), | |
| 273 NULL); | |
| 274 | |
| 275 if (!d3d11_module) { | |
| 276 feature_level = FEATURE_LEVEL_NO_D3D11_DLL; | |
| 277 } else { | |
| 278 D3D11CreateDeviceFunc create_func = | |
| 279 reinterpret_cast<D3D11CreateDeviceFunc>( | |
| 280 base::GetFunctionPointerFromNativeLibrary(d3d11_module, | |
| 281 "D3D11CreateDevice")); | |
| 282 if (!create_func) { | |
| 283 feature_level = FEATURE_LEVEL_NO_CREATE_DEVICE_ENTRY_POINT; | |
| 284 } else { | |
| 285 static const D3D_FEATURE_LEVEL d3d_feature_levels[] = { | |
| 286 D3D_FEATURE_LEVEL_11_0, | |
| 287 D3D_FEATURE_LEVEL_10_1, | |
| 288 D3D_FEATURE_LEVEL_10_0, | |
| 289 D3D_FEATURE_LEVEL_9_3, | |
| 290 D3D_FEATURE_LEVEL_9_2, | |
| 291 D3D_FEATURE_LEVEL_9_1 | |
| 292 }; | |
| 293 | |
| 294 base::win::ScopedComPtr<ID3D11Device> device; | |
| 295 D3D_FEATURE_LEVEL d3d_feature_level; | |
| 296 base::win::ScopedComPtr<ID3D11DeviceContext> device_context; | |
| 297 HRESULT hr = create_func(NULL, | |
| 298 D3D_DRIVER_TYPE_HARDWARE, | |
| 299 NULL, | |
| 300 0, | |
| 301 d3d_feature_levels, | |
| 302 arraysize(d3d_feature_levels), | |
| 303 D3D11_SDK_VERSION, | |
| 304 device.Receive(), | |
| 305 &d3d_feature_level, | |
| 306 device_context.Receive()); | |
| 307 if (FAILED(hr)) { | |
| 308 feature_level = FEATURE_LEVEL_DEVICE_CREATION_FAILED; | |
| 309 } else { | |
| 310 switch (d3d_feature_level) { | |
| 311 case D3D_FEATURE_LEVEL_11_0: | |
| 312 feature_level = FEATURE_LEVEL_11_0; | |
| 313 break; | |
| 314 case D3D_FEATURE_LEVEL_10_1: | |
| 315 feature_level = FEATURE_LEVEL_10_1; | |
| 316 break; | |
| 317 case D3D_FEATURE_LEVEL_10_0: | |
| 318 feature_level = FEATURE_LEVEL_10_0; | |
| 319 break; | |
| 320 case D3D_FEATURE_LEVEL_9_3: | |
| 321 feature_level = FEATURE_LEVEL_9_3; | |
| 322 break; | |
| 323 case D3D_FEATURE_LEVEL_9_2: | |
| 324 feature_level = FEATURE_LEVEL_9_2; | |
| 325 break; | |
| 326 case D3D_FEATURE_LEVEL_9_1: | |
| 327 feature_level = FEATURE_LEVEL_9_1; | |
| 328 break; | |
| 329 default: | |
| 330 NOTREACHED(); | |
| 331 break; | |
| 332 } | |
| 333 | |
| 334 hr = device->CheckFormatSupport(DXGI_FORMAT_B8G8R8A8_UNORM, | |
| 335 &bgra_support); | |
| 336 DCHECK(SUCCEEDED(hr)); | |
| 337 } | |
| 338 } | |
| 339 } | |
| 340 | |
| 341 UMA_HISTOGRAM_ENUMERATION("GPU.D3D11_FeatureLevel", | |
| 342 feature_level, | |
| 343 NUM_FEATURE_LEVELS); | |
| 344 | |
| 345 // ANGLE requires at least feature level 10.0. Do not record any further | |
| 346 // stats if ANGLE would not work anyway. | |
| 347 if (feature_level < FEATURE_LEVEL_10_0) | |
| 348 return; | |
| 349 | |
| 350 UMA_HISTOGRAM_BOOLEAN( | |
| 351 "GPU.D3D11_B8G8R8A8_Texture2DSupport", | |
| 352 (bgra_support & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0); | |
| 353 UMA_HISTOGRAM_BOOLEAN( | |
| 354 "GPU.D3D11_B8G8R8A8_RenderTargetSupport", | |
| 355 (bgra_support & D3D11_FORMAT_SUPPORT_RENDER_TARGET) != 0); | |
| 356 } | |
| 357 | |
| 358 // Collects information about the level of D3D11 support and records it in | |
| 359 // the UMA stats. Records no stats when D3D11 in not supported at all. | |
| 360 void CollectD3D11Support() { | |
| 361 // D3D11 takes about 50ms to initialize so do this on a worker thread. | |
| 362 base::WorkerPool::PostTask( | |
| 363 FROM_HERE, | |
| 364 base::Bind(CollectD3D11SupportOnWorkerThread), | |
| 365 false); | |
| 366 } | |
| 367 | |
| 368 void DeviceIDToVendorAndDevice(const std::wstring& id, | 213 void DeviceIDToVendorAndDevice(const std::wstring& id, |
| 369 uint32* vendor_id, | 214 uint32* vendor_id, |
| 370 uint32* device_id) { | 215 uint32* device_id) { |
| 371 *vendor_id = 0; | 216 *vendor_id = 0; |
| 372 *device_id = 0; | 217 *device_id = 0; |
| 373 if (id.length() < 21) | 218 if (id.length() < 21) |
| 374 return; | 219 return; |
| 375 base::string16 vendor_id_string = id.substr(8, 4); | 220 base::string16 vendor_id_string = id.substr(8, 4); |
| 376 base::string16 device_id_string = id.substr(17, 4); | 221 base::string16 device_id_string = id.substr(17, 4); |
| 377 int vendor = 0; | 222 int vendor = 0; |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 701 } | 546 } |
| 702 | 547 |
| 703 DeviceIDToVendorAndDevice(id, &gpu_info->gpu.vendor_id, | 548 DeviceIDToVendorAndDevice(id, &gpu_info->gpu.vendor_id, |
| 704 &gpu_info->gpu.device_id); | 549 &gpu_info->gpu.device_id); |
| 705 // TODO(zmo): we only need to call CollectDriverInfoD3D() if we use ANGLE. | 550 // TODO(zmo): we only need to call CollectDriverInfoD3D() if we use ANGLE. |
| 706 if (!CollectDriverInfoD3D(id, gpu_info)) { | 551 if (!CollectDriverInfoD3D(id, gpu_info)) { |
| 707 gpu_info->basic_info_state = kCollectInfoNonFatalFailure; | 552 gpu_info->basic_info_state = kCollectInfoNonFatalFailure; |
| 708 return kCollectInfoNonFatalFailure; | 553 return kCollectInfoNonFatalFailure; |
| 709 } | 554 } |
| 710 | 555 |
| 711 // Collect basic information about supported D3D11 features. Delay for 45 | |
| 712 // seconds so as not to regress performance tests. | |
| 713 if (D3D11ShouldWork(*gpu_info)) { | |
| 714 // This is on a field trial so we can turn it off easily if it blows up | |
| 715 // again in stable channel. | |
| 716 scoped_refptr<base::FieldTrial> trial( | |
| 717 base::FieldTrialList::FactoryGetFieldTrial( | |
| 718 "D3D11Experiment", 100, "Disabled", 2015, 7, 8, | |
| 719 base::FieldTrial::SESSION_RANDOMIZED, NULL)); | |
| 720 const int enabled_group = | |
| 721 trial->AppendGroup("Enabled", 0); | |
| 722 | |
| 723 if (trial->group() == enabled_group) { | |
| 724 base::MessageLoop::current()->PostDelayedTask( | |
| 725 FROM_HERE, | |
| 726 base::Bind(&CollectD3D11Support), | |
| 727 base::TimeDelta::FromSeconds(45)); | |
| 728 } | |
| 729 } | |
| 730 | |
| 731 gpu_info->basic_info_state = kCollectInfoSuccess; | 556 gpu_info->basic_info_state = kCollectInfoSuccess; |
| 732 return kCollectInfoSuccess; | 557 return kCollectInfoSuccess; |
| 733 } | 558 } |
| 734 | 559 |
| 735 CollectInfoResult CollectDriverInfoGL(GPUInfo* gpu_info) { | 560 CollectInfoResult CollectDriverInfoGL(GPUInfo* gpu_info) { |
| 736 TRACE_EVENT0("gpu", "CollectDriverInfoGL"); | 561 TRACE_EVENT0("gpu", "CollectDriverInfoGL"); |
| 737 | 562 |
| 738 if (!gpu_info->driver_version.empty()) | 563 if (!gpu_info->driver_version.empty()) |
| 739 return kCollectInfoSuccess; | 564 return kCollectInfoSuccess; |
| 740 | 565 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 790 shader_model, | 615 shader_model, |
| 791 NUM_SHADER_MODELS); | 616 NUM_SHADER_MODELS); |
| 792 } | 617 } |
| 793 | 618 |
| 794 MergeGPUInfoGL(basic_gpu_info, context_gpu_info); | 619 MergeGPUInfoGL(basic_gpu_info, context_gpu_info); |
| 795 | 620 |
| 796 basic_gpu_info->dx_diagnostics = context_gpu_info.dx_diagnostics; | 621 basic_gpu_info->dx_diagnostics = context_gpu_info.dx_diagnostics; |
| 797 } | 622 } |
| 798 | 623 |
| 799 } // namespace gpu | 624 } // namespace gpu |
| OLD | NEW |