src/video/windowsrt/SDL_winrtrenderer.cpp
changeset 8384 bc7a52629e1e
parent 8375 e33eb49b7f42
child 8399 1fa9dcfbeac5
equal deleted inserted replaced
8383:1f415392ccf0 8384:bc7a52629e1e
     9 
     9 
    10 // Constructor.
    10 // Constructor.
    11 SDL_winrtrenderer::SDL_winrtrenderer() :
    11 SDL_winrtrenderer::SDL_winrtrenderer() :
    12     m_mainTextureHelperSurface(NULL),
    12     m_mainTextureHelperSurface(NULL),
    13     m_loadingComplete(false),
    13     m_loadingComplete(false),
    14 	m_vertexCount(0)
    14     m_vertexCount(0)
    15 {
    15 {
    16 }
    16 }
    17 
    17 
    18 SDL_winrtrenderer::~SDL_winrtrenderer()
    18 SDL_winrtrenderer::~SDL_winrtrenderer()
    19 {
    19 {
    24 }
    24 }
    25 
    25 
    26 // Initialize the Direct3D resources required to run.
    26 // Initialize the Direct3D resources required to run.
    27 void SDL_winrtrenderer::Initialize(CoreWindow^ window)
    27 void SDL_winrtrenderer::Initialize(CoreWindow^ window)
    28 {
    28 {
    29 	m_window = window;
    29     m_window = window;
    30 	
    30     
    31 	CreateDeviceResources();
    31     CreateDeviceResources();
    32 	CreateWindowSizeDependentResources();
    32     CreateWindowSizeDependentResources();
    33 }
    33 }
    34 
    34 
    35 // Recreate all device resources and set them back to the current state.
    35 // Recreate all device resources and set them back to the current state.
    36 void SDL_winrtrenderer::HandleDeviceLost()
    36 void SDL_winrtrenderer::HandleDeviceLost()
    37 {
    37 {
    38 	// Reset these member variables to ensure that UpdateForWindowSizeChange recreates all resources.
    38     // Reset these member variables to ensure that UpdateForWindowSizeChange recreates all resources.
    39 	m_windowBounds.Width = 0;
    39     m_windowBounds.Width = 0;
    40 	m_windowBounds.Height = 0;
    40     m_windowBounds.Height = 0;
    41 	m_swapChain = nullptr;
    41     m_swapChain = nullptr;
    42 
    42 
    43 	CreateDeviceResources();
    43     CreateDeviceResources();
    44 	UpdateForWindowSizeChange();
    44     UpdateForWindowSizeChange();
    45 }
    45 }
    46 
    46 
    47 // These are the resources that depend on the device.
    47 // These are the resources that depend on the device.
    48 void SDL_winrtrenderer::CreateDeviceResources()
    48 void SDL_winrtrenderer::CreateDeviceResources()
    49 {
    49 {
    50 	// This flag adds support for surfaces with a different color channel ordering
    50     // This flag adds support for surfaces with a different color channel ordering
    51 	// than the API default. It is required for compatibility with Direct2D.
    51     // than the API default. It is required for compatibility with Direct2D.
    52 	UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
    52     UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
    53 
    53 
    54 #if defined(_DEBUG)
    54 #if defined(_DEBUG)
    55 	// If the project is in a debug build, enable debugging via SDK Layers with this flag.
    55     // If the project is in a debug build, enable debugging via SDK Layers with this flag.
    56 	creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
    56     creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
    57 #endif
    57 #endif
    58 
    58 
    59 	// This array defines the set of DirectX hardware feature levels this app will support.
    59     // This array defines the set of DirectX hardware feature levels this app will support.
    60 	// Note the ordering should be preserved.
    60     // Note the ordering should be preserved.
    61 	// Don't forget to declare your application's minimum required feature level in its
    61     // Don't forget to declare your application's minimum required feature level in its
    62 	// description.  All applications are assumed to support 9.1 unless otherwise stated.
    62     // description.  All applications are assumed to support 9.1 unless otherwise stated.
    63 	D3D_FEATURE_LEVEL featureLevels[] = 
    63     D3D_FEATURE_LEVEL featureLevels[] = 
    64 	{
    64     {
    65 		D3D_FEATURE_LEVEL_11_1,
    65         D3D_FEATURE_LEVEL_11_1,
    66 		D3D_FEATURE_LEVEL_11_0,
    66         D3D_FEATURE_LEVEL_11_0,
    67 		D3D_FEATURE_LEVEL_10_1,
    67         D3D_FEATURE_LEVEL_10_1,
    68 		D3D_FEATURE_LEVEL_10_0,
    68         D3D_FEATURE_LEVEL_10_0,
    69 		D3D_FEATURE_LEVEL_9_3,
    69         D3D_FEATURE_LEVEL_9_3,
    70 		D3D_FEATURE_LEVEL_9_2,
    70         D3D_FEATURE_LEVEL_9_2,
    71 		D3D_FEATURE_LEVEL_9_1
    71         D3D_FEATURE_LEVEL_9_1
    72 	};
    72     };
    73 
    73 
    74 	// Create the Direct3D 11 API device object and a corresponding context.
    74     // Create the Direct3D 11 API device object and a corresponding context.
    75 	ComPtr<ID3D11Device> device;
    75     ComPtr<ID3D11Device> device;
    76 	ComPtr<ID3D11DeviceContext> context;
    76     ComPtr<ID3D11DeviceContext> context;
    77 	DX::ThrowIfFailed(
    77     DX::ThrowIfFailed(
    78 		D3D11CreateDevice(
    78         D3D11CreateDevice(
    79 			nullptr, // Specify nullptr to use the default adapter.
    79             nullptr, // Specify nullptr to use the default adapter.
    80 			D3D_DRIVER_TYPE_HARDWARE,
    80             D3D_DRIVER_TYPE_HARDWARE,
    81 			nullptr,
    81             nullptr,
    82 			creationFlags, // Set set debug and Direct2D compatibility flags.
    82             creationFlags, // Set set debug and Direct2D compatibility flags.
    83 			featureLevels, // List of feature levels this app can support.
    83             featureLevels, // List of feature levels this app can support.
    84 			ARRAYSIZE(featureLevels),
    84             ARRAYSIZE(featureLevels),
    85 			D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION for Windows Store apps.
    85             D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION for Windows Store apps.
    86 			&device, // Returns the Direct3D device created.
    86             &device, // Returns the Direct3D device created.
    87 			&m_featureLevel, // Returns feature level of device created.
    87             &m_featureLevel, // Returns feature level of device created.
    88 			&context // Returns the device immediate context.
    88             &context // Returns the device immediate context.
    89 			)
    89             )
    90 		);
    90         );
    91 
    91 
    92 	// Get the Direct3D 11.1 API device and context interfaces.
    92     // Get the Direct3D 11.1 API device and context interfaces.
    93 	DX::ThrowIfFailed(
    93     DX::ThrowIfFailed(
    94 		device.As(&m_d3dDevice)
    94         device.As(&m_d3dDevice)
    95 		);
    95         );
    96 
    96 
    97 	DX::ThrowIfFailed(
    97     DX::ThrowIfFailed(
    98 		context.As(&m_d3dContext)
    98         context.As(&m_d3dContext)
    99 		);
    99         );
   100 
   100 
   101     auto loadVSTask = DX::ReadDataAsync("SDL_VS2012_WinRT\\SimpleVertexShader.cso");
   101     auto loadVSTask = DX::ReadDataAsync("SDL_VS2012_WinRT\\SimpleVertexShader.cso");
   102 	auto loadPSTask = DX::ReadDataAsync("SDL_VS2012_WinRT\\SimplePixelShader.cso");
   102     auto loadPSTask = DX::ReadDataAsync("SDL_VS2012_WinRT\\SimplePixelShader.cso");
   103 
   103 
   104 	auto createVSTask = loadVSTask.then([this](Platform::Array<byte>^ fileData) {
   104     auto createVSTask = loadVSTask.then([this](Platform::Array<byte>^ fileData) {
   105 		DX::ThrowIfFailed(
   105         DX::ThrowIfFailed(
   106 			m_d3dDevice->CreateVertexShader(
   106             m_d3dDevice->CreateVertexShader(
   107  				fileData->Data,
   107                 fileData->Data,
   108 				fileData->Length,
   108                 fileData->Length,
   109 				nullptr,
   109                 nullptr,
   110 				&m_vertexShader
   110                 &m_vertexShader
   111 				)
   111                 )
   112 			);
   112             );
   113 
   113 
   114 		const D3D11_INPUT_ELEMENT_DESC vertexDesc[] = 
   114         const D3D11_INPUT_ELEMENT_DESC vertexDesc[] = 
   115 		{
   115         {
   116 			{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0,  D3D11_INPUT_PER_VERTEX_DATA, 0 },
   116             { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0,  D3D11_INPUT_PER_VERTEX_DATA, 0 },
   117 			{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
   117             { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
   118 		};
   118         };
   119 
   119 
   120 		DX::ThrowIfFailed(
   120         DX::ThrowIfFailed(
   121 			m_d3dDevice->CreateInputLayout(
   121             m_d3dDevice->CreateInputLayout(
   122 				vertexDesc,
   122                 vertexDesc,
   123 				ARRAYSIZE(vertexDesc),
   123                 ARRAYSIZE(vertexDesc),
   124 				fileData->Data,
   124                 fileData->Data,
   125 				fileData->Length,
   125                 fileData->Length,
   126 				&m_inputLayout
   126                 &m_inputLayout
   127 				)
   127                 )
   128 			);
   128             );
   129 	});
   129     });
   130 
   130 
   131 	auto createPSTask = loadPSTask.then([this](Platform::Array<byte>^ fileData) {
   131     auto createPSTask = loadPSTask.then([this](Platform::Array<byte>^ fileData) {
   132 		DX::ThrowIfFailed(
   132         DX::ThrowIfFailed(
   133 			m_d3dDevice->CreatePixelShader(
   133             m_d3dDevice->CreatePixelShader(
   134 				fileData->Data,
   134                 fileData->Data,
   135 				fileData->Length,
   135                 fileData->Length,
   136 				nullptr,
   136                 nullptr,
   137 				&m_pixelShader
   137                 &m_pixelShader
   138 				)
   138                 )
   139 			);
   139             );
   140 	});
   140     });
   141 
   141 
   142 	auto createVertexBuffer = (createPSTask && createVSTask).then([this] () {
   142     auto createVertexBuffer = (createPSTask && createVSTask).then([this] () {
   143 		VertexPositionColor vertices[] = 
   143         VertexPositionColor vertices[] = 
   144 		{
   144         {
   145 			{XMFLOAT3(-1.0f, -1.0f, 0.0f),  XMFLOAT2(0.0f, 1.0f)},
   145             {XMFLOAT3(-1.0f, -1.0f, 0.0f),  XMFLOAT2(0.0f, 1.0f)},
   146 			{XMFLOAT3(-1.0f, 1.0f, 0.0f), XMFLOAT2(0.0f, 0.0f)},
   146             {XMFLOAT3(-1.0f, 1.0f, 0.0f), XMFLOAT2(0.0f, 0.0f)},
   147 			{XMFLOAT3(1.0f, -1.0f, 0.0f), XMFLOAT2(1.0f, 1.0f)},
   147             {XMFLOAT3(1.0f, -1.0f, 0.0f), XMFLOAT2(1.0f, 1.0f)},
   148 			{XMFLOAT3(1.0f, 1.0f, 0.0f), XMFLOAT2(1.0f, 0.0f)},
   148             {XMFLOAT3(1.0f, 1.0f, 0.0f), XMFLOAT2(1.0f, 0.0f)},
   149 		};
   149         };
   150 
   150 
   151 		m_vertexCount = ARRAYSIZE(vertices);
   151         m_vertexCount = ARRAYSIZE(vertices);
   152 
   152 
   153 		D3D11_SUBRESOURCE_DATA vertexBufferData = {0};
   153         D3D11_SUBRESOURCE_DATA vertexBufferData = {0};
   154 		vertexBufferData.pSysMem = vertices;
   154         vertexBufferData.pSysMem = vertices;
   155 		vertexBufferData.SysMemPitch = 0;
   155         vertexBufferData.SysMemPitch = 0;
   156 		vertexBufferData.SysMemSlicePitch = 0;
   156         vertexBufferData.SysMemSlicePitch = 0;
   157 		CD3D11_BUFFER_DESC vertexBufferDesc(sizeof(vertices), D3D11_BIND_VERTEX_BUFFER);
   157         CD3D11_BUFFER_DESC vertexBufferDesc(sizeof(vertices), D3D11_BIND_VERTEX_BUFFER);
   158 		DX::ThrowIfFailed(
   158         DX::ThrowIfFailed(
   159 			m_d3dDevice->CreateBuffer(
   159             m_d3dDevice->CreateBuffer(
   160 				&vertexBufferDesc,
   160                 &vertexBufferDesc,
   161 				&vertexBufferData,
   161                 &vertexBufferData,
   162 				&m_vertexBuffer
   162                 &m_vertexBuffer
   163 				)
   163                 )
   164 			);
   164             );
   165 	});
   165     });
   166 
   166 
   167     auto createMainSamplerTask = createVertexBuffer.then([this] () {
   167     auto createMainSamplerTask = createVertexBuffer.then([this] () {
   168 		D3D11_SAMPLER_DESC samplerDesc;
   168         D3D11_SAMPLER_DESC samplerDesc;
   169 		samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
   169         samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
   170 		samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
   170         samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
   171 		samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
   171         samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
   172 		samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
   172         samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
   173 		samplerDesc.MipLODBias = 0.0f;
   173         samplerDesc.MipLODBias = 0.0f;
   174 		samplerDesc.MaxAnisotropy = 1;
   174         samplerDesc.MaxAnisotropy = 1;
   175 		samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
   175         samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
   176 		samplerDesc.BorderColor[0] = 0.0f;
   176         samplerDesc.BorderColor[0] = 0.0f;
   177 		samplerDesc.BorderColor[1] = 0.0f;
   177         samplerDesc.BorderColor[1] = 0.0f;
   178 		samplerDesc.BorderColor[2] = 0.0f;
   178         samplerDesc.BorderColor[2] = 0.0f;
   179 		samplerDesc.BorderColor[3] = 0.0f;
   179         samplerDesc.BorderColor[3] = 0.0f;
   180 		samplerDesc.MinLOD = 0.0f;
   180         samplerDesc.MinLOD = 0.0f;
   181 		samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
   181         samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
   182 		DX::ThrowIfFailed(
   182         DX::ThrowIfFailed(
   183 			m_d3dDevice->CreateSamplerState(
   183             m_d3dDevice->CreateSamplerState(
   184 				&samplerDesc,
   184                 &samplerDesc,
   185 				&m_mainSampler
   185                 &m_mainSampler
   186 				)
   186                 )
   187 			);
   187             );
   188 	});
   188     });
   189 
   189 
   190 	createMainSamplerTask.then([this] () {
   190     createMainSamplerTask.then([this] () {
   191 		m_loadingComplete = true;
   191         m_loadingComplete = true;
   192 	});
   192     });
   193 }
   193 }
   194 
   194 
   195 // Allocate all memory resources that change on a window SizeChanged event.
   195 // Allocate all memory resources that change on a window SizeChanged event.
   196 void SDL_winrtrenderer::CreateWindowSizeDependentResources()
   196 void SDL_winrtrenderer::CreateWindowSizeDependentResources()
   197 { 
   197 { 
   198 	// Store the window bounds so the next time we get a SizeChanged event we can
   198     // Store the window bounds so the next time we get a SizeChanged event we can
   199 	// avoid rebuilding everything if the size is identical.
   199     // avoid rebuilding everything if the size is identical.
   200 	m_windowBounds = m_window->Bounds;
   200     m_windowBounds = m_window->Bounds;
   201 
   201 
   202 	// Calculate the necessary swap chain and render target size in pixels.
   202     // Calculate the necessary swap chain and render target size in pixels.
   203 	float windowWidth = ConvertDipsToPixels(m_windowBounds.Width);
   203     float windowWidth = ConvertDipsToPixels(m_windowBounds.Width);
   204 	float windowHeight = ConvertDipsToPixels(m_windowBounds.Height);
   204     float windowHeight = ConvertDipsToPixels(m_windowBounds.Height);
   205 
   205 
   206 	// The width and height of the swap chain must be based on the window's
   206     // The width and height of the swap chain must be based on the window's
   207 	// landscape-oriented width and height. If the window is in a portrait
   207     // landscape-oriented width and height. If the window is in a portrait
   208 	// orientation, the dimensions must be reversed.
   208     // orientation, the dimensions must be reversed.
   209 	m_orientation = DisplayProperties::CurrentOrientation;
   209     m_orientation = DisplayProperties::CurrentOrientation;
   210 	bool swapDimensions =
   210     bool swapDimensions =
   211 		m_orientation == DisplayOrientations::Portrait ||
   211         m_orientation == DisplayOrientations::Portrait ||
   212 		m_orientation == DisplayOrientations::PortraitFlipped;
   212         m_orientation == DisplayOrientations::PortraitFlipped;
   213 	m_renderTargetSize.Width = swapDimensions ? windowHeight : windowWidth;
   213     m_renderTargetSize.Width = swapDimensions ? windowHeight : windowWidth;
   214 	m_renderTargetSize.Height = swapDimensions ? windowWidth : windowHeight;
   214     m_renderTargetSize.Height = swapDimensions ? windowWidth : windowHeight;
   215 
   215 
   216 	if(m_swapChain != nullptr)
   216     if(m_swapChain != nullptr)
   217 	{
   217     {
   218 		// If the swap chain already exists, resize it.
   218         // If the swap chain already exists, resize it.
   219 		DX::ThrowIfFailed(
   219         DX::ThrowIfFailed(
   220 			m_swapChain->ResizeBuffers(
   220             m_swapChain->ResizeBuffers(
   221 				2, // Double-buffered swap chain.
   221                 2, // Double-buffered swap chain.
   222 				static_cast<UINT>(m_renderTargetSize.Width),
   222                 static_cast<UINT>(m_renderTargetSize.Width),
   223 				static_cast<UINT>(m_renderTargetSize.Height),
   223                 static_cast<UINT>(m_renderTargetSize.Height),
   224 				DXGI_FORMAT_B8G8R8A8_UNORM,
   224                 DXGI_FORMAT_B8G8R8A8_UNORM,
   225 				0
   225                 0
   226 				)
   226                 )
   227 			);
   227             );
   228 	}
   228     }
   229 	else
   229     else
   230 	{
   230     {
   231 		// Otherwise, create a new one using the same adapter as the existing Direct3D device.
   231         // Otherwise, create a new one using the same adapter as the existing Direct3D device.
   232 		DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
   232         DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
   233 		swapChainDesc.Width = static_cast<UINT>(m_renderTargetSize.Width); // Match the size of the window.
   233         swapChainDesc.Width = static_cast<UINT>(m_renderTargetSize.Width); // Match the size of the window.
   234 		swapChainDesc.Height = static_cast<UINT>(m_renderTargetSize.Height);
   234         swapChainDesc.Height = static_cast<UINT>(m_renderTargetSize.Height);
   235 		swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // This is the most common swap chain format.
   235         swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // This is the most common swap chain format.
   236 		swapChainDesc.Stereo = false;
   236         swapChainDesc.Stereo = false;
   237 		swapChainDesc.SampleDesc.Count = 1; // Don't use multi-sampling.
   237         swapChainDesc.SampleDesc.Count = 1; // Don't use multi-sampling.
   238 		swapChainDesc.SampleDesc.Quality = 0;
   238         swapChainDesc.SampleDesc.Quality = 0;
   239 		swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
   239         swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
   240 		swapChainDesc.BufferCount = 2; // Use double-buffering to minimize latency.
   240         swapChainDesc.BufferCount = 2; // Use double-buffering to minimize latency.
   241 		swapChainDesc.Scaling = DXGI_SCALING_NONE;
   241         swapChainDesc.Scaling = DXGI_SCALING_NONE;
   242 		swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // All Windows Store apps must use this SwapEffect.
   242         swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // All Windows Store apps must use this SwapEffect.
   243 		swapChainDesc.Flags = 0;
   243         swapChainDesc.Flags = 0;
   244 
   244 
   245 		ComPtr<IDXGIDevice1>  dxgiDevice;
   245         ComPtr<IDXGIDevice1>  dxgiDevice;
   246 		DX::ThrowIfFailed(
   246         DX::ThrowIfFailed(
   247 			m_d3dDevice.As(&dxgiDevice)
   247             m_d3dDevice.As(&dxgiDevice)
   248 			);
   248             );
   249 
   249 
   250 		ComPtr<IDXGIAdapter> dxgiAdapter;
   250         ComPtr<IDXGIAdapter> dxgiAdapter;
   251 		DX::ThrowIfFailed(
   251         DX::ThrowIfFailed(
   252 			dxgiDevice->GetAdapter(&dxgiAdapter)
   252             dxgiDevice->GetAdapter(&dxgiAdapter)
   253 			);
   253             );
   254 
   254 
   255 		ComPtr<IDXGIFactory2> dxgiFactory;
   255         ComPtr<IDXGIFactory2> dxgiFactory;
   256 		DX::ThrowIfFailed(
   256         DX::ThrowIfFailed(
   257 			dxgiAdapter->GetParent(
   257             dxgiAdapter->GetParent(
   258 				__uuidof(IDXGIFactory2), 
   258                 __uuidof(IDXGIFactory2), 
   259 				&dxgiFactory
   259                 &dxgiFactory
   260 				)
   260                 )
   261 			);
   261             );
   262 
   262 
   263 		Windows::UI::Core::CoreWindow^ window = m_window.Get();
   263         Windows::UI::Core::CoreWindow^ window = m_window.Get();
   264 		DX::ThrowIfFailed(
   264         DX::ThrowIfFailed(
   265 			dxgiFactory->CreateSwapChainForCoreWindow(
   265             dxgiFactory->CreateSwapChainForCoreWindow(
   266 				m_d3dDevice.Get(),
   266                 m_d3dDevice.Get(),
   267 				reinterpret_cast<IUnknown*>(window),
   267                 reinterpret_cast<IUnknown*>(window),
   268 				&swapChainDesc,
   268                 &swapChainDesc,
   269 				nullptr, // Allow on all displays.
   269                 nullptr, // Allow on all displays.
   270 				&m_swapChain
   270                 &m_swapChain
   271 				)
   271                 )
   272 			);
   272             );
   273 			
   273             
   274 		// Ensure that DXGI does not queue more than one frame at a time. This both reduces latency and
   274         // Ensure that DXGI does not queue more than one frame at a time. This both reduces latency and
   275 		// ensures that the application will only render after each VSync, minimizing power consumption.
   275         // ensures that the application will only render after each VSync, minimizing power consumption.
   276 		DX::ThrowIfFailed(
   276         DX::ThrowIfFailed(
   277 			dxgiDevice->SetMaximumFrameLatency(1)
   277             dxgiDevice->SetMaximumFrameLatency(1)
   278 			);
   278             );
   279 	}
   279     }
   280 	
   280     
   281 	// Set the proper orientation for the swap chain, and generate the
   281     // Set the proper orientation for the swap chain, and generate the
   282 	// 3D matrix transformation for rendering to the rotated swap chain.
   282     // 3D matrix transformation for rendering to the rotated swap chain.
   283 	DXGI_MODE_ROTATION rotation = DXGI_MODE_ROTATION_UNSPECIFIED;
   283     DXGI_MODE_ROTATION rotation = DXGI_MODE_ROTATION_UNSPECIFIED;
   284 	switch (m_orientation)
   284     switch (m_orientation)
   285 	{
   285     {
   286 		case DisplayOrientations::Landscape:
   286         case DisplayOrientations::Landscape:
   287 			rotation = DXGI_MODE_ROTATION_IDENTITY;
   287             rotation = DXGI_MODE_ROTATION_IDENTITY;
   288 			m_orientationTransform3D = XMFLOAT4X4( // 0-degree Z-rotation
   288             m_orientationTransform3D = XMFLOAT4X4( // 0-degree Z-rotation
   289 				1.0f, 0.0f, 0.0f, 0.0f,
   289                 1.0f, 0.0f, 0.0f, 0.0f,
   290 				0.0f, 1.0f, 0.0f, 0.0f,
   290                 0.0f, 1.0f, 0.0f, 0.0f,
   291 				0.0f, 0.0f, 1.0f, 0.0f,
   291                 0.0f, 0.0f, 1.0f, 0.0f,
   292 				0.0f, 0.0f, 0.0f, 1.0f
   292                 0.0f, 0.0f, 0.0f, 1.0f
   293 				);
   293                 );
   294 			break;
   294             break;
   295 
   295 
   296 		case DisplayOrientations::Portrait:
   296         case DisplayOrientations::Portrait:
   297 			rotation = DXGI_MODE_ROTATION_ROTATE270;
   297             rotation = DXGI_MODE_ROTATION_ROTATE270;
   298 			m_orientationTransform3D = XMFLOAT4X4( // 90-degree Z-rotation
   298             m_orientationTransform3D = XMFLOAT4X4( // 90-degree Z-rotation
   299 				0.0f, 1.0f, 0.0f, 0.0f,
   299                 0.0f, 1.0f, 0.0f, 0.0f,
   300 				-1.0f, 0.0f, 0.0f, 0.0f,
   300                 -1.0f, 0.0f, 0.0f, 0.0f,
   301 				0.0f, 0.0f, 1.0f, 0.0f,
   301                 0.0f, 0.0f, 1.0f, 0.0f,
   302 				0.0f, 0.0f, 0.0f, 1.0f
   302                 0.0f, 0.0f, 0.0f, 1.0f
   303 				);
   303                 );
   304 			break;
   304             break;
   305 
   305 
   306 		case DisplayOrientations::LandscapeFlipped:
   306         case DisplayOrientations::LandscapeFlipped:
   307 			rotation = DXGI_MODE_ROTATION_ROTATE180;
   307             rotation = DXGI_MODE_ROTATION_ROTATE180;
   308 			m_orientationTransform3D = XMFLOAT4X4( // 180-degree Z-rotation
   308             m_orientationTransform3D = XMFLOAT4X4( // 180-degree Z-rotation
   309 				-1.0f, 0.0f, 0.0f, 0.0f,
   309                 -1.0f, 0.0f, 0.0f, 0.0f,
   310 				0.0f, -1.0f, 0.0f, 0.0f,
   310                 0.0f, -1.0f, 0.0f, 0.0f,
   311 				0.0f, 0.0f, 1.0f, 0.0f,
   311                 0.0f, 0.0f, 1.0f, 0.0f,
   312 				0.0f, 0.0f, 0.0f, 1.0f
   312                 0.0f, 0.0f, 0.0f, 1.0f
   313 				);
   313                 );
   314 			break;
   314             break;
   315 
   315 
   316 		case DisplayOrientations::PortraitFlipped:
   316         case DisplayOrientations::PortraitFlipped:
   317 			rotation = DXGI_MODE_ROTATION_ROTATE90;
   317             rotation = DXGI_MODE_ROTATION_ROTATE90;
   318 			m_orientationTransform3D = XMFLOAT4X4( // 270-degree Z-rotation
   318             m_orientationTransform3D = XMFLOAT4X4( // 270-degree Z-rotation
   319 				0.0f, -1.0f, 0.0f, 0.0f,
   319                 0.0f, -1.0f, 0.0f, 0.0f,
   320 				1.0f, 0.0f, 0.0f, 0.0f,
   320                 1.0f, 0.0f, 0.0f, 0.0f,
   321 				0.0f, 0.0f, 1.0f, 0.0f,
   321                 0.0f, 0.0f, 1.0f, 0.0f,
   322 				0.0f, 0.0f, 0.0f, 1.0f
   322                 0.0f, 0.0f, 0.0f, 1.0f
   323 				);
   323                 );
   324 			break;
   324             break;
   325 
   325 
   326 		default:
   326         default:
   327 			throw ref new Platform::FailureException();
   327             throw ref new Platform::FailureException();
   328 	}
   328     }
   329 
   329 
   330 	DX::ThrowIfFailed(
   330     DX::ThrowIfFailed(
   331 		m_swapChain->SetRotation(rotation)
   331         m_swapChain->SetRotation(rotation)
   332 		);
   332         );
   333 
   333 
   334 	// Create a render target view of the swap chain back buffer.
   334     // Create a render target view of the swap chain back buffer.
   335 	ComPtr<ID3D11Texture2D> backBuffer;
   335     ComPtr<ID3D11Texture2D> backBuffer;
   336 	DX::ThrowIfFailed(
   336     DX::ThrowIfFailed(
   337 		m_swapChain->GetBuffer(
   337         m_swapChain->GetBuffer(
   338 			0,
   338             0,
   339 			__uuidof(ID3D11Texture2D),
   339             __uuidof(ID3D11Texture2D),
   340 			&backBuffer
   340             &backBuffer
   341 			)
   341             )
   342 		);
   342         );
   343 
   343 
   344 	DX::ThrowIfFailed(
   344     DX::ThrowIfFailed(
   345 		m_d3dDevice->CreateRenderTargetView(
   345         m_d3dDevice->CreateRenderTargetView(
   346 			backBuffer.Get(),
   346             backBuffer.Get(),
   347 			nullptr,
   347             nullptr,
   348 			&m_renderTargetView
   348             &m_renderTargetView
   349 			)
   349             )
   350 		);
   350         );
   351 
   351 
   352 	// Create a depth stencil view.
   352     // Create a depth stencil view.
   353 	CD3D11_TEXTURE2D_DESC depthStencilDesc(
   353     CD3D11_TEXTURE2D_DESC depthStencilDesc(
   354 		DXGI_FORMAT_D24_UNORM_S8_UINT, 
   354         DXGI_FORMAT_D24_UNORM_S8_UINT, 
   355 		static_cast<UINT>(m_renderTargetSize.Width),
   355         static_cast<UINT>(m_renderTargetSize.Width),
   356 		static_cast<UINT>(m_renderTargetSize.Height),
   356         static_cast<UINT>(m_renderTargetSize.Height),
   357 		1,
   357         1,
   358 		1,
   358         1,
   359 		D3D11_BIND_DEPTH_STENCIL
   359         D3D11_BIND_DEPTH_STENCIL
   360 		);
   360         );
   361 
   361 
   362 	ComPtr<ID3D11Texture2D> depthStencil;
   362     ComPtr<ID3D11Texture2D> depthStencil;
   363 	DX::ThrowIfFailed(
   363     DX::ThrowIfFailed(
   364 		m_d3dDevice->CreateTexture2D(
   364         m_d3dDevice->CreateTexture2D(
   365 			&depthStencilDesc,
   365             &depthStencilDesc,
   366 			nullptr,
   366             nullptr,
   367 			&depthStencil
   367             &depthStencil
   368 			)
   368             )
   369 		);
   369         );
   370 
   370 
   371 	// Set the rendering viewport to target the entire window.
   371     // Set the rendering viewport to target the entire window.
   372 	CD3D11_VIEWPORT viewport(
   372     CD3D11_VIEWPORT viewport(
   373 		0.0f,
   373         0.0f,
   374 		0.0f,
   374         0.0f,
   375 		m_renderTargetSize.Width,
   375         m_renderTargetSize.Width,
   376 		m_renderTargetSize.Height
   376         m_renderTargetSize.Height
   377 		);
   377         );
   378 
   378 
   379 	m_d3dContext->RSSetViewports(1, &viewport);
   379     m_d3dContext->RSSetViewports(1, &viewport);
   380 }
   380 }
   381 
   381 
   382 void SDL_winrtrenderer::ResizeMainTexture(int w, int h)
   382 void SDL_winrtrenderer::ResizeMainTexture(int w, int h)
   383 {
   383 {
   384     const int pixelSizeInBytes = 4;
   384     const int pixelSizeInBytes = 4;
   385 
   385 
   386     D3D11_TEXTURE2D_DESC textureDesc = {0};
   386     D3D11_TEXTURE2D_DESC textureDesc = {0};
   387 	textureDesc.Width = w;
   387     textureDesc.Width = w;
   388 	textureDesc.Height = h;
   388     textureDesc.Height = h;
   389 	textureDesc.MipLevels = 1;
   389     textureDesc.MipLevels = 1;
   390 	textureDesc.ArraySize = 1;
   390     textureDesc.ArraySize = 1;
   391 	textureDesc.Format = DXGI_FORMAT_B8G8R8X8_UNORM;
   391     textureDesc.Format = DXGI_FORMAT_B8G8R8X8_UNORM;
   392 	textureDesc.SampleDesc.Count = 1;
   392     textureDesc.SampleDesc.Count = 1;
   393 	textureDesc.SampleDesc.Quality = 0;
   393     textureDesc.SampleDesc.Quality = 0;
   394 	textureDesc.Usage = D3D11_USAGE_DYNAMIC;
   394     textureDesc.Usage = D3D11_USAGE_DYNAMIC;
   395 	textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
   395     textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
   396 	textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
   396     textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
   397 	textureDesc.MiscFlags = 0;
   397     textureDesc.MiscFlags = 0;
   398 
   398 
   399     const int numPixels = textureDesc.Width * textureDesc.Height;
   399     const int numPixels = textureDesc.Width * textureDesc.Height;
   400     std::vector<uint8> initialTexturePixels(numPixels * pixelSizeInBytes, 0x00);
   400     std::vector<uint8> initialTexturePixels(numPixels * pixelSizeInBytes, 0x00);
   401 
   401 
   402     // Fill the texture with a non-black color, for debugging purposes:
   402     // Fill the texture with a non-black color, for debugging purposes:
   405     //    initialTexturePixels[i+1] = 0xff;
   405     //    initialTexturePixels[i+1] = 0xff;
   406     //    initialTexturePixels[i+2] = 0x00;
   406     //    initialTexturePixels[i+2] = 0x00;
   407     //    initialTexturePixels[i+3] = 0xff;
   407     //    initialTexturePixels[i+3] = 0xff;
   408     //}
   408     //}
   409 
   409 
   410 	D3D11_SUBRESOURCE_DATA initialTextureData = {0};
   410     D3D11_SUBRESOURCE_DATA initialTextureData = {0};
   411 	initialTextureData.pSysMem = (void *)&(initialTexturePixels[0]);
   411     initialTextureData.pSysMem = (void *)&(initialTexturePixels[0]);
   412 	initialTextureData.SysMemPitch = textureDesc.Width * pixelSizeInBytes;
   412     initialTextureData.SysMemPitch = textureDesc.Width * pixelSizeInBytes;
   413 	initialTextureData.SysMemSlicePitch = numPixels * pixelSizeInBytes;
   413     initialTextureData.SysMemSlicePitch = numPixels * pixelSizeInBytes;
   414 	DX::ThrowIfFailed(
   414     DX::ThrowIfFailed(
   415 		m_d3dDevice->CreateTexture2D(
   415         m_d3dDevice->CreateTexture2D(
   416 			&textureDesc,
   416             &textureDesc,
   417 			&initialTextureData,
   417             &initialTextureData,
   418 			&m_mainTexture
   418             &m_mainTexture
   419 			)
   419             )
   420 		);
   420         );
   421 
   421 
   422     if (m_mainTextureHelperSurface) {
   422     if (m_mainTextureHelperSurface) {
   423         SDL_FreeSurface(m_mainTextureHelperSurface);
   423         SDL_FreeSurface(m_mainTextureHelperSurface);
   424         m_mainTextureHelperSurface = NULL;
   424         m_mainTextureHelperSurface = NULL;
   425     }
   425     }
   431         0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000);    // TODO, WinRT: calculate masks given the Direct3D-defined pixel format of the texture
   431         0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000);    // TODO, WinRT: calculate masks given the Direct3D-defined pixel format of the texture
   432     if (m_mainTextureHelperSurface == NULL) {
   432     if (m_mainTextureHelperSurface == NULL) {
   433         DX::ThrowIfFailed(E_FAIL);  // TODO, WinRT: generate a better error here, taking into account who's calling this function.
   433         DX::ThrowIfFailed(E_FAIL);  // TODO, WinRT: generate a better error here, taking into account who's calling this function.
   434     }
   434     }
   435 
   435 
   436 	D3D11_SHADER_RESOURCE_VIEW_DESC resourceViewDesc;
   436     D3D11_SHADER_RESOURCE_VIEW_DESC resourceViewDesc;
   437 	resourceViewDesc.Format = textureDesc.Format;
   437     resourceViewDesc.Format = textureDesc.Format;
   438 	resourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
   438     resourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
   439 	resourceViewDesc.Texture2D.MostDetailedMip = 0;
   439     resourceViewDesc.Texture2D.MostDetailedMip = 0;
   440 	resourceViewDesc.Texture2D.MipLevels = textureDesc.MipLevels;
   440     resourceViewDesc.Texture2D.MipLevels = textureDesc.MipLevels;
   441 	DX::ThrowIfFailed(
   441     DX::ThrowIfFailed(
   442 		m_d3dDevice->CreateShaderResourceView(
   442         m_d3dDevice->CreateShaderResourceView(
   443 			m_mainTexture.Get(),
   443             m_mainTexture.Get(),
   444 			&resourceViewDesc,
   444             &resourceViewDesc,
   445 			&m_mainTextureResourceView)
   445             &m_mainTextureResourceView)
   446 		);
   446         );
   447 }
   447 }
   448 
   448 
   449 // This method is called in the event handler for the SizeChanged event.
   449 // This method is called in the event handler for the SizeChanged event.
   450 void SDL_winrtrenderer::UpdateForWindowSizeChange()
   450 void SDL_winrtrenderer::UpdateForWindowSizeChange()
   451 {
   451 {
   452 	if (m_window->Bounds.Width  != m_windowBounds.Width ||
   452     if (m_window->Bounds.Width  != m_windowBounds.Width ||
   453 		m_window->Bounds.Height != m_windowBounds.Height ||
   453         m_window->Bounds.Height != m_windowBounds.Height ||
   454 		m_orientation != DisplayProperties::CurrentOrientation)
   454         m_orientation != DisplayProperties::CurrentOrientation)
   455 	{
   455     {
   456 		ID3D11RenderTargetView* nullViews[] = {nullptr};
   456         ID3D11RenderTargetView* nullViews[] = {nullptr};
   457 		m_d3dContext->OMSetRenderTargets(ARRAYSIZE(nullViews), nullViews, nullptr);
   457         m_d3dContext->OMSetRenderTargets(ARRAYSIZE(nullViews), nullViews, nullptr);
   458 		m_renderTargetView = nullptr;
   458         m_renderTargetView = nullptr;
   459 		m_d3dContext->Flush();
   459         m_d3dContext->Flush();
   460 		CreateWindowSizeDependentResources();
   460         CreateWindowSizeDependentResources();
   461 	}
   461     }
   462 }
   462 }
   463 
   463 
   464 void SDL_winrtrenderer::Render(SDL_Surface * surface, SDL_Rect * rects, int numrects)
   464 void SDL_winrtrenderer::Render(SDL_Surface * surface, SDL_Rect * rects, int numrects)
   465 {
   465 {
   466 	const float blackColor[] = { 0.0f, 0.0f, 0.0f, 0.0f };
   466     const float blackColor[] = { 0.0f, 0.0f, 0.0f, 0.0f };
   467 	m_d3dContext->ClearRenderTargetView(
   467     m_d3dContext->ClearRenderTargetView(
   468 		m_renderTargetView.Get(),
   468         m_renderTargetView.Get(),
   469 		blackColor
   469         blackColor
   470 		);
   470         );
   471 
   471 
   472 	// Only draw the screen once it is loaded (some loading is asynchronous).
   472     // Only draw the screen once it is loaded (some loading is asynchronous).
   473 	if (!m_loadingComplete)
   473     if (!m_loadingComplete)
   474 	{
   474     {
   475 		return;
   475         return;
   476 	}
   476     }
   477     if (!m_mainTextureResourceView)
   477     if (!m_mainTextureResourceView)
   478     {
   478     {
   479         return;
   479         return;
   480     }
   480     }
   481 
   481 
   482 	// Update the main texture (for SDL usage).  Start by mapping the SDL
   482     // Update the main texture (for SDL usage).  Start by mapping the SDL
   483     // window's main texture to CPU-accessible memory:
   483     // window's main texture to CPU-accessible memory:
   484 	D3D11_MAPPED_SUBRESOURCE textureMemory = {0};
   484     D3D11_MAPPED_SUBRESOURCE textureMemory = {0};
   485 	DX::ThrowIfFailed(
   485     DX::ThrowIfFailed(
   486 		m_d3dContext->Map(
   486         m_d3dContext->Map(
   487 			m_mainTexture.Get(),
   487             m_mainTexture.Get(),
   488 			0,
   488             0,
   489 			D3D11_MAP_WRITE_DISCARD,
   489             D3D11_MAP_WRITE_DISCARD,
   490 			0,
   490             0,
   491 			&textureMemory)
   491             &textureMemory)
   492 		);
   492         );
   493 
   493 
   494     // Copy pixel data to the locked texture's memory:
   494     // Copy pixel data to the locked texture's memory:
   495     m_mainTextureHelperSurface->pixels = textureMemory.pData;
   495     m_mainTextureHelperSurface->pixels = textureMemory.pData;
   496     m_mainTextureHelperSurface->pitch = textureMemory.RowPitch;
   496     m_mainTextureHelperSurface->pitch = textureMemory.RowPitch;
   497     SDL_BlitSurface(surface, NULL, m_mainTextureHelperSurface, NULL);
   497     SDL_BlitSurface(surface, NULL, m_mainTextureHelperSurface, NULL);
   498 	// TODO, WinRT: only update the requested rects (passed to SDL_UpdateWindowSurface), rather than everything
   498     // TODO, WinRT: only update the requested rects (passed to SDL_UpdateWindowSurface), rather than everything
   499 
   499 
   500     // Clean up a bit, then commit the texture's memory back to Direct3D:
   500     // Clean up a bit, then commit the texture's memory back to Direct3D:
   501     m_mainTextureHelperSurface->pixels = NULL;
   501     m_mainTextureHelperSurface->pixels = NULL;
   502     m_mainTextureHelperSurface->pitch = 0;
   502     m_mainTextureHelperSurface->pitch = 0;
   503 	m_d3dContext->Unmap(
   503     m_d3dContext->Unmap(
   504 		m_mainTexture.Get(),
   504         m_mainTexture.Get(),
   505 		0);
   505         0);
   506 
   506 
   507 	m_d3dContext->OMSetRenderTargets(
   507     m_d3dContext->OMSetRenderTargets(
   508 		1,
   508         1,
   509 		m_renderTargetView.GetAddressOf(),
   509         m_renderTargetView.GetAddressOf(),
   510 		nullptr
   510         nullptr
   511 		);
   511         );
   512 
   512 
   513 	UINT stride = sizeof(VertexPositionColor);
   513     UINT stride = sizeof(VertexPositionColor);
   514 	UINT offset = 0;
   514     UINT offset = 0;
   515 	m_d3dContext->IASetVertexBuffers(
   515     m_d3dContext->IASetVertexBuffers(
   516 		0,
   516         0,
   517 		1,
   517         1,
   518 		m_vertexBuffer.GetAddressOf(),
   518         m_vertexBuffer.GetAddressOf(),
   519 		&stride,
   519         &stride,
   520 		&offset
   520         &offset
   521 		);
   521         );
   522 
   522 
   523 	m_d3dContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
   523     m_d3dContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
   524 
   524 
   525 	m_d3dContext->IASetInputLayout(m_inputLayout.Get());
   525     m_d3dContext->IASetInputLayout(m_inputLayout.Get());
   526 
   526 
   527 	m_d3dContext->VSSetShader(
   527     m_d3dContext->VSSetShader(
   528 		m_vertexShader.Get(),
   528         m_vertexShader.Get(),
   529 		nullptr,
   529         nullptr,
   530 		0
   530         0
   531 		);
   531         );
   532 
   532 
   533 	m_d3dContext->PSSetShader(
   533     m_d3dContext->PSSetShader(
   534 		m_pixelShader.Get(),
   534         m_pixelShader.Get(),
   535 		nullptr,
   535         nullptr,
   536 		0
   536         0
   537 		);
   537         );
   538 
   538 
   539 	m_d3dContext->PSSetShaderResources(0, 1, m_mainTextureResourceView.GetAddressOf());
   539     m_d3dContext->PSSetShaderResources(0, 1, m_mainTextureResourceView.GetAddressOf());
   540 
   540 
   541 	m_d3dContext->PSSetSamplers(0, 1, m_mainSampler.GetAddressOf());
   541     m_d3dContext->PSSetSamplers(0, 1, m_mainSampler.GetAddressOf());
   542 
   542 
   543 	m_d3dContext->Draw(4, 0);
   543     m_d3dContext->Draw(4, 0);
   544 }
   544 }
   545 
   545 
   546 // Method to deliver the final image to the display.
   546 // Method to deliver the final image to the display.
   547 void SDL_winrtrenderer::Present()
   547 void SDL_winrtrenderer::Present()
   548 {
   548 {
   549 	// The application may optionally specify "dirty" or "scroll"
   549     // The application may optionally specify "dirty" or "scroll"
   550 	// rects to improve efficiency in certain scenarios.
   550     // rects to improve efficiency in certain scenarios.
   551 	DXGI_PRESENT_PARAMETERS parameters = {0};
   551     DXGI_PRESENT_PARAMETERS parameters = {0};
   552 	parameters.DirtyRectsCount = 0;
   552     parameters.DirtyRectsCount = 0;
   553 	parameters.pDirtyRects = nullptr;
   553     parameters.pDirtyRects = nullptr;
   554 	parameters.pScrollRect = nullptr;
   554     parameters.pScrollRect = nullptr;
   555 	parameters.pScrollOffset = nullptr;
   555     parameters.pScrollOffset = nullptr;
   556 	
   556     
   557 	// The first argument instructs DXGI to block until VSync, putting the application
   557     // The first argument instructs DXGI to block until VSync, putting the application
   558 	// to sleep until the next VSync. This ensures we don't waste any cycles rendering
   558     // to sleep until the next VSync. This ensures we don't waste any cycles rendering
   559 	// frames that will never be displayed to the screen.
   559     // frames that will never be displayed to the screen.
   560 	HRESULT hr = m_swapChain->Present1(1, 0, &parameters);
   560     HRESULT hr = m_swapChain->Present1(1, 0, &parameters);
   561 
   561 
   562 	// Discard the contents of the render target.
   562     // Discard the contents of the render target.
   563 	// This is a valid operation only when the existing contents will be entirely
   563     // This is a valid operation only when the existing contents will be entirely
   564 	// overwritten. If dirty or scroll rects are used, this call should be removed.
   564     // overwritten. If dirty or scroll rects are used, this call should be removed.
   565 	m_d3dContext->DiscardView(m_renderTargetView.Get());
   565     m_d3dContext->DiscardView(m_renderTargetView.Get());
   566 
   566 
   567 	// If the device was removed either by a disconnect or a driver upgrade, we 
   567     // If the device was removed either by a disconnect or a driver upgrade, we 
   568 	// must recreate all device resources.
   568     // must recreate all device resources.
   569 	if (hr == DXGI_ERROR_DEVICE_REMOVED)
   569     if (hr == DXGI_ERROR_DEVICE_REMOVED)
   570 	{
   570     {
   571 		HandleDeviceLost();
   571         HandleDeviceLost();
   572 	}
   572     }
   573 	else
   573     else
   574 	{
   574     {
   575 		DX::ThrowIfFailed(hr);
   575         DX::ThrowIfFailed(hr);
   576 	}
   576     }
   577 }
   577 }
   578 
   578 
   579 // Method to convert a length in device-independent pixels (DIPs) to a length in physical pixels.
   579 // Method to convert a length in device-independent pixels (DIPs) to a length in physical pixels.
   580 float SDL_winrtrenderer::ConvertDipsToPixels(float dips)
   580 float SDL_winrtrenderer::ConvertDipsToPixels(float dips)
   581 {
   581 {
   582 	static const float dipsPerInch = 96.0f;
   582     static const float dipsPerInch = 96.0f;
   583 	return floor(dips * DisplayProperties::LogicalDpi / dipsPerInch + 0.5f); // Round to nearest integer.
   583     return floor(dips * DisplayProperties::LogicalDpi / dipsPerInch + 0.5f); // Round to nearest integer.
   584 }
   584 }