OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2009, Google Inc. | 2 * Copyright 2009, Google Inc. |
3 * All rights reserved. | 3 * All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
7 * met: | 7 * met: |
8 * | 8 * |
9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 #include "core/cross/features.h" | 47 #include "core/cross/features.h" |
48 #include "core/cross/types.h" | 48 #include "core/cross/types.h" |
49 #include "core/win/d3d9/buffer_d3d9.h" | 49 #include "core/win/d3d9/buffer_d3d9.h" |
50 #include "core/win/d3d9/d3d_entry_points.h" | 50 #include "core/win/d3d9/d3d_entry_points.h" |
51 #include "core/win/d3d9/draw_element_d3d9.h" | 51 #include "core/win/d3d9/draw_element_d3d9.h" |
52 #include "core/win/d3d9/effect_d3d9.h" | 52 #include "core/win/d3d9/effect_d3d9.h" |
53 #include "core/win/d3d9/param_cache_d3d9.h" | 53 #include "core/win/d3d9/param_cache_d3d9.h" |
54 #include "core/win/d3d9/primitive_d3d9.h" | 54 #include "core/win/d3d9/primitive_d3d9.h" |
55 #include "core/win/d3d9/render_surface_d3d9.h" | 55 #include "core/win/d3d9/render_surface_d3d9.h" |
56 #include "core/win/d3d9/sampler_d3d9.h" | 56 #include "core/win/d3d9/sampler_d3d9.h" |
| 57 #include "core/win/d3d9/software_renderer_d3d9.h" |
57 #include "core/win/d3d9/stream_bank_d3d9.h" | 58 #include "core/win/d3d9/stream_bank_d3d9.h" |
58 #include "core/win/d3d9/texture_d3d9.h" | 59 #include "core/win/d3d9/texture_d3d9.h" |
59 #include "core/win/d3d9/utils_d3d9.h" | 60 #include "core/win/d3d9/utils_d3d9.h" |
60 | 61 |
61 namespace o3d { | 62 namespace o3d { |
62 | 63 |
63 typedef std::vector<Effect*> EffectArray; | 64 typedef std::vector<Effect*> EffectArray; |
64 typedef std::vector<RenderSurfaceBase*> RenderSurfaceBaseArray; | 65 typedef std::vector<RenderSurfaceBase*> RenderSurfaceBaseArray; |
65 typedef std::vector<State*> StateArray; | 66 typedef std::vector<State*> StateArray; |
66 typedef std::vector<Texture*> TextureArray; | 67 typedef std::vector<Texture*> TextureArray; |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 if (!SUCCEEDED(d3d->CheckDeviceFormat(D3DADAPTER_DEFAULT, | 291 if (!SUCCEEDED(d3d->CheckDeviceFormat(D3DADAPTER_DEFAULT, |
291 D3DDEVTYPE_HAL, | 292 D3DDEVTYPE_HAL, |
292 d3d_display_mode.Format, | 293 d3d_display_mode.Format, |
293 D3DUSAGE_DEPTHSTENCIL, | 294 D3DUSAGE_DEPTHSTENCIL, |
294 D3DRTYPE_SURFACE, | 295 D3DRTYPE_SURFACE, |
295 depth_stencil_formats[i]))) { | 296 depth_stencil_formats[i]))) { |
296 LOG(ERROR) << "Device does not support all required texture formats" | 297 LOG(ERROR) << "Device does not support all required texture formats" |
297 << " for depth/stencil buffers."; | 298 << " for depth/stencil buffers."; |
298 return false; | 299 return false; |
299 } | 300 } |
300 } | 301 } |
301 | 302 |
302 return true; | 303 return true; |
303 } | 304 } |
304 | 305 |
305 // Attempt to create a Direct3D9 object supporting the required caps. Return | 306 // Attempt to create a Direct3D9 object supporting the required caps. Return |
306 // NULL if the object cannot be created or if it does not support the caps. | 307 // NULL if the object cannot be created or if it does not support the caps. |
307 Renderer::InitStatus CreateDirect3D(Direct3DCreate9_Ptr d3d_create_function, | 308 Renderer::InitStatus CreateDirect3D(Direct3DCreate9_Ptr d3d_create_function, |
308 LPDIRECT3D9* d3d, | 309 LPDIRECT3D9* d3d, |
309 Features* features) { | 310 Features* features) { |
310 if (!d3d_create_function) { | 311 if (!d3d_create_function) { |
(...skipping 11 matching lines...) Expand all Loading... |
322 *d3d = NULL; | 323 *d3d = NULL; |
323 return Renderer::GPU_NOT_UP_TO_SPEC; | 324 return Renderer::GPU_NOT_UP_TO_SPEC; |
324 } | 325 } |
325 | 326 |
326 return Renderer::SUCCESS; | 327 return Renderer::SUCCESS; |
327 } | 328 } |
328 | 329 |
329 // For certain GPU drivers we need to force anti-aliasing off to avoid a | 330 // For certain GPU drivers we need to force anti-aliasing off to avoid a |
330 // a huge performance hit when certain types of windows are used on the same | 331 // a huge performance hit when certain types of windows are used on the same |
331 // desktop as O3D. This function returns true if O3D is running on one | 332 // desktop as O3D. This function returns true if O3D is running on one |
332 // of these GPUs/Drivers. | 333 // of these GPUs/Drivers. |
333 bool ForceAntiAliasingOff(LPDIRECT3D9* d3d) { | 334 bool ForceAntiAliasingOff(LPDIRECT3D9* d3d) { |
334 D3DADAPTER_IDENTIFIER9 identifier; | 335 D3DADAPTER_IDENTIFIER9 identifier; |
335 HRESULT hr = (*d3d)->GetAdapterIdentifier(D3DADAPTER_DEFAULT, 0, &identifier); | 336 HRESULT hr = (*d3d)->GetAdapterIdentifier(D3DADAPTER_DEFAULT, 0, &identifier); |
336 | 337 |
337 unsigned int vendor_id = identifier.VendorId; | 338 unsigned int vendor_id = identifier.VendorId; |
338 unsigned int device_id = identifier.DeviceId; | 339 unsigned int device_id = identifier.DeviceId; |
339 unsigned int product = HIWORD(identifier.DriverVersion.HighPart); | 340 unsigned int product = HIWORD(identifier.DriverVersion.HighPart); |
340 unsigned int version = LOWORD(identifier.DriverVersion.HighPart); | 341 unsigned int version = LOWORD(identifier.DriverVersion.HighPart); |
341 unsigned int subversion = HIWORD(identifier.DriverVersion.LowPart); | 342 unsigned int subversion = HIWORD(identifier.DriverVersion.LowPart); |
342 unsigned int build = LOWORD(identifier.DriverVersion.LowPart); | 343 unsigned int build = LOWORD(identifier.DriverVersion.LowPart); |
343 | 344 |
344 // Disable ATI drivers 6.14.10.x where x is 6800 or lower. | 345 // Disable ATI drivers 6.14.10.x where x is 6800 or lower. |
345 if (vendor_id == 4098 && // ATI | 346 if (vendor_id == 4098 && // ATI |
346 product == 6 && | 347 product == 6 && |
347 version == 14 && | 348 version == 14 && |
348 subversion == 10 && | 349 subversion == 10 && |
349 build <= 6800) { | 350 build <= 6800) { |
350 return true; | 351 return true; |
351 } | 352 } |
352 | 353 |
353 return false; | 354 return false; |
354 } | 355 } |
355 | 356 |
| 357 namespace { |
| 358 // Returns whether the ForceSoftwareRenderer value of the Software\Google\o3d |
| 359 // key is non-zero. |
| 360 bool IsForceSoftwareRendererEnabled() { |
| 361 HKEY key; |
| 362 if (FAILED(RegOpenKeyEx(HKEY_CURRENT_USER, |
| 363 TEXT("Software\\Google\\o3d"), |
| 364 0, |
| 365 KEY_READ, |
| 366 &key))) { |
| 367 return false; |
| 368 } |
| 369 |
| 370 bool enabled = false; |
| 371 DWORD type; |
| 372 DWORD value; |
| 373 DWORD size = sizeof(value); |
| 374 if (SUCCEEDED(RegQueryValueEx(key, |
| 375 TEXT("ForceSoftwareRenderer"), |
| 376 NULL, |
| 377 &type, |
| 378 reinterpret_cast<LPBYTE>(&value), |
| 379 &size))) { |
| 380 if (type == REG_DWORD && size == sizeof(value) && value) { |
| 381 enabled = true; |
| 382 } |
| 383 } |
| 384 RegCloseKey(key); |
| 385 |
| 386 return enabled; |
| 387 } |
| 388 } |
356 | 389 |
357 // Helper function that gets the D3D Interface, checks the available | 390 // Helper function that gets the D3D Interface, checks the available |
358 // multisampling modes and selects the most advanced one available to create | 391 // multisampling modes and selects the most advanced one available to create |
359 // a D3D Device with a back buffer containing depth and stencil buffers that | 392 // a D3D Device with a back buffer containing depth and stencil buffers that |
360 // match the current display device. | 393 // match the current display device. |
361 Renderer::InitStatus InitializeD3D9Context( | 394 Renderer::InitStatus InitializeD3D9Context( |
362 HWND window, | 395 HWND window, |
363 LPDIRECT3D9* d3d, | 396 LPDIRECT3D9* d3d, |
364 LPDIRECT3DDEVICE9* d3d_device, | 397 LPDIRECT3DDEVICE9* d3d_device, |
365 D3DPRESENT_PARAMETERS* d3d_present_parameters, | 398 D3DPRESENT_PARAMETERS* d3d_present_parameters, |
366 bool fullscreen, | 399 bool fullscreen, |
367 Features* features, | 400 Features* features, |
368 int* out_width, | 401 int* out_width, |
369 int* out_height) { | 402 int* out_height) { |
370 | 403 |
371 // Try the hardware renderer first. | 404 // Check registry to see if the developer has opted to force the software |
372 Renderer::InitStatus status_hardware = CreateDirect3D( | 405 // renderer. |
373 Direct3DCreate9, d3d, features); | 406 Renderer::InitStatus status_hardware; |
| 407 if (IsForceSoftwareRendererEnabled()) { |
| 408 // Simulate GPU not up to spec. |
| 409 status_hardware = Renderer::GPU_NOT_UP_TO_SPEC; |
| 410 } else { |
| 411 // Create a hardware device. |
| 412 status_hardware = CreateDirect3D(Direct3DCreate9, d3d, features); |
| 413 } |
| 414 |
374 if (status_hardware != Renderer::SUCCESS) { | 415 if (status_hardware != Renderer::SUCCESS) { |
375 Renderer::InitStatus status_software = CreateDirect3D( | 416 Renderer::InitStatus status_software = CreateDirect3D( |
376 Direct3DCreate9Software, d3d, features); | 417 Direct3DCreate9Software, d3d, features); |
377 | 418 |
378 // We should not be requiring caps that are not supported by the software | 419 // We should not be requiring caps that are not supported by the software |
379 // renderer. | 420 // renderer. |
380 DCHECK(status_software != Renderer::GPU_NOT_UP_TO_SPEC); | 421 DCHECK(status_software != Renderer::GPU_NOT_UP_TO_SPEC); |
381 | 422 |
382 if (status_software != Renderer::SUCCESS) { | 423 if (status_software != Renderer::SUCCESS) { |
383 // Report the hardware error. An error with the software renderer should | 424 // Report the hardware error. An error with the software renderer should |
384 // only mean that it is not available, which is normal. | 425 // only mean that it is not available, which is normal. |
385 if (status_hardware == Renderer::INITIALIZATION_ERROR) { | 426 if (status_hardware == Renderer::INITIALIZATION_ERROR) { |
386 LOG(ERROR) << "Failed to create the initial D3D9 Interface"; | 427 LOG(ERROR) << "Failed to create the initial D3D9 Interface"; |
387 } | 428 } |
388 return status_hardware; | 429 return status_hardware; |
389 } | 430 } |
| 431 |
| 432 SetupSoftwareRenderer(*d3d); |
390 } | 433 } |
391 | 434 |
392 D3DDISPLAYMODE d3ddm; | 435 D3DDISPLAYMODE d3ddm; |
393 if (!HR((*d3d)->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm))) | 436 if (!HR((*d3d)->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm))) |
394 return Renderer::GPU_NOT_UP_TO_SPEC; | 437 return Renderer::GPU_NOT_UP_TO_SPEC; |
395 | 438 |
396 // NOTE: make sure the backbuffer matches this format, as it is | 439 // NOTE: make sure the backbuffer matches this format, as it is |
397 // currently currently assumed to be 32-bit 8X8R8G8B | 440 // currently assumed to be 32-bit 8X8R8G8B |
398 | 441 |
399 ZeroMemory(d3d_present_parameters, sizeof(*d3d_present_parameters)); | 442 ZeroMemory(d3d_present_parameters, sizeof(*d3d_present_parameters)); |
400 d3d_present_parameters->Windowed = !fullscreen; | 443 d3d_present_parameters->Windowed = !fullscreen; |
401 d3d_present_parameters->SwapEffect = D3DSWAPEFFECT_DISCARD; | 444 d3d_present_parameters->SwapEffect = D3DSWAPEFFECT_DISCARD; |
402 d3d_present_parameters->BackBufferFormat = d3ddm.Format; | 445 d3d_present_parameters->BackBufferFormat = d3ddm.Format; |
403 d3d_present_parameters->EnableAutoDepthStencil = FALSE; | 446 d3d_present_parameters->EnableAutoDepthStencil = FALSE; |
404 d3d_present_parameters->AutoDepthStencilFormat = D3DFMT_UNKNOWN; | 447 d3d_present_parameters->AutoDepthStencilFormat = D3DFMT_UNKNOWN; |
405 // wait for vsync | 448 // wait for vsync |
406 d3d_present_parameters->PresentationInterval = D3DPRESENT_INTERVAL_ONE; | 449 d3d_present_parameters->PresentationInterval = D3DPRESENT_INTERVAL_ONE; |
407 | 450 |
(...skipping 1314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1722 static int swizzle_table[] = { 2, 1, 0, 3, }; | 1765 static int swizzle_table[] = { 2, 1, 0, 3, }; |
1723 return swizzle_table; | 1766 return swizzle_table; |
1724 } | 1767 } |
1725 | 1768 |
1726 // This is a factory function for creating Renderer objects. Since | 1769 // This is a factory function for creating Renderer objects. Since |
1727 // we're implementing D3D9, we only ever return a D3D9 renderer. | 1770 // we're implementing D3D9, we only ever return a D3D9 renderer. |
1728 Renderer* Renderer::CreateDefaultRenderer(ServiceLocator* service_locator) { | 1771 Renderer* Renderer::CreateDefaultRenderer(ServiceLocator* service_locator) { |
1729 return RendererD3D9::CreateDefault(service_locator); | 1772 return RendererD3D9::CreateDefault(service_locator); |
1730 } | 1773 } |
1731 } // namespace o3d | 1774 } // namespace o3d |
OLD | NEW |