WinRT: moved a bit more Direct3D 11.1 code into the SDL_Renderer backend
This commit is contained in:
parent
f7b08ae60b
commit
b9299763b6
7 changed files with 72 additions and 41 deletions
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ static int D3D11_UpdateViewport(SDL_Renderer * renderer);
|
|||
// 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 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags)
|
|||
//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 @@ D3D11_UpdateViewport(SDL_Renderer * renderer)
|
|||
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: */
|
||||
|
|
|
@ -33,6 +33,12 @@ static SDL_WinRT_MainFunction SDL_WinRT_main = nullptr;
|
|||
// 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;
|
||||
|
|
|
@ -12,6 +12,7 @@ SDL_winrtrenderer::SDL_winrtrenderer() :
|
|||
m_mainTextureHelperSurface(NULL),
|
||||
m_loadingComplete(false),
|
||||
m_vertexCount(0),
|
||||
m_sdlRenderer(NULL),
|
||||
m_sdlRendererData(NULL)
|
||||
{
|
||||
}
|
||||
|
@ -562,42 +563,7 @@ void SDL_winrtrenderer::Render(SDL_Surface * surface, SDL_Rect * rects, int numr
|
|||
// 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.
|
||||
|
|
|
@ -31,7 +31,8 @@ internal:
|
|||
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:
|
||||
|
|
|
@ -220,7 +220,10 @@ WINRT_CreateWindow(_THIS, SDL_Window * window)
|
|||
// 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());
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue