Create a Direct3D 11 device, if enabled and available.

TRAC #21925
Signed-off-by: Daniel Koch
Author: Nicolas Capens

git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1399 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/renderer/Renderer.cpp b/src/libGLESv2/renderer/Renderer.cpp
index f6c200d..8169bf7 100644
--- a/src/libGLESv2/renderer/Renderer.cpp
+++ b/src/libGLESv2/renderer/Renderer.cpp
@@ -8,13 +8,51 @@
 
 #include "libGLESv2/renderer/Renderer.h"
 #include "libGLESv2/renderer/Renderer9.h"
+#include "libGLESv2/renderer/Renderer11.h"
+
+#if !defined(ANGLE_ENABLE_D3D11)
+// Enables use of the Direct3D 11 API, when available
+#define ANGLE_ENABLE_D3D11 0
+#endif
 
 extern "C"
 {
 
 rx::Renderer *glCreateRenderer(egl::Display *display, HDC hDc, bool softwareDevice)
 {
-    return new rx::Renderer9(display, hDc, softwareDevice);
+    rx::Renderer *renderer = NULL;
+    EGLint status = EGL_BAD_ALLOC;
+    
+    #if ANGLE_ENABLE_D3D11
+        renderer = new rx::Renderer11(display, hDc);
+    
+        if (renderer)
+        {
+            status = renderer->initialize();
+        }
+
+        if (status == EGL_SUCCESS)
+        {
+            return renderer;
+        }
+
+        // Failed to create a D3D11 renderer, try creating a D3D9 renderer
+        delete renderer;
+    #endif
+
+    renderer = new rx::Renderer9(display, hDc, softwareDevice);
+    
+    if (renderer)
+    {
+        status = renderer->initialize();
+    }
+
+    if (status == EGL_SUCCESS)
+    {
+        return renderer;
+    }
+
+    return NULL;
 }
 
 void glDestroyRenderer(rx::Renderer *renderer)
diff --git a/src/libGLESv2/renderer/Renderer11.cpp b/src/libGLESv2/renderer/Renderer11.cpp
index b464364..ee26e25 100644
--- a/src/libGLESv2/renderer/Renderer11.cpp
+++ b/src/libGLESv2/renderer/Renderer11.cpp
@@ -43,31 +43,55 @@
 
     if (mD3d11Module)
     {
+        FreeLibrary(mD3d11Module);
         mD3d11Module = NULL;
     }
 
     if (mDxgiModule)
     {
+        FreeLibrary(mDxgiModule);
         mDxgiModule = NULL;
     }
-
 }
 
 EGLint Renderer11::initialize()
 {
-
-    mDxgiModule = GetModuleHandle(TEXT("dxgi.dll"));
-    mD3d11Module = GetModuleHandle(TEXT("d3d11.dll"));
+    mDxgiModule = LoadLibrary(TEXT("dxgi.dll"));
+    mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
 
     if (mD3d11Module == NULL || mDxgiModule == NULL)
     {
-        ERR("No D3D11 or DXGI module found - aborting!\n");
+        ERR("Could not load D3D11 or DXGI library - aborting!\n");
         return EGL_NOT_INITIALIZED;
     }
 
-    // TODO: device creation, any one-time setup.
-    UNIMPLEMENTED();
+    PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice");
 
+    if (D3D11CreateDevice == NULL)
+    {
+        ERR("Could not retrieve D3D11CreateDevice address - aborting!\n");
+        return EGL_NOT_INITIALIZED;
+    }
+
+    D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_10_0;
+
+    HRESULT result = D3D11CreateDevice(NULL,
+                                       D3D_DRIVER_TYPE_HARDWARE,
+                                       NULL,
+                                       NULL,
+                                       &featureLevel,
+                                       1,
+                                       D3D11_SDK_VERSION,
+                                       &mD3d11,
+                                       NULL,
+                                       &mDeviceContext);
+
+    if (!mD3d11 || FAILED(result))
+    {
+        ERR("Could not create D3D11 device - aborting!\n");
+        return EGL_NOT_INITIALIZED;   // Cleanup done by destructor through glDestroyRenderer
+    }
+    
     initializeDevice();
 
     return EGL_SUCCESS;
@@ -80,7 +104,7 @@
 {
     // Permanent non-default states
     // TODO
-    UNIMPLEMENTED();
+    // UNIMPLEMENTED();
 }
 
 
@@ -128,7 +152,7 @@
 void Renderer11::releaseDeviceResources()
 {
     // TODO
-    UNIMPLEMENTED();
+    // UNIMPLEMENTED();
 }
 
 void Renderer11::markDeviceLost()