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