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 |