Test for valid back buffer and depth stencil formats.

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

git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1411 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/build_angle.gypi b/src/build_angle.gypi
index 2ad9481..cd526af 100644
--- a/src/build_angle.gypi
+++ b/src/build_angle.gypi
@@ -258,6 +258,8 @@
             'libGLESv2/renderer/Renderer.h',
             'libGLESv2/renderer/Renderer11.cpp',
             'libGLESv2/renderer/Renderer11.h',
+            'libGLESv2/renderer/renderer11_utils.cpp',
+            'libGLESv2/renderer/renderer11_utils.h',
             'libGLESv2/renderer/Renderer9.cpp',
             'libGLESv2/renderer/Renderer9.h',
             'libGLESv2/renderer/renderer9_utils.cpp',
diff --git a/src/libGLESv2/libGLESv2.vcxproj b/src/libGLESv2/libGLESv2.vcxproj
index bcd4497..c3107ab 100644
--- a/src/libGLESv2/libGLESv2.vcxproj
+++ b/src/libGLESv2/libGLESv2.vcxproj
@@ -247,6 +247,7 @@
     <ClCompile Include="Renderbuffer.cpp" />

     <ClCompile Include="renderer\Renderer.cpp" />

     <ClCompile Include="renderer\Renderer11.cpp" />

+    <ClCompile Include="renderer\renderer11_utils.cpp" />

     <ClCompile Include="renderer\Renderer9.cpp" />

     <ClCompile Include="renderer\Image.cpp" />

     <ClCompile Include="renderer\renderer9_utils.cpp" />

@@ -283,6 +284,7 @@
     <ClInclude Include="renderer\Image.h" />

     <ClInclude Include="renderer\Renderer.h" />

     <ClInclude Include="renderer\Renderer11.h" />

+    <ClInclude Include="renderer\renderer11_utils.h" />

     <ClInclude Include="renderer\Renderer9.h" />

     <ClInclude Include="renderer\renderer9_utils.h" />

     <ClInclude Include="renderer\ShaderCache.h" />

diff --git a/src/libGLESv2/libGLESv2.vcxproj.filters b/src/libGLESv2/libGLESv2.vcxproj.filters
index 2e26a00..1fb9bea 100644
--- a/src/libGLESv2/libGLESv2.vcxproj.filters
+++ b/src/libGLESv2/libGLESv2.vcxproj.filters
@@ -104,6 +104,9 @@
     <ClCompile Include="renderer\Renderer.cpp">

       <Filter>Renderer</Filter>

     </ClCompile>

+    <ClCompile Include="renderer\renderer11_utils.cpp">

+      <Filter>Renderer</Filter>

+    </ClCompile>

   </ItemGroup>

   <ItemGroup>

     <ClInclude Include="BinaryStream.h">

@@ -214,6 +217,9 @@
     <ClInclude Include="renderer\Renderer11.h">

       <Filter>Renderer</Filter>

     </ClInclude>

+    <ClInclude Include="renderer\renderer11_utils.h">

+      <Filter>Renderer</Filter>

+    </ClInclude>

   </ItemGroup>

   <ItemGroup>

     <None Include="libGLESv2.def">

diff --git a/src/libGLESv2/renderer/Renderer11.cpp b/src/libGLESv2/renderer/Renderer11.cpp
index 41318b1..02a1535 100644
--- a/src/libGLESv2/renderer/Renderer11.cpp
+++ b/src/libGLESv2/renderer/Renderer11.cpp
@@ -9,12 +9,22 @@
 #include "common/debug.h"
 #include "libGLESv2/utilities.h"
 #include "libGLESv2/renderer/Renderer11.h"
+#include "libGLESv2/renderer/renderer11_utils.h"
 
 #include "libEGL/Config.h"
 #include "libEGL/Display.h"
 
 namespace rx
 {
+static const DXGI_FORMAT RenderTargetFormats[] =
+    {
+        DXGI_FORMAT_R8G8B8A8_UNORM
+    };
+
+static const DXGI_FORMAT DepthStencilFormats[] =
+    {
+        DXGI_FORMAT_D24_UNORM_S8_UINT
+    };
 
 Renderer11::Renderer11(egl::Display *display, HDC hDc) : Renderer(display), mDc(hDc)
 {
@@ -23,12 +33,26 @@
 
     mDevice = NULL;
     mDeviceContext = NULL;
+    mDxgiAdapter = NULL;
+    mDxgiFactory = NULL;
 }
 
 Renderer11::~Renderer11()
 {
     releaseDeviceResources();
 
+    if (mDxgiFactory)
+    {
+        mDxgiFactory->Release();
+        mDxgiFactory = NULL;
+    }
+
+    if (mDxgiAdapter)
+    {
+        mDxgiAdapter->Release();
+        mDxgiAdapter = NULL;
+    }
+
     if (mDeviceContext)
     {
         mDeviceContext->Release();
@@ -96,7 +120,34 @@
         ERR("Could not create D3D11 device - aborting!\n");
         return EGL_NOT_INITIALIZED;   // Cleanup done by destructor through glDestroyRenderer
     }
-    
+
+    IDXGIDevice *dxgiDevice = NULL;
+    result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
+
+    if (FAILED(result))
+    {
+        ERR("Could not query DXGI device - aborting!\n");
+        return EGL_NOT_INITIALIZED;
+    }
+
+    result = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&mDxgiAdapter);
+
+    if (FAILED(result))
+    {
+        ERR("Could not retrieve DXGI adapter - aborting!\n");
+        return EGL_NOT_INITIALIZED;
+    }
+
+    dxgiDevice->Release();
+
+    result = mDxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&mDxgiFactory);
+
+    if (!mDxgiFactory || FAILED(result))
+    {
+        ERR("Could not create DXGI factory - aborting!\n");
+        return EGL_NOT_INITIALIZED;
+    }
+
     initializeDevice();
 
     return EGL_SUCCESS;
@@ -112,12 +163,44 @@
     // UNIMPLEMENTED();
 }
 
-
 int Renderer11::generateConfigs(ConfigDesc **configDescList)
 {
-    // TODO
-    UNIMPLEMENTED();
-    return 0;
+    int numRenderFormats = sizeof(RenderTargetFormats) / sizeof(RenderTargetFormats[0]);
+    int numDepthFormats = sizeof(DepthStencilFormats) / sizeof(DepthStencilFormats[0]);
+    (*configDescList) = new ConfigDesc[numRenderFormats * numDepthFormats];
+    int numConfigs = 0;
+    
+    for (int formatIndex = 0; formatIndex < numRenderFormats; formatIndex++)
+    {
+        for (int depthStencilIndex = 0; depthStencilIndex < numDepthFormats; depthStencilIndex++)
+        {
+            DXGI_FORMAT renderTargetFormat = RenderTargetFormats[formatIndex];
+
+            UINT formatSupport = 0;
+            HRESULT result = mDevice->CheckFormatSupport(renderTargetFormat, &formatSupport);
+            
+            if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET))
+            {
+                DXGI_FORMAT depthStencilFormat = DepthStencilFormats[depthStencilIndex];
+
+                UINT formatSupport = 0;
+                HRESULT result = mDevice->CheckFormatSupport(depthStencilFormat, &formatSupport);
+
+                if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL))
+                {
+                    ConfigDesc newConfig;
+                    newConfig.renderTargetFormat = d3d11_gl::ConvertBackBufferFormat(renderTargetFormat);
+                    newConfig.depthStencilFormat = d3d11_gl::ConvertDepthStencilFormat(depthStencilFormat);
+                    newConfig.multiSample = 0;     // FIXME: enumerate multi-sampling
+                    newConfig.fastConfig = true;   // Assume all DX11 format conversions to be fast
+
+                    (*configDescList)[numConfigs++] = newConfig;
+                }
+            }
+        }
+    }
+
+    return numConfigs;
 }
 
 void Renderer11::deleteConfigs(ConfigDesc *configDescList)
diff --git a/src/libGLESv2/renderer/Renderer11.h b/src/libGLESv2/renderer/Renderer11.h
index be1a4b3..112b70f 100644
--- a/src/libGLESv2/renderer/Renderer11.h
+++ b/src/libGLESv2/renderer/Renderer11.h
@@ -105,6 +105,8 @@
     ID3D11Device *mDevice;
     D3D_FEATURE_LEVEL mFeatureLevel;
     ID3D11DeviceContext *mDeviceContext;
+    IDXGIAdapter *mDxgiAdapter;
+    IDXGIFactory1 *mDxgiFactory;
 };
 
 }
diff --git a/src/libGLESv2/renderer/renderer11_utils.cpp b/src/libGLESv2/renderer/renderer11_utils.cpp
new file mode 100644
index 0000000..c405c88
--- /dev/null
+++ b/src/libGLESv2/renderer/renderer11_utils.cpp
@@ -0,0 +1,41 @@
+//

+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.

+// Use of this source code is governed by a BSD-style license that can be

+// found in the LICENSE file.

+//

+

+// renderer11_utils.cpp: Conversion functions and other utility routines

+// specific to the D3D11 renderer.

+

+#include "libGLESv2/renderer/renderer11_utils.h"

+

+#include "common/debug.h"

+

+namespace d3d11_gl

+{

+

+GLenum ConvertBackBufferFormat(DXGI_FORMAT format)

+{

+    switch (format)

+    {

+      case DXGI_FORMAT_R8G8B8A8_UNORM: return GL_RGBA8_OES;

+      default:

+        UNREACHABLE();

+    }

+

+    return GL_RGBA8_OES;

+}

+

+GLenum ConvertDepthStencilFormat(DXGI_FORMAT format)

+{

+    switch (format)

+    {

+      case DXGI_FORMAT_D24_UNORM_S8_UINT: return GL_DEPTH24_STENCIL8_OES;

+      default:

+        UNREACHABLE();

+    }

+

+    return GL_DEPTH24_STENCIL8_OES;

+}

+

+}

diff --git a/src/libGLESv2/renderer/renderer11_utils.h b/src/libGLESv2/renderer/renderer11_utils.h
new file mode 100644
index 0000000..9c03f74
--- /dev/null
+++ b/src/libGLESv2/renderer/renderer11_utils.h
@@ -0,0 +1,21 @@
+//

+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.

+// Use of this source code is governed by a BSD-style license that can be

+// found in the LICENSE file.

+//

+

+// renderer11_utils.h: Conversion functions and other utility routines

+// specific to the D3D11 renderer.

+

+#define GL_APICALL
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <d3d11.h>

+

+namespace d3d11_gl

+{

+

+GLenum ConvertBackBufferFormat(DXGI_FORMAT format);

+GLenum ConvertDepthStencilFormat(DXGI_FORMAT format);

+

+}