--- a/src/core/windows/SDL_windows.c Sat Feb 02 19:32:44 2013 -0500
+++ b/src/core/windows/SDL_windows.c Sat Feb 02 21:05:32 2013 -0500
@@ -30,17 +30,24 @@
/* Sets an error message based on GetLastError() */
void
-WIN_SetError(const char *prefix)
+WIN_SetErrorFromHRESULT(const char *prefix, HRESULT hr)
{
TCHAR buffer[1024];
char *message;
- FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0,
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, hr, 0,
buffer, SDL_arraysize(buffer), NULL);
message = WIN_StringToUTF8(buffer);
SDL_SetError("%s%s%s", prefix ? prefix : "", prefix ? ": " : "", message);
SDL_free(message);
}
+/* Sets an error message based on GetLastError() */
+void
+WIN_SetError(const char *prefix)
+{
+ WIN_SetErrorFromHRESULT(prefix, GetLastError());
+}
+
HRESULT
WIN_CoInitialize(void)
{
--- a/src/core/windows/SDL_windows.h Sat Feb 02 19:32:44 2013 -0500
+++ b/src/core/windows/SDL_windows.h Sat Feb 02 21:05:32 2013 -0500
@@ -46,6 +46,9 @@
#define WIN_UTF8ToString(S) SDL_iconv_string("ASCII", "UTF-8", (char *)(S), SDL_strlen(S)+1)
#endif
+/* Sets an error message based on a given HRESULT */
+extern void WIN_SetErrorFromHRESULT(const char *prefix, HRESULT hr);
+
/* Sets an error message based on GetLastError() */
extern void WIN_SetError(const char *prefix);
--- a/src/render/direct3d11/SDL_render_d3d11.cpp Sat Feb 02 19:32:44 2013 -0500
+++ b/src/render/direct3d11/SDL_render_d3d11.cpp Sat Feb 02 21:05:32 2013 -0500
@@ -62,7 +62,7 @@
// const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip);
//static int D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
// Uint32 format, void * pixels, int pitch);
-//static void D3D11_RenderPresent(SDL_Renderer * renderer);
+static void D3D11_RenderPresent(SDL_Renderer * renderer);
//static void D3D11_DestroyTexture(SDL_Renderer * renderer,
// SDL_Texture * texture);
//static void D3D11_DestroyRenderer(SDL_Renderer * renderer);
@@ -135,7 +135,7 @@
//renderer->RenderCopy = D3D11_RenderCopy;
//renderer->RenderCopyEx = D3D11_RenderCopyEx;
//renderer->RenderReadPixels = D3D11_RenderReadPixels;
- //renderer->RenderPresent = D3D11_RenderPresent;
+ renderer->RenderPresent = D3D11_RenderPresent;
//renderer->DestroyTexture = D3D11_DestroyTexture;
//renderer->DestroyRenderer = D3D11_DestroyRenderer;
renderer->info = D3D11_RenderDriver.info;
@@ -286,6 +286,51 @@
return 0;
}
+static void
+D3D11_RenderPresent(SDL_Renderer * renderer)
+{
+ D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
+
+#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
+ // 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 = data->swapChain->Present(1, 0);
+#else
+ // The application may optionally specify "dirty" or "scroll"
+ // rects to improve efficiency in certain scenarios.
+ // This option is not available on Windows Phone 8, to note.
+ 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 = data->swapChain->Present1(1, 0, ¶meters);
+#endif
+
+ // 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.
+ data->d3dContext->DiscardView(data->renderTargetView.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)
+ {
+ extern void WINRT_HandleDeviceLost(); // TODO, WinRT: move lost-device handling into the Direct3D 11.1 renderer, as appropriate
+ WINRT_HandleDeviceLost();
+ }
+ else
+ {
+ WIN_SetErrorFromHRESULT(__FUNCTION__, hr);
+ // TODO, WinRT: consider throwing an exception if D3D11_RenderPresent fails, especially if there is a way to salvedge debug info from users' machines
+ }
+}
+
#endif /* SDL_VIDEO_RENDER_D3D && !SDL_RENDER_DISABLED */
/* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/windowsrt/SDL_WinRTApp.cpp Sat Feb 02 19:32:44 2013 -0500
+++ b/src/video/windowsrt/SDL_WinRTApp.cpp Sat Feb 02 21:05:32 2013 -0500
@@ -33,6 +33,12 @@
// SDL_CreateWindow().
SDL_WinRTApp ^ SDL_WinRTGlobalApp = nullptr;
+// HACK: provide a temporary means for the Direct3D 11.1 renderer to handle lost devices, while refactoring is underway
+void WINRT_HandleDeviceLost()
+{
+ SDL_WinRTGlobalApp->m_renderer->HandleDeviceLost();
+}
+
using namespace Windows::ApplicationModel;
using namespace Windows::ApplicationModel::Core;
using namespace Windows::ApplicationModel::Activation;
--- a/src/video/windowsrt/SDL_winrtrenderer.cpp Sat Feb 02 19:32:44 2013 -0500
+++ b/src/video/windowsrt/SDL_winrtrenderer.cpp Sat Feb 02 21:05:32 2013 -0500
@@ -12,6 +12,7 @@
m_mainTextureHelperSurface(NULL),
m_loadingComplete(false),
m_vertexCount(0),
+ m_sdlRenderer(NULL),
m_sdlRendererData(NULL)
{
}
@@ -562,42 +563,7 @@
// Method to deliver the final image to the display.
void SDL_winrtrenderer::Present()
{
-#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
- // 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_sdlRendererData->swapChain->Present(1, 0);
-#else
- // The application may optionally specify "dirty" or "scroll"
- // rects to improve efficiency in certain scenarios.
- // This option is not available on Windows Phone 8, to note.
- 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_sdlRendererData->swapChain->Present1(1, 0, ¶meters);
-#endif
-
- // 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_sdlRendererData->d3dContext->DiscardView(m_sdlRendererData->renderTargetView.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);
- }
+ SDL_RenderPresent(m_sdlRenderer);
}
// Method to convert a length in device-independent pixels (DIPs) to a length in physical pixels.
--- a/src/video/windowsrt/SDL_winrtrenderer.h Sat Feb 02 19:32:44 2013 -0500
+++ b/src/video/windowsrt/SDL_winrtrenderer.h Sat Feb 02 21:05:32 2013 -0500
@@ -31,7 +31,8 @@
void ResizeMainTexture(int w, int h);
internal:
- // Internal SDL rendeerer (likely a temporary addition, for refactoring purposes):
+ // Internal SDL renderer (likely a temporary addition, for refactoring purposes):
+ SDL_Renderer * m_sdlRenderer;
D3D11_RenderData * m_sdlRendererData;
protected private:
--- a/src/video/windowsrt/SDL_winrtvideo.cpp Sat Feb 02 19:32:44 2013 -0500
+++ b/src/video/windowsrt/SDL_winrtvideo.cpp Sat Feb 02 21:05:32 2013 -0500
@@ -220,7 +220,10 @@
// for refactoring purposes. Initialize the SDL_Renderer
// first in order to give it the opportunity to create key
// resources first.
+ //
+ // TODO, WinRT: either make WINRT_CreateWindow not call SDL_CreateRenderer, or have it do error checking if it does call it
SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE);
+ SDL_WinRTGlobalApp->m_renderer->m_sdlRenderer = renderer;
SDL_WinRTGlobalApp->m_renderer->m_sdlRendererData = (D3D11_RenderData *) renderer->driverdata;
SDL_WinRTGlobalApp->m_renderer->Initialize(CoreWindow::GetForCurrentThread());