mirror of
https://github.com/bkaradzic/bgfx.git
synced 2026-02-17 20:52:36 +01:00
Added fall back to noop renderer when device is removed.
This commit is contained in:
39
src/bgfx.cpp
39
src/bgfx.cpp
@@ -1669,6 +1669,13 @@ namespace bgfx
|
||||
{
|
||||
m_renderCtx->flip(m_render->m_hmd);
|
||||
m_flipped = true;
|
||||
|
||||
if (m_renderCtx->isDeviceRemoved() )
|
||||
{
|
||||
// Something horribly went wrong, fallback to noop renderer.
|
||||
m_renderCtx = m_renderNoop;
|
||||
g_caps.rendererType = m_renderCtx->getRendererType();
|
||||
}
|
||||
}
|
||||
|
||||
if (apiSemWait(_msecs) )
|
||||
@@ -1834,7 +1841,7 @@ namespace bgfx
|
||||
|
||||
static RendererCreator s_rendererCreator[] =
|
||||
{
|
||||
{ noop::rendererCreate, noop::rendererDestroy, BGFX_RENDERER_NOOP_NAME, !!BGFX_CONFIG_RENDERER_NOOP }, // Noop
|
||||
{ noop::rendererCreate, noop::rendererDestroy, BGFX_RENDERER_NOOP_NAME, true }, // Noop
|
||||
{ d3d9::rendererCreate, d3d9::rendererDestroy, BGFX_RENDERER_DIRECT3D9_NAME, !!BGFX_CONFIG_RENDERER_DIRECT3D9 }, // Direct3D9
|
||||
{ d3d11::rendererCreate, d3d11::rendererDestroy, BGFX_RENDERER_DIRECT3D11_NAME, !!BGFX_CONFIG_RENDERER_DIRECT3D11 }, // Direct3D11
|
||||
{ d3d12::rendererCreate, d3d12::rendererDestroy, BGFX_RENDERER_DIRECT3D12_NAME, !!BGFX_CONFIG_RENDERER_DIRECT3D12 }, // Direct3D12
|
||||
@@ -1850,8 +1857,6 @@ namespace bgfx
|
||||
};
|
||||
BX_STATIC_ASSERT(BX_COUNTOF(s_rendererCreator) == RendererType::Count);
|
||||
|
||||
static RendererDestroyFn s_rendererDestroyFn;
|
||||
|
||||
struct Condition
|
||||
{
|
||||
enum Enum
|
||||
@@ -1974,7 +1979,6 @@ namespace bgfx
|
||||
renderCtx = s_rendererCreator[renderer].createFn();
|
||||
if (NULL != renderCtx)
|
||||
{
|
||||
s_rendererDestroyFn = s_rendererCreator[renderer].destroyFn;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1984,9 +1988,12 @@ namespace bgfx
|
||||
return renderCtx;
|
||||
}
|
||||
|
||||
void rendererDestroy()
|
||||
void rendererDestroy(RendererContextI* _renderCtx)
|
||||
{
|
||||
s_rendererDestroyFn();
|
||||
if (NULL != _renderCtx)
|
||||
{
|
||||
s_rendererCreator[_renderCtx->getRendererType()].destroyFn();
|
||||
}
|
||||
}
|
||||
|
||||
void Context::rendererExecCommands(CommandBuffer& _cmdbuf)
|
||||
@@ -2020,8 +2027,9 @@ namespace bgfx
|
||||
RendererType::Enum type;
|
||||
_cmdbuf.read(type);
|
||||
|
||||
m_renderCtx = rendererCreate(type);
|
||||
m_rendererInitialized = NULL != m_renderCtx;
|
||||
m_renderMain = rendererCreate(type);
|
||||
|
||||
m_rendererInitialized = NULL != m_renderMain;
|
||||
|
||||
if (!m_rendererInitialized)
|
||||
{
|
||||
@@ -2031,6 +2039,12 @@ namespace bgfx
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
m_renderCtx = m_renderMain;
|
||||
m_renderNoop = RendererType::Noop != type
|
||||
? rendererCreate(RendererType::Noop)
|
||||
: NULL
|
||||
;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2053,8 +2067,15 @@ namespace bgfx
|
||||
case CommandBuffer::RendererShutdownEnd:
|
||||
{
|
||||
BX_CHECK(!m_rendererInitialized && !m_exit, "This shouldn't happen! Bad synchronization?");
|
||||
rendererDestroy();
|
||||
|
||||
m_renderCtx = NULL;
|
||||
|
||||
rendererDestroy(m_renderMain);
|
||||
m_renderMain = NULL;
|
||||
|
||||
rendererDestroy(m_renderNoop);
|
||||
m_renderNoop = NULL;
|
||||
|
||||
m_exit = true;
|
||||
}
|
||||
// fall through
|
||||
|
||||
@@ -2178,6 +2178,7 @@ namespace bgfx
|
||||
virtual ~RendererContextI() = 0;
|
||||
virtual RendererType::Enum getRendererType() const = 0;
|
||||
virtual const char* getRendererName() const = 0;
|
||||
virtual bool isDeviceRemoved() = 0;
|
||||
virtual void flip(HMD& _hmd) = 0;
|
||||
virtual void createIndexBuffer(IndexBufferHandle _handle, Memory* _mem, uint16_t _flags) = 0;
|
||||
virtual void destroyIndexBuffer(IndexBufferHandle _handle) = 0;
|
||||
@@ -2244,6 +2245,8 @@ namespace bgfx
|
||||
, m_frames(0)
|
||||
, m_debug(BGFX_DEBUG_NONE)
|
||||
, m_renderCtx(NULL)
|
||||
, m_renderMain(NULL)
|
||||
, m_renderNoop(NULL)
|
||||
, m_rendererInitialized(false)
|
||||
, m_exit(false)
|
||||
, m_flipAfterRender(false)
|
||||
@@ -4308,6 +4311,8 @@ namespace bgfx
|
||||
ClearQuad m_clearQuad;
|
||||
|
||||
RendererContextI* m_renderCtx;
|
||||
RendererContextI* m_renderMain;
|
||||
RendererContextI* m_renderNoop;
|
||||
|
||||
bool m_rendererInitialized;
|
||||
bool m_exit;
|
||||
|
||||
19
src/config.h
19
src/config.h
@@ -19,8 +19,7 @@
|
||||
&& !defined(BGFX_CONFIG_RENDERER_OPENGL) \
|
||||
&& !defined(BGFX_CONFIG_RENDERER_OPENGLES) \
|
||||
&& !defined(BGFX_CONFIG_RENDERER_VULKAN) \
|
||||
&& !defined(BGFX_CONFIG_RENDERER_GNM) \
|
||||
&& !defined(BGFX_CONFIG_RENDERER_NOOP)
|
||||
&& !defined(BGFX_CONFIG_RENDERER_GNM)
|
||||
|
||||
# ifndef BGFX_CONFIG_RENDERER_DIRECT3D9
|
||||
# define BGFX_CONFIG_RENDERER_DIRECT3D9 (0 \
|
||||
@@ -86,18 +85,6 @@
|
||||
? 1 : 0)
|
||||
# endif // BGFX_CONFIG_RENDERER_GNM
|
||||
|
||||
# ifndef BGFX_CONFIG_RENDERER_NOOP
|
||||
# define BGFX_CONFIG_RENDERER_NOOP (!(0 \
|
||||
|| BGFX_CONFIG_RENDERER_DIRECT3D9 \
|
||||
|| BGFX_CONFIG_RENDERER_DIRECT3D11 \
|
||||
|| BGFX_CONFIG_RENDERER_DIRECT3D12 \
|
||||
|| BGFX_CONFIG_RENDERER_METAL \
|
||||
|| BGFX_CONFIG_RENDERER_OPENGL \
|
||||
|| BGFX_CONFIG_RENDERER_OPENGLES \
|
||||
|| BGFX_CONFIG_RENDERER_VULKAN \
|
||||
|| BGFX_CONFIG_RENDERER_GNM \
|
||||
? 1 : 0) )
|
||||
# endif // BGFX_CONFIG_RENDERER_NOOP
|
||||
#else
|
||||
# ifndef BGFX_CONFIG_RENDERER_DIRECT3D9
|
||||
# define BGFX_CONFIG_RENDERER_DIRECT3D9 0
|
||||
@@ -130,10 +117,6 @@
|
||||
# ifndef BGFX_CONFIG_RENDERER_GNM
|
||||
# define BGFX_CONFIG_RENDERER_GNM 0
|
||||
# endif // BGFX_CONFIG_RENDERER_GNM
|
||||
|
||||
# ifndef BGFX_CONFIG_RENDERER_NOOP
|
||||
# define BGFX_CONFIG_RENDERER_NOOP 0
|
||||
# endif // BGFX_CONFIG_RENDERER_NOOP
|
||||
#endif // !defined...
|
||||
|
||||
#if BGFX_CONFIG_RENDERER_OPENGL && BGFX_CONFIG_RENDERER_OPENGL < 21
|
||||
|
||||
@@ -455,6 +455,35 @@ namespace bgfx { namespace d3d11
|
||||
;
|
||||
}
|
||||
|
||||
static const char* getLostReason(HRESULT _hr)
|
||||
{
|
||||
switch (_hr)
|
||||
{
|
||||
// The GPU device instance has been suspended. Use GetDeviceRemovedReason to determine the appropriate action.
|
||||
case DXGI_ERROR_DEVICE_REMOVED: return "DXGI_ERROR_DEVICE_REMOVED";
|
||||
|
||||
// The GPU will not respond to more commands, most likely because of an invalid command passed by the calling application.
|
||||
case DXGI_ERROR_DEVICE_HUNG: return "DXGI_ERROR_DEVICE_HUNG";
|
||||
|
||||
// The GPU will not respond to more commands, most likely because some other application submitted invalid commands.
|
||||
// The calling application should re-create the device and continue.
|
||||
case DXGI_ERROR_DEVICE_RESET: return "DXGI_ERROR_DEVICE_RESET";
|
||||
|
||||
// An internal issue prevented the driver from carrying out the specified operation. The driver's state is probably
|
||||
// suspect, and the application should not continue.
|
||||
case DXGI_ERROR_DRIVER_INTERNAL_ERROR: return "DXGI_ERROR_DRIVER_INTERNAL_ERROR";
|
||||
|
||||
// A resource is not available at the time of the call, but may become available later.
|
||||
case DXGI_ERROR_NOT_CURRENTLY_AVAILABLE: return "DXGI_ERROR_NOT_CURRENTLY_AVAILABLE";
|
||||
|
||||
case S_OK: return "S_OK";
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
return "Unknown HRESULT?";
|
||||
}
|
||||
|
||||
template <typename Ty>
|
||||
static BX_NO_INLINE void setDebugObjectName(Ty* _interface, const char* _format, ...)
|
||||
{
|
||||
@@ -654,7 +683,7 @@ namespace bgfx { namespace d3d11
|
||||
, m_adapter(NULL)
|
||||
, m_factory(NULL)
|
||||
, m_swapChain(NULL)
|
||||
, m_lost(0)
|
||||
, m_lost(false)
|
||||
, m_numWindows(0)
|
||||
, m_device(NULL)
|
||||
, m_deviceCtx(NULL)
|
||||
@@ -2263,9 +2292,15 @@ BX_PRAGMA_DIAGNOSTIC_POP();
|
||||
capturePostReset();
|
||||
}
|
||||
|
||||
bool isDeviceRemoved() BX_OVERRIDE
|
||||
{
|
||||
return m_lost;
|
||||
}
|
||||
|
||||
void flip(HMD& _hmd) BX_OVERRIDE
|
||||
{
|
||||
if (NULL != m_swapChain)
|
||||
if (NULL != m_swapChain
|
||||
&& !m_lost)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
uint32_t syncInterval = BX_ENABLED(!BX_PLATFORM_WINDOWS)
|
||||
@@ -2298,15 +2333,14 @@ BX_PRAGMA_DIAGNOSTIC_POP();
|
||||
}
|
||||
}
|
||||
|
||||
if (isLost(hr) )
|
||||
{
|
||||
++m_lost;
|
||||
BGFX_FATAL(10 > m_lost, bgfx::Fatal::DeviceLost, "Device is lost. FAILED 0x%08x", hr);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_lost = 0;
|
||||
}
|
||||
m_lost = d3d11::isLost(hr);
|
||||
BGFX_FATAL(!m_lost
|
||||
, bgfx::Fatal::DeviceLost
|
||||
, "Device is lost. FAILED 0x%08x %s (%s)"
|
||||
, hr
|
||||
, getLostReason(hr)
|
||||
, DXGI_ERROR_DEVICE_REMOVED == hr ? getLostReason(m_device->GetDeviceRemovedReason() ) : "no info"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3551,7 +3585,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
|
||||
#endif // BX_PLATFORM_WINDOWS
|
||||
|
||||
bool m_needPresent;
|
||||
uint16_t m_lost;
|
||||
bool m_lost;
|
||||
uint16_t m_numWindows;
|
||||
FrameBufferHandle m_windows[BGFX_CONFIG_MAX_FRAME_BUFFERS];
|
||||
|
||||
@@ -5273,7 +5307,8 @@ BX_PRAGMA_DIAGNOSTIC_POP();
|
||||
|
||||
void RendererContextD3D11::submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter)
|
||||
{
|
||||
if (updateResolution(_render->m_resolution) )
|
||||
if (m_lost
|
||||
|| updateResolution(_render->m_resolution) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1260,7 +1260,7 @@ namespace bgfx { namespace d3d12
|
||||
return BGFX_RENDERER_DIRECT3D12_NAME;
|
||||
}
|
||||
|
||||
static bool isLost(HRESULT _hr)
|
||||
static bool isDeviceRemoved(HRESULT _hr)
|
||||
{
|
||||
return DXGI_ERROR_DEVICE_REMOVED == _hr
|
||||
|| DXGI_ERROR_DEVICE_HUNG == _hr
|
||||
@@ -1270,6 +1270,11 @@ namespace bgfx { namespace d3d12
|
||||
;
|
||||
}
|
||||
|
||||
bool isDeviceRemoved() BX_OVERRIDE
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void flip(HMD& /*_hmd*/) BX_OVERRIDE
|
||||
{
|
||||
if (NULL != m_swapChain)
|
||||
@@ -1294,7 +1299,7 @@ namespace bgfx { namespace d3d12
|
||||
m_presentElapsed = now - start;
|
||||
|
||||
if (FAILED(hr)
|
||||
&& isLost(hr) )
|
||||
&& isDeviceRemoved(hr) )
|
||||
{
|
||||
++m_lost;
|
||||
BGFX_FATAL(10 > m_lost, bgfx::Fatal::DeviceLost, "Device is lost. FAILED 0x%08x", hr);
|
||||
@@ -5337,7 +5342,7 @@ data.NumQualityLevels = 0;
|
||||
buffer.setState(m_commandList, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
|
||||
scratchBuffer.allocUav(srvHandle[stage], buffer);
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
buffer.setState(m_commandList, D3D12_RESOURCE_STATE_GENERIC_READ);
|
||||
scratchBuffer.allocSrv(srvHandle[stage], buffer);
|
||||
|
||||
@@ -1458,6 +1458,11 @@ namespace bgfx { namespace d3d9
|
||||
m_flushQuery->GetData(NULL, 0, D3DGETDATA_FLUSH);
|
||||
}
|
||||
|
||||
bool isDeviceRemoved() BX_OVERRIDE
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void flip(HMD& /*_hmd*/) BX_OVERRIDE
|
||||
{
|
||||
if (NULL != m_swapChain)
|
||||
@@ -1488,7 +1493,7 @@ namespace bgfx { namespace d3d9
|
||||
}
|
||||
|
||||
#if BX_PLATFORM_WINDOWS
|
||||
if (isLost(hr) )
|
||||
if (d3d9::isLost(hr) )
|
||||
{
|
||||
do
|
||||
{
|
||||
|
||||
@@ -2289,6 +2289,11 @@ namespace bgfx { namespace gl
|
||||
return BGFX_RENDERER_OPENGL_NAME;
|
||||
}
|
||||
|
||||
bool isDeviceRemoved() BX_OVERRIDE
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void flip(HMD& _hmd)
|
||||
{
|
||||
if (m_flip)
|
||||
|
||||
@@ -1069,6 +1069,11 @@ namespace bgfx { namespace mtl
|
||||
}
|
||||
}
|
||||
|
||||
bool isDeviceRemoved() BX_OVERRIDE
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void flip(HMD& /*_hmd*/) BX_OVERRIDE
|
||||
{
|
||||
if (NULL == m_commandBuffer)
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
|
||||
#include "bgfx_p.h"
|
||||
|
||||
#if BGFX_CONFIG_RENDERER_NOOP
|
||||
|
||||
namespace bgfx { namespace noop
|
||||
{
|
||||
struct RendererContextNOOP : public RendererContextI
|
||||
@@ -52,6 +50,11 @@ namespace bgfx { namespace noop
|
||||
return BGFX_RENDERER_NOOP_NAME;
|
||||
}
|
||||
|
||||
bool isDeviceRemoved() BX_OVERRIDE
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void flip(HMD& /*_hmd*/) BX_OVERRIDE
|
||||
{
|
||||
}
|
||||
@@ -224,19 +227,3 @@ namespace bgfx { namespace noop
|
||||
s_renderNOOP = NULL;
|
||||
}
|
||||
} /* namespace noop */ } // namespace bgfx
|
||||
|
||||
#else
|
||||
|
||||
namespace bgfx { namespace noop
|
||||
{
|
||||
RendererContextI* rendererCreate()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void rendererDestroy()
|
||||
{
|
||||
}
|
||||
} /* namespace noop */ } // namespace bgfx
|
||||
|
||||
#endif // BGFX_CONFIG_RENDERER_NOOP
|
||||
|
||||
@@ -1919,6 +1919,11 @@ VK_IMPORT_DEVICE
|
||||
return BGFX_RENDERER_VULKAN_NAME;
|
||||
}
|
||||
|
||||
bool isDeviceRemoved() BX_OVERRIDE
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void flip(HMD& /*_hmd*/) BX_OVERRIDE
|
||||
{
|
||||
if (VK_NULL_HANDLE != m_swapchain)
|
||||
|
||||
Reference in New Issue
Block a user