WinRT: video code cleanup: combined files Direct3DBase.* and SDL_winrtrenderer.*
authorDavid Ludwig <dludwig@pobox.com>
Sun, 25 Nov 2012 19:05:56 -0500
changeset 8369 6dfc4ba22640
parent 8368 c611e5a2eab4
child 8370 a7b682df854c
WinRT: video code cleanup: combined files Direct3DBase.* and SDL_winrtrenderer.*
VisualC/SDL/SDL_VS2012_WinRT.vcxproj
src/video/windowsrt/Direct3DBase.cpp
src/video/windowsrt/Direct3DBase.h
src/video/windowsrt/SDL_winrtrenderer.cpp
src/video/windowsrt/SDL_winrtrenderer.h
--- a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj	Sun Nov 25 17:35:41 2012 -0500
+++ b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj	Sun Nov 25 19:05:56 2012 -0500
@@ -117,14 +117,6 @@
     <ClCompile Include="..\..\src\video\SDL_stretch.c" />
     <ClCompile Include="..\..\src\video\SDL_surface.c" />
     <ClCompile Include="..\..\src\video\SDL_video.c" />
-    <ClCompile Include="..\..\src\video\windowsrt\Direct3DBase.cpp">
-      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
-      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
-      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
-      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
-      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</CompileAsWinRT>
-      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</CompileAsWinRT>
-    </ClCompile>
     <ClCompile Include="..\..\src\video\windowsrt\SDL_WinRTApp.cpp">
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
@@ -270,7 +262,6 @@
     <ClInclude Include="..\..\src\video\SDL_RLEaccel_c.h" />
     <ClInclude Include="..\..\src\video\SDL_shape_internals.h" />
     <ClInclude Include="..\..\src\video\SDL_sysvideo.h" />
-    <ClInclude Include="..\..\src\video\windowsrt\Direct3DBase.h" />
     <ClInclude Include="..\..\src\video\windowsrt\DirectXHelper.h" />
     <ClInclude Include="..\..\src\video\windowsrt\SDLmain_WinRT_common.h" />
     <ClInclude Include="..\..\src\video\windowsrt\SDL_WinRTApp.h" />
--- a/src/video/windowsrt/Direct3DBase.cpp	Sun Nov 25 17:35:41 2012 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,344 +0,0 @@
-#include "SDLmain_WinRT_common.h"
-#include "Direct3DBase.h"
-
-using namespace DirectX;
-using namespace Microsoft::WRL;
-using namespace Windows::UI::Core;
-using namespace Windows::Foundation;
-using namespace Windows::Graphics::Display;
-
-// Constructor.
-Direct3DBase::Direct3DBase()
-{
-}
-
-// Initialize the Direct3D resources required to run.
-void Direct3DBase::Initialize(CoreWindow^ window)
-{
-	m_window = window;
-	
-	CreateDeviceResources();
-	CreateWindowSizeDependentResources();
-}
-
-// Recreate all device resources and set them back to the current state.
-void Direct3DBase::HandleDeviceLost()
-{
-	// Reset these member variables to ensure that UpdateForWindowSizeChange recreates all resources.
-	m_windowBounds.Width = 0;
-	m_windowBounds.Height = 0;
-	m_swapChain = nullptr;
-
-	CreateDeviceResources();
-	UpdateForWindowSizeChange();
-}
-
-// These are the resources that depend on the device.
-void Direct3DBase::CreateDeviceResources()
-{
-	// This flag adds support for surfaces with a different color channel ordering
-	// than the API default. It is required for compatibility with Direct2D.
-	UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
-
-#if defined(_DEBUG)
-	// If the project is in a debug build, enable debugging via SDK Layers with this flag.
-	creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
-#endif
-
-	// This array defines the set of DirectX hardware feature levels this app will support.
-	// Note the ordering should be preserved.
-	// Don't forget to declare your application's minimum required feature level in its
-	// description.  All applications are assumed to support 9.1 unless otherwise stated.
-	D3D_FEATURE_LEVEL featureLevels[] = 
-	{
-		D3D_FEATURE_LEVEL_11_1,
-		D3D_FEATURE_LEVEL_11_0,
-		D3D_FEATURE_LEVEL_10_1,
-		D3D_FEATURE_LEVEL_10_0,
-		D3D_FEATURE_LEVEL_9_3,
-		D3D_FEATURE_LEVEL_9_2,
-		D3D_FEATURE_LEVEL_9_1
-	};
-
-	// Create the Direct3D 11 API device object and a corresponding context.
-	ComPtr<ID3D11Device> device;
-	ComPtr<ID3D11DeviceContext> context;
-	DX::ThrowIfFailed(
-		D3D11CreateDevice(
-			nullptr, // Specify nullptr to use the default adapter.
-			D3D_DRIVER_TYPE_HARDWARE,
-			nullptr,
-			creationFlags, // Set set debug and Direct2D compatibility flags.
-			featureLevels, // List of feature levels this app can support.
-			ARRAYSIZE(featureLevels),
-			D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION for Windows Store apps.
-			&device, // Returns the Direct3D device created.
-			&m_featureLevel, // Returns feature level of device created.
-			&context // Returns the device immediate context.
-			)
-		);
-
-	// Get the Direct3D 11.1 API device and context interfaces.
-	DX::ThrowIfFailed(
-		device.As(&m_d3dDevice)
-		);
-
-	DX::ThrowIfFailed(
-		context.As(&m_d3dContext)
-		);
-}
-
-// Allocate all memory resources that change on a window SizeChanged event.
-void Direct3DBase::CreateWindowSizeDependentResources()
-{ 
-	// Store the window bounds so the next time we get a SizeChanged event we can
-	// avoid rebuilding everything if the size is identical.
-	m_windowBounds = m_window->Bounds;
-
-	// Calculate the necessary swap chain and render target size in pixels.
-	float windowWidth = ConvertDipsToPixels(m_windowBounds.Width);
-	float windowHeight = ConvertDipsToPixels(m_windowBounds.Height);
-
-	// The width and height of the swap chain must be based on the window's
-	// landscape-oriented width and height. If the window is in a portrait
-	// orientation, the dimensions must be reversed.
-	m_orientation = DisplayProperties::CurrentOrientation;
-	bool swapDimensions =
-		m_orientation == DisplayOrientations::Portrait ||
-		m_orientation == DisplayOrientations::PortraitFlipped;
-	m_renderTargetSize.Width = swapDimensions ? windowHeight : windowWidth;
-	m_renderTargetSize.Height = swapDimensions ? windowWidth : windowHeight;
-
-	if(m_swapChain != nullptr)
-	{
-		// If the swap chain already exists, resize it.
-		DX::ThrowIfFailed(
-			m_swapChain->ResizeBuffers(
-				2, // Double-buffered swap chain.
-				static_cast<UINT>(m_renderTargetSize.Width),
-				static_cast<UINT>(m_renderTargetSize.Height),
-				DXGI_FORMAT_B8G8R8A8_UNORM,
-				0
-				)
-			);
-	}
-	else
-	{
-		// Otherwise, create a new one using the same adapter as the existing Direct3D device.
-		DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
-		swapChainDesc.Width = static_cast<UINT>(m_renderTargetSize.Width); // Match the size of the window.
-		swapChainDesc.Height = static_cast<UINT>(m_renderTargetSize.Height);
-		swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // This is the most common swap chain format.
-		swapChainDesc.Stereo = false;
-		swapChainDesc.SampleDesc.Count = 1; // Don't use multi-sampling.
-		swapChainDesc.SampleDesc.Quality = 0;
-		swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
-		swapChainDesc.BufferCount = 2; // Use double-buffering to minimize latency.
-		swapChainDesc.Scaling = DXGI_SCALING_NONE;
-		swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // All Windows Store apps must use this SwapEffect.
-		swapChainDesc.Flags = 0;
-
-		ComPtr<IDXGIDevice1>  dxgiDevice;
-		DX::ThrowIfFailed(
-			m_d3dDevice.As(&dxgiDevice)
-			);
-
-		ComPtr<IDXGIAdapter> dxgiAdapter;
-		DX::ThrowIfFailed(
-			dxgiDevice->GetAdapter(&dxgiAdapter)
-			);
-
-		ComPtr<IDXGIFactory2> dxgiFactory;
-		DX::ThrowIfFailed(
-			dxgiAdapter->GetParent(
-				__uuidof(IDXGIFactory2), 
-				&dxgiFactory
-				)
-			);
-
-		Windows::UI::Core::CoreWindow^ window = m_window.Get();
-		DX::ThrowIfFailed(
-			dxgiFactory->CreateSwapChainForCoreWindow(
-				m_d3dDevice.Get(),
-				reinterpret_cast<IUnknown*>(window),
-				&swapChainDesc,
-				nullptr, // Allow on all displays.
-				&m_swapChain
-				)
-			);
-			
-		// Ensure that DXGI does not queue more than one frame at a time. This both reduces latency and
-		// ensures that the application will only render after each VSync, minimizing power consumption.
-		DX::ThrowIfFailed(
-			dxgiDevice->SetMaximumFrameLatency(1)
-			);
-	}
-	
-	// Set the proper orientation for the swap chain, and generate the
-	// 3D matrix transformation for rendering to the rotated swap chain.
-	DXGI_MODE_ROTATION rotation = DXGI_MODE_ROTATION_UNSPECIFIED;
-	switch (m_orientation)
-	{
-		case DisplayOrientations::Landscape:
-			rotation = DXGI_MODE_ROTATION_IDENTITY;
-			m_orientationTransform3D = XMFLOAT4X4( // 0-degree Z-rotation
-				1.0f, 0.0f, 0.0f, 0.0f,
-				0.0f, 1.0f, 0.0f, 0.0f,
-				0.0f, 0.0f, 1.0f, 0.0f,
-				0.0f, 0.0f, 0.0f, 1.0f
-				);
-			break;
-
-		case DisplayOrientations::Portrait:
-			rotation = DXGI_MODE_ROTATION_ROTATE270;
-			m_orientationTransform3D = XMFLOAT4X4( // 90-degree Z-rotation
-				0.0f, 1.0f, 0.0f, 0.0f,
-				-1.0f, 0.0f, 0.0f, 0.0f,
-				0.0f, 0.0f, 1.0f, 0.0f,
-				0.0f, 0.0f, 0.0f, 1.0f
-				);
-			break;
-
-		case DisplayOrientations::LandscapeFlipped:
-			rotation = DXGI_MODE_ROTATION_ROTATE180;
-			m_orientationTransform3D = XMFLOAT4X4( // 180-degree Z-rotation
-				-1.0f, 0.0f, 0.0f, 0.0f,
-				0.0f, -1.0f, 0.0f, 0.0f,
-				0.0f, 0.0f, 1.0f, 0.0f,
-				0.0f, 0.0f, 0.0f, 1.0f
-				);
-			break;
-
-		case DisplayOrientations::PortraitFlipped:
-			rotation = DXGI_MODE_ROTATION_ROTATE90;
-			m_orientationTransform3D = XMFLOAT4X4( // 270-degree Z-rotation
-				0.0f, -1.0f, 0.0f, 0.0f,
-				1.0f, 0.0f, 0.0f, 0.0f,
-				0.0f, 0.0f, 1.0f, 0.0f,
-				0.0f, 0.0f, 0.0f, 1.0f
-				);
-			break;
-
-		default:
-			throw ref new Platform::FailureException();
-	}
-
-	DX::ThrowIfFailed(
-		m_swapChain->SetRotation(rotation)
-		);
-
-	// Create a render target view of the swap chain back buffer.
-	ComPtr<ID3D11Texture2D> backBuffer;
-	DX::ThrowIfFailed(
-		m_swapChain->GetBuffer(
-			0,
-			__uuidof(ID3D11Texture2D),
-			&backBuffer
-			)
-		);
-
-	DX::ThrowIfFailed(
-		m_d3dDevice->CreateRenderTargetView(
-			backBuffer.Get(),
-			nullptr,
-			&m_renderTargetView
-			)
-		);
-
-	// Create a depth stencil view.
-	CD3D11_TEXTURE2D_DESC depthStencilDesc(
-		DXGI_FORMAT_D24_UNORM_S8_UINT, 
-		static_cast<UINT>(m_renderTargetSize.Width),
-		static_cast<UINT>(m_renderTargetSize.Height),
-		1,
-		1,
-		D3D11_BIND_DEPTH_STENCIL
-		);
-
-	ComPtr<ID3D11Texture2D> depthStencil;
-	DX::ThrowIfFailed(
-		m_d3dDevice->CreateTexture2D(
-			&depthStencilDesc,
-			nullptr,
-			&depthStencil
-			)
-		);
-
-	CD3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc(D3D11_DSV_DIMENSION_TEXTURE2D);
-	DX::ThrowIfFailed(
-		m_d3dDevice->CreateDepthStencilView(
-			depthStencil.Get(),
-			&depthStencilViewDesc,
-			&m_depthStencilView
-			)
-		);
-
-	// Set the rendering viewport to target the entire window.
-	CD3D11_VIEWPORT viewport(
-		0.0f,
-		0.0f,
-		m_renderTargetSize.Width,
-		m_renderTargetSize.Height
-		);
-
-	m_d3dContext->RSSetViewports(1, &viewport);
-}
-
-// This method is called in the event handler for the SizeChanged event.
-void Direct3DBase::UpdateForWindowSizeChange()
-{
-	if (m_window->Bounds.Width  != m_windowBounds.Width ||
-		m_window->Bounds.Height != m_windowBounds.Height ||
-		m_orientation != DisplayProperties::CurrentOrientation)
-	{
-		ID3D11RenderTargetView* nullViews[] = {nullptr};
-		m_d3dContext->OMSetRenderTargets(ARRAYSIZE(nullViews), nullViews, nullptr);
-		m_renderTargetView = nullptr;
-		m_depthStencilView = nullptr;
-		m_d3dContext->Flush();
-		CreateWindowSizeDependentResources();
-	}
-}
-
-// Method to deliver the final image to the display.
-void Direct3DBase::Present()
-{
-	// The application may optionally specify "dirty" or "scroll"
-	// rects to improve efficiency in certain scenarios.
-	DXGI_PRESENT_PARAMETERS parameters = {0};
-	parameters.DirtyRectsCount = 0;
-	parameters.pDirtyRects = nullptr;
-	parameters.pScrollRect = nullptr;
-	parameters.pScrollOffset = nullptr;
-	
-	// The first argument instructs DXGI to block until VSync, putting the application
-	// to sleep until the next VSync. This ensures we don't waste any cycles rendering
-	// frames that will never be displayed to the screen.
-	HRESULT hr = m_swapChain->Present1(1, 0, &parameters);
-
-	// Discard the contents of the render target.
-	// This is a valid operation only when the existing contents will be entirely
-	// overwritten. If dirty or scroll rects are used, this call should be removed.
-	m_d3dContext->DiscardView(m_renderTargetView.Get());
-
-	// Discard the contents of the depth stencil.
-	m_d3dContext->DiscardView(m_depthStencilView.Get());
-
-	// If the device was removed either by a disconnect or a driver upgrade, we 
-	// must recreate all device resources.
-	if (hr == DXGI_ERROR_DEVICE_REMOVED)
-	{
-		HandleDeviceLost();
-	}
-	else
-	{
-		DX::ThrowIfFailed(hr);
-	}
-}
-
-// Method to convert a length in device-independent pixels (DIPs) to a length in physical pixels.
-float Direct3DBase::ConvertDipsToPixels(float dips)
-{
-	static const float dipsPerInch = 96.0f;
-	return floor(dips * DisplayProperties::LogicalDpi / dipsPerInch + 0.5f); // Round to nearest integer.
-}
--- a/src/video/windowsrt/Direct3DBase.h	Sun Nov 25 17:35:41 2012 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-#pragma once
-
-#include "DirectXHelper.h"
-#include "SDL.h"
-
-// Helper class that initializes DirectX APIs for 3D rendering.
-ref class Direct3DBase abstract
-{
-internal:
-	Direct3DBase();
-
-public:
-	virtual void Initialize(Windows::UI::Core::CoreWindow^ window);
-	virtual void HandleDeviceLost();
-	virtual void CreateDeviceResources();
-	virtual void CreateWindowSizeDependentResources();
-	virtual void UpdateForWindowSizeChange();
-	virtual void Present();
-	virtual float ConvertDipsToPixels(float dips);
-
-internal:
-	virtual void Render(SDL_Surface * surface, SDL_Rect * rects, int numrects) = 0;
-
-protected private:
-	// Direct3D Objects.
-	Microsoft::WRL::ComPtr<ID3D11Device1> m_d3dDevice;
-	Microsoft::WRL::ComPtr<ID3D11DeviceContext1> m_d3dContext;
-	Microsoft::WRL::ComPtr<IDXGISwapChain1> m_swapChain;
-	Microsoft::WRL::ComPtr<ID3D11RenderTargetView> m_renderTargetView;
-	Microsoft::WRL::ComPtr<ID3D11DepthStencilView> m_depthStencilView;
-
-	// Cached renderer properties.
-	D3D_FEATURE_LEVEL m_featureLevel;
-	Windows::Foundation::Size m_renderTargetSize;
-	Windows::Foundation::Rect m_windowBounds;
-	Platform::Agile<Windows::UI::Core::CoreWindow> m_window;
-	Windows::Graphics::Display::DisplayOrientations m_orientation;
-
-	// Transform used for display orientation.
-	DirectX::XMFLOAT4X4 m_orientationTransform3D;
-};
--- a/src/video/windowsrt/SDL_winrtrenderer.cpp	Sun Nov 25 17:35:41 2012 -0500
+++ b/src/video/windowsrt/SDL_winrtrenderer.cpp	Sun Nov 25 19:05:56 2012 -0500
@@ -3,20 +3,93 @@
 
 using namespace DirectX;
 using namespace Microsoft::WRL;
+using namespace Windows::UI::Core;
 using namespace Windows::Foundation;
-using namespace Windows::UI::Core;
+using namespace Windows::Graphics::Display;
 
+// Constructor.
 SDL_winrtrenderer::SDL_winrtrenderer() :
-	m_loadingComplete(false),
+    m_loadingComplete(false),
 	m_vertexCount(0)
 {
 }
 
+// Initialize the Direct3D resources required to run.
+void SDL_winrtrenderer::Initialize(CoreWindow^ window)
+{
+	m_window = window;
+	
+	CreateDeviceResources();
+	CreateWindowSizeDependentResources();
+}
+
+// Recreate all device resources and set them back to the current state.
+void SDL_winrtrenderer::HandleDeviceLost()
+{
+	// Reset these member variables to ensure that UpdateForWindowSizeChange recreates all resources.
+	m_windowBounds.Width = 0;
+	m_windowBounds.Height = 0;
+	m_swapChain = nullptr;
+
+	CreateDeviceResources();
+	UpdateForWindowSizeChange();
+}
+
+// These are the resources that depend on the device.
 void SDL_winrtrenderer::CreateDeviceResources()
 {
-	Direct3DBase::CreateDeviceResources();
+	// This flag adds support for surfaces with a different color channel ordering
+	// than the API default. It is required for compatibility with Direct2D.
+	UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
+
+#if defined(_DEBUG)
+	// If the project is in a debug build, enable debugging via SDK Layers with this flag.
+	creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
+#endif
+
+	// This array defines the set of DirectX hardware feature levels this app will support.
+	// Note the ordering should be preserved.
+	// Don't forget to declare your application's minimum required feature level in its
+	// description.  All applications are assumed to support 9.1 unless otherwise stated.
+	D3D_FEATURE_LEVEL featureLevels[] = 
+	{
+		D3D_FEATURE_LEVEL_11_1,
+		D3D_FEATURE_LEVEL_11_0,
+		D3D_FEATURE_LEVEL_10_1,
+		D3D_FEATURE_LEVEL_10_0,
+		D3D_FEATURE_LEVEL_9_3,
+		D3D_FEATURE_LEVEL_9_2,
+		D3D_FEATURE_LEVEL_9_1
+	};
 
-	auto loadVSTask = DX::ReadDataAsync("SDL_VS2012_WinRT\\SimpleVertexShader.cso");
+	// Create the Direct3D 11 API device object and a corresponding context.
+	ComPtr<ID3D11Device> device;
+	ComPtr<ID3D11DeviceContext> context;
+	DX::ThrowIfFailed(
+		D3D11CreateDevice(
+			nullptr, // Specify nullptr to use the default adapter.
+			D3D_DRIVER_TYPE_HARDWARE,
+			nullptr,
+			creationFlags, // Set set debug and Direct2D compatibility flags.
+			featureLevels, // List of feature levels this app can support.
+			ARRAYSIZE(featureLevels),
+			D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION for Windows Store apps.
+			&device, // Returns the Direct3D device created.
+			&m_featureLevel, // Returns feature level of device created.
+			&context // Returns the device immediate context.
+			)
+		);
+
+	// Get the Direct3D 11.1 API device and context interfaces.
+	DX::ThrowIfFailed(
+		device.As(&m_d3dDevice)
+		);
+
+	DX::ThrowIfFailed(
+		context.As(&m_d3dContext)
+		);
+
+    auto loadVSTask = DX::ReadDataAsync("SDL_VS2012_WinRT\\SimpleVertexShader.cso");
 	auto loadPSTask = DX::ReadDataAsync("SDL_VS2012_WinRT\\SimplePixelShader.cso");
 
 	auto createVSTask = loadVSTask.then([this](Platform::Array<byte>^ fileData) {
@@ -110,6 +183,202 @@
 	});
 }
 
+// Allocate all memory resources that change on a window SizeChanged event.
+void SDL_winrtrenderer::CreateWindowSizeDependentResources()
+{ 
+	// Store the window bounds so the next time we get a SizeChanged event we can
+	// avoid rebuilding everything if the size is identical.
+	m_windowBounds = m_window->Bounds;
+
+	// Calculate the necessary swap chain and render target size in pixels.
+	float windowWidth = ConvertDipsToPixels(m_windowBounds.Width);
+	float windowHeight = ConvertDipsToPixels(m_windowBounds.Height);
+
+	// The width and height of the swap chain must be based on the window's
+	// landscape-oriented width and height. If the window is in a portrait
+	// orientation, the dimensions must be reversed.
+	m_orientation = DisplayProperties::CurrentOrientation;
+	bool swapDimensions =
+		m_orientation == DisplayOrientations::Portrait ||
+		m_orientation == DisplayOrientations::PortraitFlipped;
+	m_renderTargetSize.Width = swapDimensions ? windowHeight : windowWidth;
+	m_renderTargetSize.Height = swapDimensions ? windowWidth : windowHeight;
+
+	if(m_swapChain != nullptr)
+	{
+		// If the swap chain already exists, resize it.
+		DX::ThrowIfFailed(
+			m_swapChain->ResizeBuffers(
+				2, // Double-buffered swap chain.
+				static_cast<UINT>(m_renderTargetSize.Width),
+				static_cast<UINT>(m_renderTargetSize.Height),
+				DXGI_FORMAT_B8G8R8A8_UNORM,
+				0
+				)
+			);
+	}
+	else
+	{
+		// Otherwise, create a new one using the same adapter as the existing Direct3D device.
+		DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
+		swapChainDesc.Width = static_cast<UINT>(m_renderTargetSize.Width); // Match the size of the window.
+		swapChainDesc.Height = static_cast<UINT>(m_renderTargetSize.Height);
+		swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // This is the most common swap chain format.
+		swapChainDesc.Stereo = false;
+		swapChainDesc.SampleDesc.Count = 1; // Don't use multi-sampling.
+		swapChainDesc.SampleDesc.Quality = 0;
+		swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+		swapChainDesc.BufferCount = 2; // Use double-buffering to minimize latency.
+		swapChainDesc.Scaling = DXGI_SCALING_NONE;
+		swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // All Windows Store apps must use this SwapEffect.
+		swapChainDesc.Flags = 0;
+
+		ComPtr<IDXGIDevice1>  dxgiDevice;
+		DX::ThrowIfFailed(
+			m_d3dDevice.As(&dxgiDevice)
+			);
+
+		ComPtr<IDXGIAdapter> dxgiAdapter;
+		DX::ThrowIfFailed(
+			dxgiDevice->GetAdapter(&dxgiAdapter)
+			);
+
+		ComPtr<IDXGIFactory2> dxgiFactory;
+		DX::ThrowIfFailed(
+			dxgiAdapter->GetParent(
+				__uuidof(IDXGIFactory2), 
+				&dxgiFactory
+				)
+			);
+
+		Windows::UI::Core::CoreWindow^ window = m_window.Get();
+		DX::ThrowIfFailed(
+			dxgiFactory->CreateSwapChainForCoreWindow(
+				m_d3dDevice.Get(),
+				reinterpret_cast<IUnknown*>(window),
+				&swapChainDesc,
+				nullptr, // Allow on all displays.
+				&m_swapChain
+				)
+			);
+			
+		// Ensure that DXGI does not queue more than one frame at a time. This both reduces latency and
+		// ensures that the application will only render after each VSync, minimizing power consumption.
+		DX::ThrowIfFailed(
+			dxgiDevice->SetMaximumFrameLatency(1)
+			);
+	}
+	
+	// Set the proper orientation for the swap chain, and generate the
+	// 3D matrix transformation for rendering to the rotated swap chain.
+	DXGI_MODE_ROTATION rotation = DXGI_MODE_ROTATION_UNSPECIFIED;
+	switch (m_orientation)
+	{
+		case DisplayOrientations::Landscape:
+			rotation = DXGI_MODE_ROTATION_IDENTITY;
+			m_orientationTransform3D = XMFLOAT4X4( // 0-degree Z-rotation
+				1.0f, 0.0f, 0.0f, 0.0f,
+				0.0f, 1.0f, 0.0f, 0.0f,
+				0.0f, 0.0f, 1.0f, 0.0f,
+				0.0f, 0.0f, 0.0f, 1.0f
+				);
+			break;
+
+		case DisplayOrientations::Portrait:
+			rotation = DXGI_MODE_ROTATION_ROTATE270;
+			m_orientationTransform3D = XMFLOAT4X4( // 90-degree Z-rotation
+				0.0f, 1.0f, 0.0f, 0.0f,
+				-1.0f, 0.0f, 0.0f, 0.0f,
+				0.0f, 0.0f, 1.0f, 0.0f,
+				0.0f, 0.0f, 0.0f, 1.0f
+				);
+			break;
+
+		case DisplayOrientations::LandscapeFlipped:
+			rotation = DXGI_MODE_ROTATION_ROTATE180;
+			m_orientationTransform3D = XMFLOAT4X4( // 180-degree Z-rotation
+				-1.0f, 0.0f, 0.0f, 0.0f,
+				0.0f, -1.0f, 0.0f, 0.0f,
+				0.0f, 0.0f, 1.0f, 0.0f,
+				0.0f, 0.0f, 0.0f, 1.0f
+				);
+			break;
+
+		case DisplayOrientations::PortraitFlipped:
+			rotation = DXGI_MODE_ROTATION_ROTATE90;
+			m_orientationTransform3D = XMFLOAT4X4( // 270-degree Z-rotation
+				0.0f, -1.0f, 0.0f, 0.0f,
+				1.0f, 0.0f, 0.0f, 0.0f,
+				0.0f, 0.0f, 1.0f, 0.0f,
+				0.0f, 0.0f, 0.0f, 1.0f
+				);
+			break;
+
+		default:
+			throw ref new Platform::FailureException();
+	}
+
+	DX::ThrowIfFailed(
+		m_swapChain->SetRotation(rotation)
+		);
+
+	// Create a render target view of the swap chain back buffer.
+	ComPtr<ID3D11Texture2D> backBuffer;
+	DX::ThrowIfFailed(
+		m_swapChain->GetBuffer(
+			0,
+			__uuidof(ID3D11Texture2D),
+			&backBuffer
+			)
+		);
+
+	DX::ThrowIfFailed(
+		m_d3dDevice->CreateRenderTargetView(
+			backBuffer.Get(),
+			nullptr,
+			&m_renderTargetView
+			)
+		);
+
+	// Create a depth stencil view.
+	CD3D11_TEXTURE2D_DESC depthStencilDesc(
+		DXGI_FORMAT_D24_UNORM_S8_UINT, 
+		static_cast<UINT>(m_renderTargetSize.Width),
+		static_cast<UINT>(m_renderTargetSize.Height),
+		1,
+		1,
+		D3D11_BIND_DEPTH_STENCIL
+		);
+
+	ComPtr<ID3D11Texture2D> depthStencil;
+	DX::ThrowIfFailed(
+		m_d3dDevice->CreateTexture2D(
+			&depthStencilDesc,
+			nullptr,
+			&depthStencil
+			)
+		);
+
+	CD3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc(D3D11_DSV_DIMENSION_TEXTURE2D);
+	DX::ThrowIfFailed(
+		m_d3dDevice->CreateDepthStencilView(
+			depthStencil.Get(),
+			&depthStencilViewDesc,
+			&m_depthStencilView
+			)
+		);
+
+	// Set the rendering viewport to target the entire window.
+	CD3D11_VIEWPORT viewport(
+		0.0f,
+		0.0f,
+		m_renderTargetSize.Width,
+		m_renderTargetSize.Height
+		);
+
+	m_d3dContext->RSSetViewports(1, &viewport);
+}
+
 void SDL_winrtrenderer::ResizeMainTexture(int w, int h)
 {
     D3D11_TEXTURE2D_DESC textureDesc = {0};
@@ -152,6 +421,22 @@
 		);
 }
 
+// This method is called in the event handler for the SizeChanged event.
+void SDL_winrtrenderer::UpdateForWindowSizeChange()
+{
+	if (m_window->Bounds.Width  != m_windowBounds.Width ||
+		m_window->Bounds.Height != m_windowBounds.Height ||
+		m_orientation != DisplayProperties::CurrentOrientation)
+	{
+		ID3D11RenderTargetView* nullViews[] = {nullptr};
+		m_d3dContext->OMSetRenderTargets(ARRAYSIZE(nullViews), nullViews, nullptr);
+		m_renderTargetView = nullptr;
+		m_depthStencilView = nullptr;
+		m_d3dContext->Flush();
+		CreateWindowSizeDependentResources();
+	}
+}
+
 void SDL_winrtrenderer::Render(SDL_Surface * surface, SDL_Rect * rects, int numrects)
 {
 	const float blackColor[] = { 0.0f, 0.0f, 0.0f, 1.0f };
@@ -237,3 +522,46 @@
 
 	m_d3dContext->Draw(4, 0);
 }
+
+// Method to deliver the final image to the display.
+void SDL_winrtrenderer::Present()
+{
+	// The application may optionally specify "dirty" or "scroll"
+	// rects to improve efficiency in certain scenarios.
+	DXGI_PRESENT_PARAMETERS parameters = {0};
+	parameters.DirtyRectsCount = 0;
+	parameters.pDirtyRects = nullptr;
+	parameters.pScrollRect = nullptr;
+	parameters.pScrollOffset = nullptr;
+	
+	// The first argument instructs DXGI to block until VSync, putting the application
+	// to sleep until the next VSync. This ensures we don't waste any cycles rendering
+	// frames that will never be displayed to the screen.
+	HRESULT hr = m_swapChain->Present1(1, 0, &parameters);
+
+	// Discard the contents of the render target.
+	// This is a valid operation only when the existing contents will be entirely
+	// overwritten. If dirty or scroll rects are used, this call should be removed.
+	m_d3dContext->DiscardView(m_renderTargetView.Get());
+
+	// Discard the contents of the depth stencil.
+	m_d3dContext->DiscardView(m_depthStencilView.Get());
+
+	// If the device was removed either by a disconnect or a driver upgrade, we 
+	// must recreate all device resources.
+	if (hr == DXGI_ERROR_DEVICE_REMOVED)
+	{
+		HandleDeviceLost();
+	}
+	else
+	{
+		DX::ThrowIfFailed(hr);
+	}
+}
+
+// Method to convert a length in device-independent pixels (DIPs) to a length in physical pixels.
+float SDL_winrtrenderer::ConvertDipsToPixels(float dips)
+{
+	static const float dipsPerInch = 96.0f;
+	return floor(dips * DisplayProperties::LogicalDpi / dipsPerInch + 0.5f); // Round to nearest integer.
+}
--- a/src/video/windowsrt/SDL_winrtrenderer.h	Sun Nov 25 17:35:41 2012 -0500
+++ b/src/video/windowsrt/SDL_winrtrenderer.h	Sun Nov 25 19:05:56 2012 -0500
@@ -1,6 +1,7 @@
 #pragma once
 
-#include "Direct3DBase.h"
+#include "DirectXHelper.h"
+#include "SDL.h"
 
 struct VertexPositionColor
 {
@@ -8,22 +9,32 @@
 	DirectX::XMFLOAT2 tex;
 };
 
-// This class renders a simple spinning cube.
-ref class SDL_winrtrenderer sealed : public Direct3DBase
+// Helper class that initializes DirectX APIs for 3D rendering.
+ref class SDL_winrtrenderer
 {
-public:
+internal:
 	SDL_winrtrenderer();
 
-	// Direct3DBase methods.
-	virtual void CreateDeviceResources() override;
+public:
+	virtual void Initialize(Windows::UI::Core::CoreWindow^ window);
+	virtual void HandleDeviceLost();
+	virtual void CreateDeviceResources();
+	virtual void CreateWindowSizeDependentResources();
+	virtual void UpdateForWindowSizeChange();
+	virtual void Present();
+	virtual float ConvertDipsToPixels(float dips);
 
 internal:
-	virtual void Render(SDL_Surface * surface, SDL_Rect * rects, int numrects) override;
+	virtual void Render(SDL_Surface * surface, SDL_Rect * rects, int numrects);
     void ResizeMainTexture(int w, int h);
 
-private:
-	bool m_loadingComplete;
-
+protected private:
+	// Direct3D Objects.
+	Microsoft::WRL::ComPtr<ID3D11Device1> m_d3dDevice;
+	Microsoft::WRL::ComPtr<ID3D11DeviceContext1> m_d3dContext;
+	Microsoft::WRL::ComPtr<IDXGISwapChain1> m_swapChain;
+	Microsoft::WRL::ComPtr<ID3D11RenderTargetView> m_renderTargetView;
+	Microsoft::WRL::ComPtr<ID3D11DepthStencilView> m_depthStencilView;
 	Microsoft::WRL::ComPtr<ID3D11InputLayout> m_inputLayout;
 	Microsoft::WRL::ComPtr<ID3D11Buffer> m_vertexBuffer;
 	Microsoft::WRL::ComPtr<ID3D11VertexShader> m_vertexShader;
@@ -32,5 +43,17 @@
 	Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> m_mainTextureResourceView;
 	Microsoft::WRL::ComPtr<ID3D11SamplerState> m_mainSampler;
 
+	// Cached renderer properties.
+	D3D_FEATURE_LEVEL m_featureLevel;
+	Windows::Foundation::Size m_renderTargetSize;
+	Windows::Foundation::Rect m_windowBounds;
+	Platform::Agile<Windows::UI::Core::CoreWindow> m_window;
+	Windows::Graphics::Display::DisplayOrientations m_orientation;
 	uint32 m_vertexCount;
+
+	// Transform used for display orientation.
+	DirectX::XMFLOAT4X4 m_orientationTransform3D;
+
+    // Has the renderer finished loading?
+    bool m_loadingComplete;
 };