Index: core/win/d3d9/renderer_d3d9.cc |
=================================================================== |
--- core/win/d3d9/renderer_d3d9.cc (revision 19033) |
+++ core/win/d3d9/renderer_d3d9.cc (working copy) |
@@ -54,6 +54,7 @@ |
#include "core/win/d3d9/primitive_d3d9.h" |
#include "core/win/d3d9/render_surface_d3d9.h" |
#include "core/win/d3d9/sampler_d3d9.h" |
+#include "core/win/d3d9/software_renderer_d3d9.h" |
#include "core/win/d3d9/stream_bank_d3d9.h" |
#include "core/win/d3d9/texture_d3d9.h" |
#include "core/win/d3d9/utils_d3d9.h" |
@@ -297,7 +298,7 @@ |
<< " for depth/stencil buffers."; |
return false; |
} |
- } |
+ } |
return true; |
} |
@@ -329,11 +330,11 @@ |
// For certain GPU drivers we need to force anti-aliasing off to avoid a |
// a huge performance hit when certain types of windows are used on the same |
// desktop as O3D. This function returns true if O3D is running on one |
-// of these GPUs/Drivers. |
+// of these GPUs/Drivers. |
bool ForceAntiAliasingOff(LPDIRECT3D9* d3d) { |
D3DADAPTER_IDENTIFIER9 identifier; |
HRESULT hr = (*d3d)->GetAdapterIdentifier(D3DADAPTER_DEFAULT, 0, &identifier); |
- |
+ |
unsigned int vendor_id = identifier.VendorId; |
unsigned int device_id = identifier.DeviceId; |
unsigned int product = HIWORD(identifier.DriverVersion.HighPart); |
@@ -345,15 +346,47 @@ |
if (vendor_id == 4098 && // ATI |
product == 6 && |
version == 14 && |
- subversion == 10 && |
+ subversion == 10 && |
build <= 6800) { |
return true; |
- } |
+ } |
return false; |
} |
+namespace { |
+// Returns whether the ForceSoftwareRenderer value of the Software\Google\o3d |
+// key is non-zero. |
+bool IsForceSoftwareRendererEnabled() { |
+ HKEY key; |
+ if (FAILED(RegOpenKeyEx(HKEY_CURRENT_USER, |
+ TEXT("Software\\Google\\o3d"), |
+ 0, |
+ KEY_READ, |
+ &key))) { |
+ return false; |
+ } |
+ |
+ bool enabled = false; |
+ DWORD type; |
+ DWORD value; |
+ DWORD size = sizeof(value); |
+ if (SUCCEEDED(RegQueryValueEx(key, |
+ TEXT("ForceSoftwareRenderer"), |
+ NULL, |
+ &type, |
+ reinterpret_cast<LPBYTE>(&value), |
+ &size))) { |
+ if (type == REG_DWORD && size == sizeof(value) && value) { |
+ enabled = true; |
+ } |
+ } |
+ RegCloseKey(key); |
+ return enabled; |
+} |
+} |
+ |
// Helper function that gets the D3D Interface, checks the available |
// multisampling modes and selects the most advanced one available to create |
// a D3D Device with a back buffer containing depth and stencil buffers that |
@@ -368,9 +401,17 @@ |
int* out_width, |
int* out_height) { |
- // Try the hardware renderer first. |
- Renderer::InitStatus status_hardware = CreateDirect3D( |
- Direct3DCreate9, d3d, features); |
+ // Check registry to see if the developer has opted to force the software |
+ // renderer. |
+ Renderer::InitStatus status_hardware; |
+ if (IsForceSoftwareRendererEnabled()) { |
+ // Simulate GPU not up to spec. |
+ status_hardware = Renderer::GPU_NOT_UP_TO_SPEC; |
+ } else { |
+ // Create a hardware device. |
+ status_hardware = CreateDirect3D(Direct3DCreate9, d3d, features); |
+ } |
+ |
if (status_hardware != Renderer::SUCCESS) { |
Renderer::InitStatus status_software = CreateDirect3D( |
Direct3DCreate9Software, d3d, features); |
@@ -387,6 +428,8 @@ |
} |
return status_hardware; |
} |
+ |
+ SetupSoftwareRenderer(*d3d); |
} |
D3DDISPLAYMODE d3ddm; |
@@ -394,7 +437,7 @@ |
return Renderer::GPU_NOT_UP_TO_SPEC; |
// NOTE: make sure the backbuffer matches this format, as it is |
- // currently currently assumed to be 32-bit 8X8R8G8B |
+ // currently assumed to be 32-bit 8X8R8G8B |
ZeroMemory(d3d_present_parameters, sizeof(*d3d_present_parameters)); |
d3d_present_parameters->Windowed = !fullscreen; |