Implemented SwapChain11 initialization.

TRAC #21928
Signed-off-by: Geoff Lang
Signed-off-by: Daniel Koch
Author: Nicolas Capens

git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1456 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/build_angle.gypi b/src/build_angle.gypi
index 4dbc636..6b6f780 100644
--- a/src/build_angle.gypi
+++ b/src/build_angle.gypi
@@ -273,6 +273,8 @@
             'libGLESv2/renderer/SwapChain.h',
             'libGLESv2/renderer/SwapChain9.cpp',
             'libGLESv2/renderer/SwapChain9.h',
+            'libGLESv2/renderer/SwapChain11.cpp',
+            'libGLESv2/renderer/SwapChain11.h',
             'libGLESv2/renderer/TextureStorage.cpp',
             'libGLESv2/renderer/TextureStorage.h',
             'libGLESv2/renderer/RenderStateCache.cpp',
diff --git a/src/libGLESv2/libGLESv2.vcxproj b/src/libGLESv2/libGLESv2.vcxproj
index 66d4bce..bb936a5 100644
--- a/src/libGLESv2/libGLESv2.vcxproj
+++ b/src/libGLESv2/libGLESv2.vcxproj
@@ -254,6 +254,7 @@
     <ClCompile Include="renderer\renderer9_utils.cpp" />

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

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

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

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

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

     <ClCompile Include="ResourceManager.cpp" />

@@ -296,6 +297,7 @@
     <ClInclude Include="renderer\RenderStateCache.h" />

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

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

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

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

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

     <ClInclude Include="resource.h" />

diff --git a/src/libGLESv2/libGLESv2.vcxproj.filters b/src/libGLESv2/libGLESv2.vcxproj.filters
index a6a2287..d04e14a 100644
--- a/src/libGLESv2/libGLESv2.vcxproj.filters
+++ b/src/libGLESv2/libGLESv2.vcxproj.filters
@@ -122,6 +122,9 @@
     <ClCompile Include="..\third_party\murmurhash\MurmurHash3.cpp">

       <Filter>Third Party\MurmurHash</Filter>

     </ClCompile>

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

+      <Filter>Renderer</Filter>

+    </ClCompile>

   </ItemGroup>

   <ItemGroup>

     <ClInclude Include="BinaryStream.h">

@@ -250,6 +253,9 @@
     <ClInclude Include="..\third_party\murmurhash\MurmurHash3.h">

       <Filter>Third Party\MurmurHash</Filter>

     </ClInclude>

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

+      <Filter>Renderer</Filter>

+    </ClInclude>

   </ItemGroup>

   <ItemGroup>

     <None Include="libGLESv2.def">

diff --git a/src/libGLESv2/main.cpp b/src/libGLESv2/main.cpp
index 0a69d41..bda771a 100644
--- a/src/libGLESv2/main.cpp
+++ b/src/libGLESv2/main.cpp
@@ -8,6 +8,7 @@
 
 #include "libGLESv2/main.h"
 #include "libGLESv2/utilities.h"
+#include "libGLESv2/renderer/renderer9_utils.h"   // D3D9_REPLACE
 
 #include "common/debug.h"
 #include "libEGL/Surface.h"
diff --git a/src/libGLESv2/renderer/Renderer11.cpp b/src/libGLESv2/renderer/Renderer11.cpp
index bbdb731..7b1ceeb 100644
--- a/src/libGLESv2/renderer/Renderer11.cpp
+++ b/src/libGLESv2/renderer/Renderer11.cpp
@@ -12,6 +12,7 @@
 #include "libGLESv2/mathutil.h"
 #include "libGLESv2/renderer/Renderer11.h"
 #include "libGLESv2/renderer/renderer11_utils.h"
+#include "libGLESv2/renderer/SwapChain11.h"
 
 #include "libEGL/Config.h"
 #include "libEGL/Display.h"
@@ -116,7 +117,11 @@
     HRESULT result = D3D11CreateDevice(NULL,
                                        D3D_DRIVER_TYPE_HARDWARE,
                                        NULL,
-                                       0,   // D3D11_CREATE_DEVICE_DEBUG
+                                       #if defined(_DEBUG)
+                                       D3D11_CREATE_DEVICE_DEBUG,
+                                       #else
+                                       0,
+                                       #endif
                                        featureLevel,
                                        sizeof(featureLevel)/sizeof(featureLevel[0]),
                                        D3D11_SDK_VERSION,
@@ -237,12 +242,7 @@
 
 SwapChain *Renderer11::createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
 {
-    // TODO
-    UNIMPLEMENTED();
-
-    //return new rx::SwapChain(this, window, shareHandle, backBufferFormat, depthBufferFormat);
-
-    return NULL;
+    return new rx::SwapChain11(this, window, shareHandle, backBufferFormat, depthBufferFormat);
 }
 
 void Renderer11::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState)
diff --git a/src/libGLESv2/renderer/Renderer11.h b/src/libGLESv2/renderer/Renderer11.h
index 12c6344..d978511 100644
--- a/src/libGLESv2/renderer/Renderer11.h
+++ b/src/libGLESv2/renderer/Renderer11.h
@@ -123,6 +123,7 @@
     // D3D11-renderer specific methods
     ID3D11Device *getDevice() { return mDevice; }
     ID3D11DeviceContext *getDeviceContext() { return mDeviceContext; };
+    IDXGIFactory *getDxgiFactory() { return mDxgiFactory; };
 
   private:
     DISALLOW_COPY_AND_ASSIGN(Renderer11);
@@ -165,7 +166,7 @@
     D3D_FEATURE_LEVEL mFeatureLevel;
     ID3D11DeviceContext *mDeviceContext;
     IDXGIAdapter *mDxgiAdapter;
-    IDXGIFactory1 *mDxgiFactory;
+    IDXGIFactory *mDxgiFactory;
 };
 
 }
diff --git a/src/libGLESv2/renderer/SwapChain11.cpp b/src/libGLESv2/renderer/SwapChain11.cpp
new file mode 100644
index 0000000..125e1ae
--- /dev/null
+++ b/src/libGLESv2/renderer/SwapChain11.cpp
@@ -0,0 +1,319 @@
+//

+// 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.

+//

+

+// SwapChain11.cpp: Implements a back-end specific class for the D3D11 swap chain.

+

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

+

+#include "common/debug.h"

+#include "libGLESv2/utilities.h"

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

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

+#include "libGLESv2/Context.h"

+#include "libGLESv2/main.h"

+

+namespace rx

+{

+

+SwapChain11::SwapChain11(Renderer11 *renderer, HWND window, HANDLE shareHandle,

+                         GLenum backBufferFormat, GLenum depthBufferFormat)

+    : mRenderer(renderer), SwapChain(window, shareHandle, backBufferFormat, depthBufferFormat)

+{

+    mSwapChain = NULL;

+    mBackBuffer = NULL;

+    mBackBufferView = NULL;

+    mRenderTargetView = NULL;

+    mDepthStencil = NULL;

+    mDepthStencilView = NULL;

+    mOffscreenTexture = NULL;

+    mWidth = -1;

+    mHeight = -1;

+}

+

+SwapChain11::~SwapChain11()

+{

+    release();

+}

+

+void SwapChain11::release()

+{

+    if (mSwapChain)

+    {

+        mSwapChain->Release();

+        mSwapChain = NULL;

+    }

+

+    if (mBackBuffer)

+    {

+        mBackBuffer->Release();

+        mBackBuffer = NULL;

+    }

+

+    if (mBackBufferView)

+    {

+        mBackBufferView->Release();

+        mBackBufferView = NULL;

+    }

+    

+    if (mRenderTargetView)

+    {

+        mRenderTargetView->Release();

+        mRenderTargetView = NULL;

+    }

+

+    if (mDepthStencil)

+    {

+        mDepthStencil->Release();

+        mDepthStencil = NULL;

+    }

+

+    if (mDepthStencilView)

+    {

+        mDepthStencilView->Release();

+        mDepthStencilView = NULL;

+    }

+

+    if (mOffscreenTexture)

+    {

+        mOffscreenTexture->Release();

+        mOffscreenTexture = NULL;

+    }

+

+    if (mWindow)

+        mShareHandle = NULL;

+}

+

+EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swapInterval)

+{

+    ID3D11Device *device = mRenderer->getDevice();

+

+    if (device == NULL)

+    {

+        return EGL_BAD_ACCESS;

+    }

+

+    // Release specific resources to free up memory for the new render target, while the

+    // old render target still exists for the purpose of preserving its contents.

+    if (mSwapChain)

+    {

+        mSwapChain->Release();

+        mSwapChain = NULL;

+    }

+

+    if (mBackBuffer)

+    {

+        mBackBuffer->Release();

+        mBackBuffer = NULL;

+    }

+

+    if (mBackBufferView)

+    {

+        mBackBufferView->Release();

+        mBackBufferView = NULL;

+    }

+

+    if (mRenderTargetView)   // TODO: Preserve the render target content

+    {

+        mRenderTargetView->Release();

+        mRenderTargetView = NULL;

+    }

+

+    if (mOffscreenTexture)

+    {

+        mOffscreenTexture->Release();

+        mOffscreenTexture = NULL;

+    }

+

+    if (mDepthStencil)

+    {

+        mDepthStencil->Release();

+        mDepthStencil = NULL;

+    }

+

+    if (mDepthStencilView)

+    {

+        mDepthStencilView->Release();

+        mDepthStencilView = NULL;

+    }

+

+    HANDLE *pShareHandle = NULL;

+    if (!mWindow && mRenderer->getShareHandleSupport())

+    {

+        pShareHandle = &mShareHandle;

+    }

+

+    D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0};

+    offscreenTextureDesc.Width = backbufferWidth;

+    offscreenTextureDesc.Height = backbufferHeight;

+    offscreenTextureDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat);

+    offscreenTextureDesc.MipLevels = 1;

+    offscreenTextureDesc.ArraySize = 1;

+    offscreenTextureDesc.SampleDesc.Count = 1;

+    offscreenTextureDesc.SampleDesc.Quality = 0;

+    offscreenTextureDesc.Usage = D3D11_USAGE_DEFAULT;

+    offscreenTextureDesc.BindFlags = D3D11_BIND_RENDER_TARGET;

+    offscreenTextureDesc.CPUAccessFlags = 0;

+    offscreenTextureDesc.MiscFlags = 0;   // D3D11_RESOURCE_MISC_SHARED

+

+    HRESULT result = device->CreateTexture2D(&offscreenTextureDesc, NULL, &mOffscreenTexture);

+

+    if (FAILED(result))

+    {

+        ERR("Could not create offscreen texture: %08lX", result);

+        release();

+

+        if (isDeviceLostError(result))

+        {

+            return EGL_CONTEXT_LOST;

+        }

+        else

+        {

+            return EGL_BAD_ALLOC;

+        }

+    }

+        

+    result = device->CreateRenderTargetView(mOffscreenTexture, NULL, &mRenderTargetView);

+    ASSERT(SUCCEEDED(result));

+

+    if (mWindow)

+    {

+        IDXGIFactory *factory = mRenderer->getDxgiFactory();

+

+        DXGI_SWAP_CHAIN_DESC swapChainDesc = {0};

+        swapChainDesc.BufferCount = 2;

+        swapChainDesc.BufferDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat);

+        swapChainDesc.BufferDesc.Width = 1;

+        swapChainDesc.BufferDesc.Height = 1;

+        swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;

+        swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;

+        swapChainDesc.BufferDesc.RefreshRate.Numerator = 0;

+        swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;

+        swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;

+        swapChainDesc.Flags = 0;

+        swapChainDesc.OutputWindow = mWindow;

+        swapChainDesc.SampleDesc.Count = 1;

+        swapChainDesc.SampleDesc.Quality = 0;

+        swapChainDesc.Windowed = TRUE;

+

+        result = factory->CreateSwapChain(device, &swapChainDesc, &mSwapChain);

+

+        if (FAILED(result))

+        {

+            ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result);

+            release();

+

+            if (isDeviceLostError(result))

+            {

+                return EGL_CONTEXT_LOST;

+            }

+            else

+            {

+                return EGL_BAD_ALLOC;

+            }

+        }

+

+        result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackBuffer);

+        ASSERT(SUCCEEDED(result));

+

+        result = device->CreateRenderTargetView(mBackBuffer, NULL, &mBackBufferView);

+        ASSERT(SUCCEEDED(result));

+    }

+

+    if (mDepthBufferFormat != GL_NONE)

+    {

+        D3D11_TEXTURE2D_DESC depthStencilDesc = {0};

+        depthStencilDesc.Width = backbufferWidth;

+        depthStencilDesc.Height = backbufferHeight;

+        depthStencilDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mDepthBufferFormat);

+        depthStencilDesc.MipLevels = 1;

+        depthStencilDesc.ArraySize = 1;

+        depthStencilDesc.SampleDesc.Count = 1;

+        depthStencilDesc.SampleDesc.Quality = 0;

+        depthStencilDesc.Usage = D3D11_USAGE_DEFAULT;

+        depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;

+        depthStencilDesc.CPUAccessFlags = 0;

+        depthStencilDesc.MiscFlags = 0;

+

+        result = device->CreateTexture2D(&depthStencilDesc, NULL, &mDepthStencil);

+

+        if (FAILED(result))

+        {

+            ERR("Could not create depthstencil surface for new swap chain: 0x%08X", result);

+            release();

+

+            if (isDeviceLostError(result))

+            {

+                return EGL_CONTEXT_LOST;

+            }

+            else

+            {

+                return EGL_BAD_ALLOC;

+            }

+        }

+

+        result = device->CreateDepthStencilView(mDepthStencil, NULL, &mDepthStencilView);

+        ASSERT(SUCCEEDED(result));

+    }

+

+    mWidth = backbufferWidth;

+    mHeight = backbufferHeight;

+

+    return EGL_SUCCESS;

+}

+

+// parameters should be validated/clamped by caller

+EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)

+{

+    if (!mSwapChain)

+    {

+        return EGL_SUCCESS;

+    }

+

+    ID3D11Device *device = mRenderer->getDevice();

+

+    // TODO

+    UNIMPLEMENTED();

+

+    return EGL_SUCCESS;

+}

+

+// Increments refcount on view.

+// caller must Release() the returned view

+ID3D11RenderTargetView *SwapChain11::getRenderTarget()

+{

+    if (mRenderTargetView)

+    {

+        mRenderTargetView->AddRef();

+    }

+

+    return mRenderTargetView;

+}

+

+// Increments refcount on view.

+// caller must Release() the returned view

+ID3D11DepthStencilView *SwapChain11::getDepthStencil()

+{

+    if (mDepthStencilView)

+    {

+        mDepthStencilView->AddRef();

+    }

+

+    return mDepthStencilView;

+}

+

+// Increments refcount on texture.

+// caller must Release() the returned texture

+ID3D11Texture2D *SwapChain11::getOffscreenTexture()

+{

+    if (mOffscreenTexture)

+    {

+        mOffscreenTexture->AddRef();

+    }

+

+    return mOffscreenTexture;

+}

+

+}

diff --git a/src/libGLESv2/renderer/SwapChain11.h b/src/libGLESv2/renderer/SwapChain11.h
new file mode 100644
index 0000000..75cda64
--- /dev/null
+++ b/src/libGLESv2/renderer/SwapChain11.h
@@ -0,0 +1,54 @@
+//

+// 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.

+//

+

+// SwapChain11.h: Defines a back-end specific class for the D3D11 swap chain.

+

+#ifndef LIBGLESV2_RENDERER_SWAPCHAIN11_H_

+#define LIBGLESV2_RENDERER_SWAPCHAIN11_H_

+

+#include <d3d11.h>

+

+#include "common/angleutils.h"

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

+

+namespace rx

+{

+class Renderer11;

+

+class SwapChain11 : public SwapChain

+{

+  public:

+    SwapChain11(Renderer11 *renderer, HWND window, HANDLE shareHandle,

+                GLenum backBufferFormat, GLenum depthBufferFormat);

+    virtual ~SwapChain11();

+

+    virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval);

+    virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height);

+

+    virtual ID3D11RenderTargetView *getRenderTarget();

+    virtual ID3D11DepthStencilView *getDepthStencil();

+    virtual ID3D11Texture2D *getOffscreenTexture();

+

+  private:

+    DISALLOW_COPY_AND_ASSIGN(SwapChain11);

+

+    void release();

+

+    Renderer11 *mRenderer;

+    EGLint mHeight;

+    EGLint mWidth;

+

+    IDXGISwapChain *mSwapChain;

+    ID3D11Texture2D *mBackBuffer;

+    ID3D11RenderTargetView *mBackBufferView;

+    ID3D11RenderTargetView *mRenderTargetView;

+    ID3D11Texture2D *mDepthStencil;

+    ID3D11DepthStencilView *mDepthStencilView;

+    ID3D11Texture2D *mOffscreenTexture;

+};

+

+}

+#endif // LIBGLESV2_RENDERER_SWAPCHAIN11_H_

diff --git a/src/libGLESv2/renderer/SwapChain9.cpp b/src/libGLESv2/renderer/SwapChain9.cpp
index 8d3ad0c..26a780c 100644
--- a/src/libGLESv2/renderer/SwapChain9.cpp
+++ b/src/libGLESv2/renderer/SwapChain9.cpp
@@ -237,7 +237,7 @@
         ASSERT(SUCCEEDED(result));
     }
 
-    if (mDepthBufferFormat != D3DFMT_UNKNOWN)
+    if (mDepthBufferFormat != GL_NONE)
     {
         result = device->CreateDepthStencilSurface(backbufferWidth, backbufferHeight,
                                                    gl_d3d9::ConvertRenderbufferFormat(mDepthBufferFormat),
diff --git a/src/libGLESv2/renderer/renderer11_utils.h b/src/libGLESv2/renderer/renderer11_utils.h
index d4df692..0763cd1 100644
--- a/src/libGLESv2/renderer/renderer11_utils.h
+++ b/src/libGLESv2/renderer/renderer11_utils.h
@@ -44,3 +44,18 @@
 DXGI_FORMAT ConvertRenderbufferFormat(GLenum format);
 DXGI_FORMAT ConvertTextureInternalFormat(GLenum internalformat);
 }
+
+inline bool isDeviceLostError(HRESULT errorCode)
+{
+    switch (errorCode)
+    {
+      case DXGI_ERROR_DEVICE_HUNG:
+      case DXGI_ERROR_DEVICE_REMOVED:
+      case DXGI_ERROR_DEVICE_RESET:
+      case DXGI_ERROR_DRIVER_INTERNAL_ERROR:
+      case DXGI_ERROR_NOT_CURRENTLY_AVAILABLE:
+        return true;
+      default:
+        return false;
+    }
+};
diff --git a/src/libGLESv2/renderer/renderer9_utils.h b/src/libGLESv2/renderer/renderer9_utils.h
index 7002191..1cdcb69 100644
--- a/src/libGLESv2/renderer/renderer9_utils.h
+++ b/src/libGLESv2/renderer/renderer9_utils.h
@@ -63,4 +63,18 @@
 size_t ComputeRowSize(D3DFORMAT format, unsigned int width);
 }
 
+inline bool isDeviceLostError(HRESULT errorCode)
+{
+    switch (errorCode)
+    {
+      case D3DERR_DRIVERINTERNALERROR:
+      case D3DERR_DEVICELOST:
+      case D3DERR_DEVICEHUNG:
+      case D3DERR_DEVICEREMOVED:
+        return true;
+      default:
+        return false;
+    }
+};
+
 #endif // LIBGLESV2_RENDERER_RENDERER9_UTILS_H
diff --git a/src/libGLESv2/utilities.h b/src/libGLESv2/utilities.h
index cfb821c..2d7784b 100644
--- a/src/libGLESv2/utilities.h
+++ b/src/libGLESv2/utilities.h
@@ -63,18 +63,4 @@
 std::string getTempPath();
 void writeFile(const char* path, const void* data, size_t size);
 
-inline bool isDeviceLostError(HRESULT errorCode)
-{
-    switch (errorCode)
-    {
-      case D3DERR_DRIVERINTERNALERROR:
-      case D3DERR_DEVICELOST:
-      case D3DERR_DEVICEHUNG:
-      case D3DERR_DEVICEREMOVED:
-        return true;
-      default:
-        return false;
-    }
-};
-
 #endif  // LIBGLESV2_UTILITIES_H