mirror of
https://github.com/scratchfoundation/bgfx.git
synced 2024-11-28 18:45:54 -05:00
Added graceful error handling during initialization.
This commit is contained in:
parent
8adc099b02
commit
5f59978e6b
7 changed files with 816 additions and 450 deletions
|
@ -432,7 +432,7 @@ BGFX_C_API uint8_t bgfx_get_supported_renderers(bgfx_renderer_type_t _enum[BGFX_
|
|||
BGFX_C_API const char* bgfx_get_renderer_name(bgfx_renderer_type_t _type);
|
||||
|
||||
/**/
|
||||
BGFX_C_API void bgfx_init(bgfx_renderer_type_t _type, uint16_t _vendorId, uint16_t _deviceId, bgfx_callback_interface_t* _callback, bgfx_reallocator_interface_t* _allocator);
|
||||
BGFX_C_API bool bgfx_init(bgfx_renderer_type_t _type, uint16_t _vendorId, uint16_t _deviceId, bgfx_callback_interface_t* _callback, bgfx_reallocator_interface_t* _allocator);
|
||||
|
||||
/**/
|
||||
BGFX_C_API void bgfx_shutdown();
|
||||
|
|
|
@ -709,9 +709,11 @@ namespace bgfx
|
|||
/// specified, library uses default CRT allocator. The library assumes
|
||||
/// icustom allocator is thread safe.
|
||||
///
|
||||
/// @returns `true` if initialization is sucessful.
|
||||
///
|
||||
/// @attention C99 equivalent is `bgfx_init`.
|
||||
///
|
||||
void init(RendererType::Enum _type = RendererType::Count, uint16_t _vendorId = BGFX_PCI_ID_NONE, uint16_t _deviceId = 0, CallbackI* _callback = NULL, bx::ReallocatorI* _reallocator = NULL);
|
||||
bool init(RendererType::Enum _type = RendererType::Count, uint16_t _vendorId = BGFX_PCI_ID_NONE, uint16_t _deviceId = 0, CallbackI* _callback = NULL, bx::ReallocatorI* _reallocator = NULL);
|
||||
|
||||
/// Shutdown bgfx library.
|
||||
///
|
||||
|
|
103
src/bgfx.cpp
103
src/bgfx.cpp
|
@ -915,7 +915,7 @@ namespace bgfx
|
|||
TextureFormat::RGBA8, // D3D9 doesn't support RGBA8
|
||||
};
|
||||
|
||||
void Context::init(RendererType::Enum _type)
|
||||
bool Context::init(RendererType::Enum _type)
|
||||
{
|
||||
BX_CHECK(!m_rendererInitialized, "Already initialized?");
|
||||
|
||||
|
@ -990,6 +990,19 @@ namespace bgfx
|
|||
// g_caps is initialized and available after this point.
|
||||
frame();
|
||||
|
||||
if (!m_rendererInitialized)
|
||||
{
|
||||
getCommandBuffer(CommandBuffer::RendererShutdownEnd);
|
||||
frame();
|
||||
frame();
|
||||
m_declRef.shutdown(m_vertexDeclHandle);
|
||||
m_submit->destroy();
|
||||
#if BGFX_CONFIG_MULTITHREADED
|
||||
m_render->destroy();
|
||||
#endif // BGFX_CONFIG_MULTITHREADED
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint32_t ii = 0; ii < BX_COUNTOF(s_emulatedFormats); ++ii)
|
||||
{
|
||||
if (0 == (g_caps.formats[s_emulatedFormats[ii] ] & BGFX_CAPS_FORMAT_TEXTURE_COLOR) )
|
||||
|
@ -1020,6 +1033,8 @@ namespace bgfx
|
|||
m_submit->m_transientIb = createTransientIndexBuffer(BGFX_CONFIG_TRANSIENT_INDEX_BUFFER_SIZE);
|
||||
frame();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Context::shutdown()
|
||||
|
@ -1370,7 +1385,7 @@ namespace bgfx
|
|||
bool supported;
|
||||
};
|
||||
|
||||
static const RendererCreator s_rendererCreator[] =
|
||||
static RendererCreator s_rendererCreator[] =
|
||||
{
|
||||
{ noop::rendererCreate, noop::rendererDestroy, BGFX_RENDERER_NULL_NAME, !!BGFX_CONFIG_RENDERER_NULL }, // Noop
|
||||
{ d3d9::rendererCreate, d3d9::rendererDestroy, BGFX_RENDERER_DIRECT3D9_NAME, !!BGFX_CONFIG_RENDERER_DIRECT3D9 }, // Direct3D9
|
||||
|
@ -1467,10 +1482,18 @@ again:
|
|||
{
|
||||
_type = RendererType::OpenGLES;
|
||||
}
|
||||
else if (s_rendererCreator[RendererType::Direct3D12].supported)
|
||||
{
|
||||
_type = RendererType::Direct3D12;
|
||||
}
|
||||
else if (s_rendererCreator[RendererType::Vulkan].supported)
|
||||
{
|
||||
_type = RendererType::Vulkan;
|
||||
}
|
||||
else
|
||||
{
|
||||
_type = RendererType::Null;
|
||||
}
|
||||
}
|
||||
else if (BX_ENABLED(0
|
||||
|| BX_PLATFORM_ANDROID
|
||||
|
@ -1508,6 +1531,7 @@ again:
|
|||
|
||||
if (NULL == renderCtx)
|
||||
{
|
||||
s_rendererCreator[_type].supported = false;
|
||||
goto again;
|
||||
}
|
||||
|
||||
|
@ -1532,20 +1556,42 @@ again:
|
|||
uint8_t command;
|
||||
_cmdbuf.read(command);
|
||||
|
||||
BX_CHECK(CommandBuffer::RendererInit == command
|
||||
, "RendererInit must be the first command in command buffer before initialization."
|
||||
);
|
||||
BX_CHECK(!m_rendererInitialized, "This shouldn't happen! Bad synchronization?");
|
||||
switch (command)
|
||||
{
|
||||
case CommandBuffer::RendererShutdownEnd:
|
||||
m_exit = true;
|
||||
return;
|
||||
|
||||
RendererType::Enum type;
|
||||
_cmdbuf.read(type);
|
||||
case CommandBuffer::End:
|
||||
return;
|
||||
|
||||
m_renderCtx = rendererCreate(type);
|
||||
m_rendererInitialized = true;
|
||||
default:
|
||||
{
|
||||
BX_CHECK(CommandBuffer::RendererInit == command
|
||||
, "RendererInit must be the first command in command buffer before initialization. Unexpected command %d?"
|
||||
, command
|
||||
);
|
||||
BX_CHECK(!m_rendererInitialized, "This shouldn't happen! Bad synchronization?");
|
||||
|
||||
RendererType::Enum type;
|
||||
_cmdbuf.read(type);
|
||||
|
||||
m_renderCtx = rendererCreate(type);
|
||||
m_rendererInitialized = NULL != m_renderCtx;
|
||||
|
||||
if (!m_rendererInitialized)
|
||||
{
|
||||
_cmdbuf.read(command);
|
||||
BX_CHECK(CommandBuffer::End == command, "Unexpected command %d?"
|
||||
, command
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BX_CHECK(NULL != m_renderCtx, "Should not be NULL at this point.");
|
||||
|
||||
do
|
||||
{
|
||||
uint8_t command;
|
||||
|
@ -2015,7 +2061,7 @@ again:
|
|||
return s_rendererCreator[_type].name;
|
||||
}
|
||||
|
||||
void init(RendererType::Enum _type, uint16_t _vendorId, uint16_t _deviceId, CallbackI* _callback, bx::ReallocatorI* _allocator)
|
||||
bool init(RendererType::Enum _type, uint16_t _vendorId, uint16_t _deviceId, CallbackI* _callback, bx::ReallocatorI* _allocator)
|
||||
{
|
||||
BX_CHECK(NULL == s_ctx, "bgfx is already initialized.");
|
||||
|
||||
|
@ -2050,9 +2096,36 @@ again:
|
|||
BX_TRACE("Init...");
|
||||
|
||||
s_ctx = BX_ALIGNED_NEW(g_allocator, Context, 16);
|
||||
s_ctx->init(_type);
|
||||
if (!s_ctx->init(_type) )
|
||||
{
|
||||
BX_TRACE("Init failed.");
|
||||
|
||||
BX_ALIGNED_DELETE(g_allocator, s_ctx, 16);
|
||||
s_ctx = NULL;
|
||||
|
||||
if (NULL != s_callbackStub)
|
||||
{
|
||||
BX_DELETE(g_allocator, s_callbackStub);
|
||||
s_callbackStub = NULL;
|
||||
}
|
||||
|
||||
if (NULL != s_allocatorStub)
|
||||
{
|
||||
// s_allocatorStub->checkLeaks();
|
||||
|
||||
bx::CrtAllocator allocator;
|
||||
BX_DELETE(&allocator, s_allocatorStub);
|
||||
s_allocatorStub = NULL;
|
||||
}
|
||||
|
||||
s_threadIndex = 0;
|
||||
g_callback = NULL;
|
||||
g_allocator = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
BX_TRACE("Init complete.");
|
||||
return true;
|
||||
}
|
||||
|
||||
void shutdown()
|
||||
|
@ -3243,7 +3316,7 @@ BGFX_C_API const char* bgfx_get_renderer_name(bgfx_renderer_type_t _type)
|
|||
return bgfx::getRendererName(bgfx::RendererType::Enum(_type) );
|
||||
}
|
||||
|
||||
BGFX_C_API void bgfx_init(bgfx_renderer_type_t _type, uint16_t _vendorId, uint16_t _deviceId, bgfx_callback_interface_t* _callback, bgfx_reallocator_interface_t* _allocator)
|
||||
BGFX_C_API bool bgfx_init(bgfx_renderer_type_t _type, uint16_t _vendorId, uint16_t _deviceId, bgfx_callback_interface_t* _callback, bgfx_reallocator_interface_t* _allocator)
|
||||
{
|
||||
static bgfx::CallbackC99 s_callback;
|
||||
s_callback.m_interface = _callback;
|
||||
|
|
|
@ -1929,7 +1929,7 @@ namespace bgfx
|
|||
}
|
||||
|
||||
// game thread
|
||||
void init(RendererType::Enum _type);
|
||||
bool init(RendererType::Enum _type);
|
||||
void shutdown();
|
||||
|
||||
CommandBuffer& getCommandBuffer(CommandBuffer::Enum _cmd)
|
||||
|
|
|
@ -489,8 +489,10 @@ namespace bgfx { namespace d3d11
|
|||
{
|
||||
}
|
||||
|
||||
void init()
|
||||
bool init()
|
||||
{
|
||||
uint32_t errorState = 0;
|
||||
|
||||
// Must be before device creation, and before RenderDoc.
|
||||
m_ovr.init();
|
||||
|
||||
|
@ -505,7 +507,14 @@ namespace bgfx { namespace d3d11
|
|||
|
||||
#if USE_D3D11_DYNAMIC_LIB
|
||||
m_d3d11dll = bx::dlopen("d3d11.dll");
|
||||
BGFX_FATAL(NULL != m_d3d11dll, Fatal::UnableToInitialize, "Failed to load d3d11.dll.");
|
||||
BX_WARN(NULL != m_d3d11dll, "Failed to load d3d11.dll.");
|
||||
|
||||
if (NULL == m_d3d11dll)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
errorState = 1;
|
||||
|
||||
m_d3d9dll = NULL;
|
||||
|
||||
|
@ -514,26 +523,41 @@ namespace bgfx { namespace d3d11
|
|||
// D3D11_1.h has ID3DUserDefinedAnnotation
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/hh446881%28v=vs.85%29.aspx
|
||||
m_d3d9dll = bx::dlopen("d3d9.dll");
|
||||
BGFX_FATAL(NULL != m_d3d9dll, Fatal::UnableToInitialize, "Failed to load d3d9.dll.");
|
||||
|
||||
D3DPERF_SetMarker = (PFN_D3DPERF_SET_MARKER )bx::dlsym(m_d3d9dll, "D3DPERF_SetMarker" );
|
||||
D3DPERF_BeginEvent = (PFN_D3DPERF_BEGIN_EVENT)bx::dlsym(m_d3d9dll, "D3DPERF_BeginEvent");
|
||||
D3DPERF_EndEvent = (PFN_D3DPERF_END_EVENT )bx::dlsym(m_d3d9dll, "D3DPERF_EndEvent" );
|
||||
BX_CHECK(NULL != D3DPERF_SetMarker
|
||||
&& NULL != D3DPERF_BeginEvent
|
||||
&& NULL != D3DPERF_EndEvent
|
||||
, "Failed to initialize PIX events."
|
||||
);
|
||||
if (NULL != m_d3d9dll)
|
||||
{
|
||||
D3DPERF_SetMarker = (PFN_D3DPERF_SET_MARKER )bx::dlsym(m_d3d9dll, "D3DPERF_SetMarker" );
|
||||
D3DPERF_BeginEvent = (PFN_D3DPERF_BEGIN_EVENT)bx::dlsym(m_d3d9dll, "D3DPERF_BeginEvent");
|
||||
D3DPERF_EndEvent = (PFN_D3DPERF_END_EVENT )bx::dlsym(m_d3d9dll, "D3DPERF_EndEvent" );
|
||||
BX_CHECK(NULL != D3DPERF_SetMarker
|
||||
&& NULL != D3DPERF_BeginEvent
|
||||
&& NULL != D3DPERF_EndEvent
|
||||
, "Failed to initialize PIX events."
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)bx::dlsym(m_d3d11dll, "D3D11CreateDevice");
|
||||
BGFX_FATAL(NULL != D3D11CreateDevice, Fatal::UnableToInitialize, "Function D3D11CreateDevice not found.");
|
||||
BX_WARN(NULL != D3D11CreateDevice, "Function D3D11CreateDevice not found.");
|
||||
if (NULL == D3D11CreateDevice)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
m_dxgidll = bx::dlopen("dxgi.dll");
|
||||
BGFX_FATAL(NULL != m_dxgidll, Fatal::UnableToInitialize, "Failed to load dxgi.dll.");
|
||||
BX_WARN(NULL != m_dxgidll, "Failed to load dxgi.dll.");
|
||||
if (NULL == m_dxgidll)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
errorState = 2;
|
||||
|
||||
CreateDXGIFactory = (PFN_CREATE_DXGI_FACTORY)bx::dlsym(m_dxgidll, "CreateDXGIFactory");
|
||||
BGFX_FATAL(NULL != CreateDXGIFactory, Fatal::UnableToInitialize, "Function CreateDXGIFactory not found.");
|
||||
BX_WARN(NULL != CreateDXGIFactory, "Function CreateDXGIFactory not found.");
|
||||
if (NULL == CreateDXGIFactory)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
m_dxgidebugdll = bx::dlopen("dxgidebug.dll");
|
||||
if (NULL != m_dxgidebugdll)
|
||||
|
@ -558,11 +582,16 @@ namespace bgfx { namespace d3d11
|
|||
#if BX_PLATFORM_WINRT
|
||||
// WinRT requires the IDXGIFactory2 interface, which isn't supported on older platforms
|
||||
hr = CreateDXGIFactory1(__uuidof(IDXGIFactory2), (void**)&factory);
|
||||
BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Unable to create DXGI factory.");
|
||||
#else
|
||||
hr = CreateDXGIFactory(IID_IDXGIFactory, (void**)&factory);
|
||||
BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Unable to create DXGI factory.");
|
||||
#endif // BX_PLATFORM_WINRT
|
||||
BX_WARN(SUCCEEDED(hr), "Unable to create DXGI factory.");
|
||||
if (FAILED(hr) )
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
errorState = 3;
|
||||
|
||||
m_device = (ID3D11Device*)g_platformData.context;
|
||||
|
||||
|
@ -686,7 +715,14 @@ namespace bgfx { namespace d3d11
|
|||
|
||||
break;
|
||||
}
|
||||
BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Unable to create Direct3D11 device.");
|
||||
BX_WARN(SUCCEEDED(hr), "Unable to create Direct3D11 device.");
|
||||
|
||||
if (FAILED(hr) )
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
errorState = 4;
|
||||
|
||||
if (NULL != m_adapter)
|
||||
{
|
||||
|
@ -696,7 +732,14 @@ namespace bgfx { namespace d3d11
|
|||
else
|
||||
{
|
||||
m_device->GetImmediateContext(&m_deviceCtx);
|
||||
BGFX_FATAL(NULL != m_deviceCtx, Fatal::UnableToInitialize, "Unable to create Direct3D11 device.");
|
||||
BX_WARN(NULL != m_deviceCtx, "Unable to create Direct3D11 device.");
|
||||
|
||||
if (NULL == m_deviceCtx)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
errorState = 4;
|
||||
}
|
||||
|
||||
IDXGIDevice* device = NULL;
|
||||
|
@ -729,7 +772,11 @@ BX_PRAGMA_DIAGNOSTIC_POP();
|
|||
#endif // BX_COMPILER_MSVC
|
||||
}
|
||||
}
|
||||
BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Unable to create Direct3D11 device.");
|
||||
BX_WARN(SUCCEEDED(hr), "Unable to create Direct3D11 device.");
|
||||
if (FAILED(hr) )
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
// GPA increases device ref count.
|
||||
// RenderDoc makes device ref count 0 here.
|
||||
|
@ -750,7 +797,13 @@ BX_PRAGMA_DIAGNOSTIC_POP();
|
|||
}
|
||||
|
||||
hr = adapter->GetDesc(&m_adapterDesc);
|
||||
BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Unable to create Direct3D11 device.");
|
||||
BX_WARN(SUCCEEDED(hr), "Unable to create Direct3D11 device.");
|
||||
if (FAILED(hr) )
|
||||
{
|
||||
DX_RELEASE(adapter, 2);
|
||||
goto error;
|
||||
}
|
||||
|
||||
g_caps.vendorId = 0 == m_adapterDesc.VendorId
|
||||
? BGFX_PCI_ID_SOFTWARE_RASTERIZER
|
||||
: (uint16_t)m_adapterDesc.VendorId
|
||||
|
@ -761,8 +814,12 @@ BX_PRAGMA_DIAGNOSTIC_POP();
|
|||
{
|
||||
#if BX_PLATFORM_WINRT
|
||||
hr = adapter->GetParent(__uuidof(IDXGIFactory2), (void**)&m_factory);
|
||||
BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Unable to create Direct3D11 device.");
|
||||
BX_WARN(SUCCEEDED(hr), "Unable to create Direct3D11 device.");
|
||||
DX_RELEASE(adapter, 2);
|
||||
if (FAILED(hr) )
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
memset(&m_scd, 0, sizeof(m_scd) );
|
||||
m_scd.Width = BGFX_DEFAULT_WIDTH;
|
||||
|
@ -783,11 +840,14 @@ BX_PRAGMA_DIAGNOSTIC_POP();
|
|||
, NULL
|
||||
, &m_swapChain
|
||||
);
|
||||
BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Failed to create swap chain.");
|
||||
#else
|
||||
hr = adapter->GetParent(IID_IDXGIFactory, (void**)&m_factory);
|
||||
BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Unable to create Direct3D11 device.");
|
||||
BX_WARN(SUCCEEDED(hr), "Unable to create Direct3D11 device.");
|
||||
DX_RELEASE(adapter, 2);
|
||||
if (FAILED(hr) )
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
memset(&m_scd, 0, sizeof(m_scd) );
|
||||
m_scd.BufferDesc.Width = BGFX_DEFAULT_WIDTH;
|
||||
|
@ -806,13 +866,19 @@ BX_PRAGMA_DIAGNOSTIC_POP();
|
|||
, &m_scd
|
||||
, &m_swapChain
|
||||
);
|
||||
BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Failed to create swap chain.");
|
||||
|
||||
DX_CHECK(m_factory->MakeWindowAssociation( (HWND)g_platformData.nwh, 0
|
||||
| DXGI_MWA_NO_WINDOW_CHANGES
|
||||
| DXGI_MWA_NO_ALT_ENTER
|
||||
) );
|
||||
#endif // BX_PLATFORM_WINRT
|
||||
BX_WARN(SUCCEEDED(hr), "Failed to create swap chain.");
|
||||
if (FAILED(hr) )
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
errorState = 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -853,242 +919,292 @@ BX_PRAGMA_DIAGNOSTIC_POP();
|
|||
}
|
||||
}
|
||||
#endif // __MINGW__
|
||||
{
|
||||
|
||||
UniformHandle handle = BGFX_INVALID_HANDLE;
|
||||
for (uint32_t ii = 0; ii < PredefinedUniform::Count; ++ii)
|
||||
{
|
||||
m_uniformReg.add(handle, getPredefinedUniformName(PredefinedUniform::Enum(ii) ), &m_predefinedUniforms[ii]);
|
||||
}
|
||||
|
||||
g_caps.supported |= (0
|
||||
| BGFX_CAPS_TEXTURE_3D
|
||||
| BGFX_CAPS_VERTEX_ATTRIB_HALF
|
||||
| BGFX_CAPS_FRAGMENT_DEPTH
|
||||
| (getIntelExtensions(m_device) ? BGFX_CAPS_FRAGMENT_ORDERING : 0)
|
||||
| BGFX_CAPS_SWAP_CHAIN
|
||||
| (m_ovr.isInitialized() ? BGFX_CAPS_HMD : 0)
|
||||
| BGFX_CAPS_DRAW_INDIRECT
|
||||
);
|
||||
|
||||
if (m_featureLevel <= D3D_FEATURE_LEVEL_9_2)
|
||||
{
|
||||
g_caps.maxTextureSize = D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION;
|
||||
g_caps.maxFBAttachments = uint8_t(bx::uint32_min(D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT, BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS) );
|
||||
}
|
||||
else if (m_featureLevel == D3D_FEATURE_LEVEL_9_3)
|
||||
{
|
||||
g_caps.maxTextureSize = D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION;
|
||||
g_caps.maxFBAttachments = uint8_t(bx::uint32_min(D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT, BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS) );
|
||||
}
|
||||
else
|
||||
{
|
||||
g_caps.supported |= BGFX_CAPS_TEXTURE_COMPARE_ALL;
|
||||
g_caps.maxTextureSize = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
|
||||
g_caps.maxFBAttachments = uint8_t(bx::uint32_min(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS) );
|
||||
}
|
||||
|
||||
// 32-bit indices only supported on 9_2+.
|
||||
if (m_featureLevel >= D3D_FEATURE_LEVEL_9_2)
|
||||
{
|
||||
g_caps.supported |= BGFX_CAPS_INDEX32;
|
||||
}
|
||||
|
||||
// Independent blend only supported on 10_1+.
|
||||
if (m_featureLevel >= D3D_FEATURE_LEVEL_10_1)
|
||||
{
|
||||
g_caps.supported |= BGFX_CAPS_BLEND_INDEPENDENT;
|
||||
}
|
||||
|
||||
// Compute support is optional on 10_0 and 10_1 targets.
|
||||
if (m_featureLevel == D3D_FEATURE_LEVEL_10_0
|
||||
|| m_featureLevel == D3D_FEATURE_LEVEL_10_1)
|
||||
{
|
||||
struct D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS
|
||||
UniformHandle handle = BGFX_INVALID_HANDLE;
|
||||
for (uint32_t ii = 0; ii < PredefinedUniform::Count; ++ii)
|
||||
{
|
||||
BOOL ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x;
|
||||
};
|
||||
m_uniformReg.add(handle, getPredefinedUniformName(PredefinedUniform::Enum(ii) ), &m_predefinedUniforms[ii]);
|
||||
}
|
||||
|
||||
D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS data;
|
||||
hr = m_device->CheckFeatureSupport(D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, &data, sizeof(data) );
|
||||
if (SUCCEEDED(hr)
|
||||
&& data.ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x)
|
||||
g_caps.supported |= (0
|
||||
| BGFX_CAPS_TEXTURE_3D
|
||||
| BGFX_CAPS_VERTEX_ATTRIB_HALF
|
||||
| BGFX_CAPS_FRAGMENT_DEPTH
|
||||
| (getIntelExtensions(m_device) ? BGFX_CAPS_FRAGMENT_ORDERING : 0)
|
||||
| BGFX_CAPS_SWAP_CHAIN
|
||||
| (m_ovr.isInitialized() ? BGFX_CAPS_HMD : 0)
|
||||
| BGFX_CAPS_DRAW_INDIRECT
|
||||
);
|
||||
|
||||
if (m_featureLevel <= D3D_FEATURE_LEVEL_9_2)
|
||||
{
|
||||
g_caps.maxTextureSize = D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION;
|
||||
g_caps.maxFBAttachments = uint8_t(bx::uint32_min(D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT, BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS) );
|
||||
}
|
||||
else if (m_featureLevel == D3D_FEATURE_LEVEL_9_3)
|
||||
{
|
||||
g_caps.maxTextureSize = D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION;
|
||||
g_caps.maxFBAttachments = uint8_t(bx::uint32_min(D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT, BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS) );
|
||||
}
|
||||
else
|
||||
{
|
||||
g_caps.supported |= BGFX_CAPS_TEXTURE_COMPARE_ALL;
|
||||
g_caps.maxTextureSize = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
|
||||
g_caps.maxFBAttachments = uint8_t(bx::uint32_min(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS) );
|
||||
}
|
||||
|
||||
// 32-bit indices only supported on 9_2+.
|
||||
if (m_featureLevel >= D3D_FEATURE_LEVEL_9_2)
|
||||
{
|
||||
g_caps.supported |= BGFX_CAPS_INDEX32;
|
||||
}
|
||||
|
||||
// Independent blend only supported on 10_1+.
|
||||
if (m_featureLevel >= D3D_FEATURE_LEVEL_10_1)
|
||||
{
|
||||
g_caps.supported |= BGFX_CAPS_BLEND_INDEPENDENT;
|
||||
}
|
||||
|
||||
// Compute support is optional on 10_0 and 10_1 targets.
|
||||
if (m_featureLevel == D3D_FEATURE_LEVEL_10_0
|
||||
|| m_featureLevel == D3D_FEATURE_LEVEL_10_1)
|
||||
{
|
||||
struct D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS
|
||||
{
|
||||
BOOL ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x;
|
||||
};
|
||||
|
||||
D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS data;
|
||||
hr = m_device->CheckFeatureSupport(D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, &data, sizeof(data) );
|
||||
if (SUCCEEDED(hr)
|
||||
&& data.ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x)
|
||||
{
|
||||
g_caps.supported |= BGFX_CAPS_COMPUTE;
|
||||
}
|
||||
}
|
||||
else if (m_featureLevel >= D3D_FEATURE_LEVEL_11_0)
|
||||
{
|
||||
g_caps.supported |= BGFX_CAPS_COMPUTE;
|
||||
}
|
||||
}
|
||||
else if (m_featureLevel >= D3D_FEATURE_LEVEL_11_0)
|
||||
{
|
||||
g_caps.supported |= BGFX_CAPS_COMPUTE;
|
||||
}
|
||||
|
||||
// Instancing fully supported on 9_3+, optionally partially supported at lower levels.
|
||||
if (m_featureLevel >= D3D_FEATURE_LEVEL_9_3)
|
||||
{
|
||||
g_caps.supported |= BGFX_CAPS_INSTANCING;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct D3D11_FEATURE_DATA_D3D9_SIMPLE_INSTANCING_SUPPORT
|
||||
{
|
||||
BOOL SimpleInstancingSupported;
|
||||
};
|
||||
|
||||
D3D11_FEATURE_DATA_D3D9_SIMPLE_INSTANCING_SUPPORT data;
|
||||
hr = m_device->CheckFeatureSupport(D3D11_FEATURE(11) /*D3D11_FEATURE_D3D9_SIMPLE_INSTANCING_SUPPORT*/, &data, sizeof(data) );
|
||||
if (SUCCEEDED(hr)
|
||||
&& data.SimpleInstancingSupported)
|
||||
// Instancing fully supported on 9_3+, optionally partially supported at lower levels.
|
||||
if (m_featureLevel >= D3D_FEATURE_LEVEL_9_3)
|
||||
{
|
||||
g_caps.supported |= BGFX_CAPS_INSTANCING;
|
||||
}
|
||||
}
|
||||
|
||||
// shadow compare is optional on 9_1 through 9_3 targets
|
||||
if (m_featureLevel <= D3D_FEATURE_LEVEL_9_3)
|
||||
{
|
||||
struct D3D11_FEATURE_DATA_D3D9_SHADOW_SUPPORT
|
||||
else
|
||||
{
|
||||
BOOL SupportsDepthAsTextureWithLessEqualComparisonFilter;
|
||||
};
|
||||
|
||||
D3D11_FEATURE_DATA_D3D9_SHADOW_SUPPORT data;
|
||||
hr = m_device->CheckFeatureSupport(D3D11_FEATURE(9) /*D3D11_FEATURE_D3D9_SHADOW_SUPPORT*/, &data, sizeof(data) );
|
||||
if (SUCCEEDED(hr)
|
||||
&& data.SupportsDepthAsTextureWithLessEqualComparisonFilter)
|
||||
{
|
||||
g_caps.supported |= BGFX_CAPS_TEXTURE_COMPARE_LEQUAL;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t ii = 0; ii < TextureFormat::Count; ++ii)
|
||||
{
|
||||
uint8_t support = BGFX_CAPS_FORMAT_TEXTURE_NONE;
|
||||
|
||||
const DXGI_FORMAT fmt = isDepth(TextureFormat::Enum(ii) )
|
||||
? s_textureFormat[ii].m_fmtDsv
|
||||
: s_textureFormat[ii].m_fmt
|
||||
;
|
||||
const DXGI_FORMAT fmtSrgb = s_textureFormat[ii].m_fmtSrgb;
|
||||
|
||||
if (DXGI_FORMAT_UNKNOWN != fmt)
|
||||
{
|
||||
struct D3D11_FEATURE_DATA_FORMAT_SUPPORT
|
||||
struct D3D11_FEATURE_DATA_D3D9_SIMPLE_INSTANCING_SUPPORT
|
||||
{
|
||||
DXGI_FORMAT InFormat;
|
||||
UINT OutFormatSupport;
|
||||
BOOL SimpleInstancingSupported;
|
||||
};
|
||||
|
||||
D3D11_FEATURE_DATA_FORMAT_SUPPORT data; // D3D11_FEATURE_DATA_FORMAT_SUPPORT2
|
||||
data.InFormat = fmt;
|
||||
hr = m_device->CheckFeatureSupport(D3D11_FEATURE_FORMAT_SUPPORT, &data, sizeof(data) );
|
||||
if (SUCCEEDED(hr) )
|
||||
D3D11_FEATURE_DATA_D3D9_SIMPLE_INSTANCING_SUPPORT data;
|
||||
hr = m_device->CheckFeatureSupport(D3D11_FEATURE(11) /*D3D11_FEATURE_D3D9_SIMPLE_INSTANCING_SUPPORT*/, &data, sizeof(data) );
|
||||
if (SUCCEEDED(hr)
|
||||
&& data.SimpleInstancingSupported)
|
||||
{
|
||||
support |= 0 != (data.OutFormatSupport & (0
|
||||
| D3D11_FORMAT_SUPPORT_TEXTURE2D
|
||||
| D3D11_FORMAT_SUPPORT_TEXTURE3D
|
||||
| D3D11_FORMAT_SUPPORT_TEXTURECUBE
|
||||
) )
|
||||
? BGFX_CAPS_FORMAT_TEXTURE_COLOR
|
||||
: BGFX_CAPS_FORMAT_TEXTURE_NONE
|
||||
;
|
||||
|
||||
support |= 0 != (data.OutFormatSupport & (0
|
||||
| D3D11_FORMAT_SUPPORT_BUFFER
|
||||
| D3D11_FORMAT_SUPPORT_IA_VERTEX_BUFFER
|
||||
| D3D11_FORMAT_SUPPORT_IA_INDEX_BUFFER
|
||||
) )
|
||||
? BGFX_CAPS_FORMAT_TEXTURE_VERTEX
|
||||
: BGFX_CAPS_FORMAT_TEXTURE_NONE
|
||||
;
|
||||
|
||||
support |= 0 != (data.OutFormatSupport & (0
|
||||
| D3D11_FORMAT_SUPPORT_SHADER_LOAD
|
||||
) )
|
||||
? BGFX_CAPS_FORMAT_TEXTURE_IMAGE
|
||||
: BGFX_CAPS_FORMAT_TEXTURE_NONE
|
||||
;
|
||||
|
||||
support |= 0 != (data.OutFormatSupport & (0
|
||||
| D3D11_FORMAT_SUPPORT_RENDER_TARGET
|
||||
| D3D11_FORMAT_SUPPORT_DEPTH_STENCIL
|
||||
) )
|
||||
? BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER
|
||||
: BGFX_CAPS_FORMAT_TEXTURE_NONE
|
||||
;
|
||||
g_caps.supported |= BGFX_CAPS_INSTANCING;
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
// shadow compare is optional on 9_1 through 9_3 targets
|
||||
if (m_featureLevel <= D3D_FEATURE_LEVEL_9_3)
|
||||
{
|
||||
struct D3D11_FEATURE_DATA_D3D9_SHADOW_SUPPORT
|
||||
{
|
||||
BX_TRACE("CheckFeatureSupport failed with %x for format %s.", hr, getName(TextureFormat::Enum(ii) ) );
|
||||
BOOL SupportsDepthAsTextureWithLessEqualComparisonFilter;
|
||||
};
|
||||
|
||||
D3D11_FEATURE_DATA_D3D9_SHADOW_SUPPORT data;
|
||||
hr = m_device->CheckFeatureSupport(D3D11_FEATURE(9) /*D3D11_FEATURE_D3D9_SHADOW_SUPPORT*/, &data, sizeof(data) );
|
||||
if (SUCCEEDED(hr)
|
||||
&& data.SupportsDepthAsTextureWithLessEqualComparisonFilter)
|
||||
{
|
||||
g_caps.supported |= BGFX_CAPS_TEXTURE_COMPARE_LEQUAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 != (support & BGFX_CAPS_FORMAT_TEXTURE_IMAGE) )
|
||||
for (uint32_t ii = 0; ii < TextureFormat::Count; ++ii)
|
||||
{
|
||||
uint8_t support = BGFX_CAPS_FORMAT_TEXTURE_NONE;
|
||||
|
||||
const DXGI_FORMAT fmt = isDepth(TextureFormat::Enum(ii) )
|
||||
? s_textureFormat[ii].m_fmtDsv
|
||||
: s_textureFormat[ii].m_fmt
|
||||
;
|
||||
const DXGI_FORMAT fmtSrgb = s_textureFormat[ii].m_fmtSrgb;
|
||||
|
||||
if (DXGI_FORMAT_UNKNOWN != fmt)
|
||||
{
|
||||
// clear image flag for additional testing
|
||||
support &= ~BGFX_CAPS_FORMAT_TEXTURE_IMAGE;
|
||||
struct D3D11_FEATURE_DATA_FORMAT_SUPPORT
|
||||
{
|
||||
DXGI_FORMAT InFormat;
|
||||
UINT OutFormatSupport;
|
||||
};
|
||||
|
||||
data.InFormat = s_textureFormat[ii].m_fmt;
|
||||
hr = m_device->CheckFeatureSupport(D3D11_FEATURE_FORMAT_SUPPORT2, &data, sizeof(data) );
|
||||
D3D11_FEATURE_DATA_FORMAT_SUPPORT data; // D3D11_FEATURE_DATA_FORMAT_SUPPORT2
|
||||
data.InFormat = fmt;
|
||||
hr = m_device->CheckFeatureSupport(D3D11_FEATURE_FORMAT_SUPPORT, &data, sizeof(data) );
|
||||
if (SUCCEEDED(hr) )
|
||||
{
|
||||
support |= 0 != (data.OutFormatSupport & (0
|
||||
| D3D11_FORMAT_SUPPORT2_UAV_TYPED_LOAD
|
||||
| D3D11_FORMAT_SUPPORT2_UAV_TYPED_STORE
|
||||
| D3D11_FORMAT_SUPPORT_TEXTURE2D
|
||||
| D3D11_FORMAT_SUPPORT_TEXTURE3D
|
||||
| D3D11_FORMAT_SUPPORT_TEXTURECUBE
|
||||
) )
|
||||
? BGFX_CAPS_FORMAT_TEXTURE_COLOR
|
||||
: BGFX_CAPS_FORMAT_TEXTURE_NONE
|
||||
;
|
||||
|
||||
support |= 0 != (data.OutFormatSupport & (0
|
||||
| D3D11_FORMAT_SUPPORT_BUFFER
|
||||
| D3D11_FORMAT_SUPPORT_IA_VERTEX_BUFFER
|
||||
| D3D11_FORMAT_SUPPORT_IA_INDEX_BUFFER
|
||||
) )
|
||||
? BGFX_CAPS_FORMAT_TEXTURE_VERTEX
|
||||
: BGFX_CAPS_FORMAT_TEXTURE_NONE
|
||||
;
|
||||
|
||||
support |= 0 != (data.OutFormatSupport & (0
|
||||
| D3D11_FORMAT_SUPPORT_SHADER_LOAD
|
||||
) )
|
||||
? BGFX_CAPS_FORMAT_TEXTURE_IMAGE
|
||||
: BGFX_CAPS_FORMAT_TEXTURE_NONE
|
||||
;
|
||||
|
||||
support |= 0 != (data.OutFormatSupport & (0
|
||||
| D3D11_FORMAT_SUPPORT_RENDER_TARGET
|
||||
| D3D11_FORMAT_SUPPORT_DEPTH_STENCIL
|
||||
) )
|
||||
? BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER
|
||||
: BGFX_CAPS_FORMAT_TEXTURE_NONE
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
BX_TRACE("CheckFeatureSupport failed with %x for format %s.", hr, getName(TextureFormat::Enum(ii) ) );
|
||||
}
|
||||
|
||||
if (0 != (support & BGFX_CAPS_FORMAT_TEXTURE_IMAGE) )
|
||||
{
|
||||
// clear image flag for additional testing
|
||||
support &= ~BGFX_CAPS_FORMAT_TEXTURE_IMAGE;
|
||||
|
||||
data.InFormat = s_textureFormat[ii].m_fmt;
|
||||
hr = m_device->CheckFeatureSupport(D3D11_FEATURE_FORMAT_SUPPORT2, &data, sizeof(data) );
|
||||
if (SUCCEEDED(hr) )
|
||||
{
|
||||
support |= 0 != (data.OutFormatSupport & (0
|
||||
| D3D11_FORMAT_SUPPORT2_UAV_TYPED_LOAD
|
||||
| D3D11_FORMAT_SUPPORT2_UAV_TYPED_STORE
|
||||
) )
|
||||
? BGFX_CAPS_FORMAT_TEXTURE_IMAGE
|
||||
: BGFX_CAPS_FORMAT_TEXTURE_NONE
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (DXGI_FORMAT_UNKNOWN != fmtSrgb)
|
||||
{
|
||||
struct D3D11_FEATURE_DATA_FORMAT_SUPPORT
|
||||
{
|
||||
DXGI_FORMAT InFormat;
|
||||
UINT OutFormatSupport;
|
||||
};
|
||||
|
||||
D3D11_FEATURE_DATA_FORMAT_SUPPORT data; // D3D11_FEATURE_DATA_FORMAT_SUPPORT2
|
||||
data.InFormat = fmtSrgb;
|
||||
hr = m_device->CheckFeatureSupport(D3D11_FEATURE_FORMAT_SUPPORT, &data, sizeof(data) );
|
||||
if (SUCCEEDED(hr) )
|
||||
{
|
||||
support |= 0 != (data.OutFormatSupport & (0
|
||||
| D3D11_FORMAT_SUPPORT_TEXTURE2D
|
||||
| D3D11_FORMAT_SUPPORT_TEXTURE3D
|
||||
| D3D11_FORMAT_SUPPORT_TEXTURECUBE
|
||||
) )
|
||||
? BGFX_CAPS_FORMAT_TEXTURE_COLOR_SRGB
|
||||
: BGFX_CAPS_FORMAT_TEXTURE_NONE
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
BX_TRACE("CheckFeatureSupport failed with %x for sRGB format %s.", hr, getName(TextureFormat::Enum(ii) ) );
|
||||
}
|
||||
}
|
||||
|
||||
g_caps.formats[ii] = support;
|
||||
}
|
||||
|
||||
if (DXGI_FORMAT_UNKNOWN != fmtSrgb)
|
||||
// Init reserved part of view name.
|
||||
for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
|
||||
{
|
||||
struct D3D11_FEATURE_DATA_FORMAT_SUPPORT
|
||||
{
|
||||
DXGI_FORMAT InFormat;
|
||||
UINT OutFormatSupport;
|
||||
};
|
||||
|
||||
D3D11_FEATURE_DATA_FORMAT_SUPPORT data; // D3D11_FEATURE_DATA_FORMAT_SUPPORT2
|
||||
data.InFormat = fmtSrgb;
|
||||
hr = m_device->CheckFeatureSupport(D3D11_FEATURE_FORMAT_SUPPORT, &data, sizeof(data) );
|
||||
if (SUCCEEDED(hr) )
|
||||
{
|
||||
support |= 0 != (data.OutFormatSupport & (0
|
||||
| D3D11_FORMAT_SUPPORT_TEXTURE2D
|
||||
| D3D11_FORMAT_SUPPORT_TEXTURE3D
|
||||
| D3D11_FORMAT_SUPPORT_TEXTURECUBE
|
||||
) )
|
||||
? BGFX_CAPS_FORMAT_TEXTURE_COLOR_SRGB
|
||||
: BGFX_CAPS_FORMAT_TEXTURE_NONE
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
BX_TRACE("CheckFeatureSupport failed with %x for sRGB format %s.", hr, getName(TextureFormat::Enum(ii) ) );
|
||||
}
|
||||
char name[BGFX_CONFIG_MAX_VIEW_NAME_RESERVED+1];
|
||||
bx::snprintf(name, sizeof(name), "%3d ", ii);
|
||||
mbstowcs(s_viewNameW[ii], name, BGFX_CONFIG_MAX_VIEW_NAME_RESERVED);
|
||||
}
|
||||
|
||||
g_caps.formats[ii] = support;
|
||||
#if !defined(__MINGW32__)
|
||||
if (BX_ENABLED(BGFX_CONFIG_DEBUG)
|
||||
&& NULL != m_infoQueue)
|
||||
{
|
||||
m_infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, true);
|
||||
}
|
||||
#endif // !defined(__MINGW32__)
|
||||
|
||||
updateMsaa();
|
||||
postReset();
|
||||
}
|
||||
|
||||
// Init reserved part of view name.
|
||||
for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
|
||||
return true;
|
||||
|
||||
error:
|
||||
switch (errorState)
|
||||
{
|
||||
char name[BGFX_CONFIG_MAX_VIEW_NAME_RESERVED+1];
|
||||
bx::snprintf(name, sizeof(name), "%3d ", ii);
|
||||
mbstowcs(s_viewNameW[ii], name, BGFX_CONFIG_MAX_VIEW_NAME_RESERVED);
|
||||
default:
|
||||
case 5:
|
||||
DX_RELEASE(m_swapChain, 0);
|
||||
|
||||
case 4:
|
||||
DX_RELEASE(m_deviceCtx, 0);
|
||||
DX_RELEASE(m_device, 0);
|
||||
|
||||
case 3:
|
||||
DX_RELEASE(m_factory, 0);
|
||||
|
||||
case 2:
|
||||
#if USE_D3D11_DYNAMIC_LIB
|
||||
if (NULL != m_dxgidebugdll)
|
||||
{
|
||||
bx::dlclose(m_dxgidebugdll);
|
||||
m_dxgidebugdll = NULL;
|
||||
}
|
||||
|
||||
if (NULL != m_d3d9dll)
|
||||
{
|
||||
bx::dlclose(m_d3d9dll);
|
||||
m_d3d9dll = NULL;
|
||||
}
|
||||
|
||||
bx::dlclose(m_dxgidll);
|
||||
m_dxgidll = NULL;
|
||||
#endif // USE_D3D11_DYNAMIC_LIB
|
||||
|
||||
case 1:
|
||||
#if USE_D3D11_DYNAMIC_LIB
|
||||
bx::dlclose(m_d3d11dll);
|
||||
m_d3d11dll = NULL;
|
||||
#endif // USE_D3D11_DYNAMIC_LIB
|
||||
|
||||
case 0:
|
||||
unloadRenderDoc(m_renderdocdll);
|
||||
m_ovr.shutdown();
|
||||
break;
|
||||
}
|
||||
|
||||
#if !defined(__MINGW32__)
|
||||
if (BX_ENABLED(BGFX_CONFIG_DEBUG)
|
||||
&& NULL != m_infoQueue)
|
||||
{
|
||||
m_infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, true);
|
||||
}
|
||||
#endif // !defined(__MINGW32__)
|
||||
|
||||
updateMsaa();
|
||||
postReset();
|
||||
return false;
|
||||
}
|
||||
|
||||
void shutdown()
|
||||
|
@ -1123,7 +1239,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
|
|||
DX_RELEASE(m_swapChain, 0);
|
||||
DX_RELEASE(m_deviceCtx, 0);
|
||||
DX_RELEASE(m_device, 0);
|
||||
DX_RELEASE(m_factory,0);
|
||||
DX_RELEASE(m_factory, 0);
|
||||
|
||||
unloadRenderDoc(m_renderdocdll);
|
||||
|
||||
|
@ -1134,12 +1250,15 @@ BX_PRAGMA_DIAGNOSTIC_POP();
|
|||
m_dxgidebugdll = NULL;
|
||||
}
|
||||
|
||||
if (NULL != m_d3d9dll)
|
||||
{
|
||||
bx::dlclose(m_d3d9dll);
|
||||
m_d3d9dll = NULL;
|
||||
}
|
||||
|
||||
bx::dlclose(m_dxgidll);
|
||||
m_dxgidll = NULL;
|
||||
|
||||
bx::dlclose(m_d3d9dll);
|
||||
m_d3d9dll = NULL;
|
||||
|
||||
bx::dlclose(m_d3d11dll);
|
||||
m_d3d11dll = NULL;
|
||||
#endif // USE_D3D11_DYNAMIC_LIB
|
||||
|
@ -2735,7 +2854,11 @@ BX_PRAGMA_DIAGNOSTIC_POP();
|
|||
RendererContextI* rendererCreate()
|
||||
{
|
||||
s_renderD3D11 = BX_NEW(g_allocator, RendererContextD3D11);
|
||||
s_renderD3D11->init();
|
||||
if (!s_renderD3D11->init() )
|
||||
{
|
||||
BX_DELETE(g_allocator, s_renderD3D11);
|
||||
s_renderD3D11 = NULL;
|
||||
}
|
||||
return s_renderD3D11;
|
||||
}
|
||||
|
||||
|
|
|
@ -413,36 +413,77 @@ namespace bgfx { namespace d3d12
|
|||
{
|
||||
}
|
||||
|
||||
void init()
|
||||
~RendererContextD3D12()
|
||||
{
|
||||
}
|
||||
|
||||
bool init()
|
||||
{
|
||||
uint32_t errorState = 0;
|
||||
LUID luid;
|
||||
|
||||
m_fbh.idx = invalidHandle;
|
||||
memset(m_uniforms, 0, sizeof(m_uniforms) );
|
||||
memset(&m_resolution, 0, sizeof(m_resolution) );
|
||||
|
||||
#if USE_D3D12_DYNAMIC_LIB
|
||||
m_d3d12dll = bx::dlopen("d3d12.dll");
|
||||
BGFX_FATAL(NULL != m_d3d12dll, Fatal::UnableToInitialize, "Failed to load d3d12.dll.");
|
||||
BX_WARN(NULL != m_d3d12dll, "Failed to load d3d12.dll.");
|
||||
if (NULL == m_d3d12dll)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
errorState = 1;
|
||||
|
||||
D3D12CreateDevice = (PFN_D3D12_CREATE_DEVICE)bx::dlsym(m_d3d12dll, "D3D12CreateDevice");
|
||||
BGFX_FATAL(NULL != D3D12CreateDevice, Fatal::UnableToInitialize, "Function D3D12CreateDevice not found.");
|
||||
BX_WARN(NULL != D3D12CreateDevice, "Function D3D12CreateDevice not found.");
|
||||
|
||||
D3D12GetDebugInterface = (PFN_D3D12_GET_DEBUG_INTERFACE)bx::dlsym(m_d3d12dll, "D3D12GetDebugInterface");
|
||||
BGFX_FATAL(NULL != D3D12GetDebugInterface, Fatal::UnableToInitialize, "Function D3D12GetDebugInterface not found.");
|
||||
BX_WARN(NULL != D3D12GetDebugInterface, "Function D3D12GetDebugInterface not found.");
|
||||
|
||||
D3D12SerializeRootSignature = (PFN_D3D12_SERIALIZE_ROOT_SIGNATURE)bx::dlsym(m_d3d12dll, "D3D12SerializeRootSignature");
|
||||
BGFX_FATAL(NULL != D3D12SerializeRootSignature, Fatal::UnableToInitialize, "Function D3D12SerializeRootSignature not found.");
|
||||
BX_WARN(NULL != D3D12SerializeRootSignature, "Function D3D12SerializeRootSignature not found.");
|
||||
|
||||
if (NULL == D3D12CreateDevice
|
||||
|| NULL == D3D12GetDebugInterface
|
||||
|| NULL == D3D12SerializeRootSignature)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
m_dxgidll = bx::dlopen("dxgi.dll");
|
||||
BGFX_FATAL(NULL != m_dxgidll, Fatal::UnableToInitialize, "Failed to load dxgi.dll.");
|
||||
BX_WARN(NULL != m_dxgidll, "Failed to load dxgi.dll.");
|
||||
|
||||
if (NULL == m_dxgidll)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
errorState = 2;
|
||||
|
||||
CreateDXGIFactory1 = (PFN_CREATE_DXGI_FACTORY)bx::dlsym(m_dxgidll, "CreateDXGIFactory1");
|
||||
BGFX_FATAL(NULL != CreateDXGIFactory1, Fatal::UnableToInitialize, "Function CreateDXGIFactory1 not found.");
|
||||
BX_WARN(NULL != CreateDXGIFactory1, "Function CreateDXGIFactory1 not found.");
|
||||
|
||||
if (NULL == CreateDXGIFactory1)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
#else
|
||||
errorState = 2;
|
||||
#endif // USE_D3D12_DYNAMIC_LIB
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
hr = CreateDXGIFactory1(__uuidof(IDXGIFactory), (void**)&m_factory);
|
||||
BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Unable to create DXGI factory.");
|
||||
BX_WARN(SUCCEEDED(hr), "Unable to create DXGI factory.");
|
||||
|
||||
if (FAILED(hr) )
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
errorState = 3;
|
||||
|
||||
m_adapter = NULL;
|
||||
m_driverType = D3D_DRIVER_TYPE_HARDWARE;
|
||||
|
@ -511,15 +552,22 @@ namespace bgfx { namespace d3d12
|
|||
, __uuidof(ID3D12Device)
|
||||
, (void**)&m_device
|
||||
);
|
||||
BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Unable to create Direct3D12 device.");
|
||||
BX_WARN(SUCCEEDED(hr), "Unable to create Direct3D12 device.");
|
||||
|
||||
if (NULL != m_adapter)
|
||||
{
|
||||
DX_RELEASE(m_adapter, 2);
|
||||
}
|
||||
|
||||
if (FAILED(hr) )
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
errorState = 4;
|
||||
|
||||
memset(&m_adapterDesc, 0, sizeof(m_adapterDesc) );
|
||||
LUID luid = m_device->GetAdapterLuid();
|
||||
luid = m_device->GetAdapterLuid();
|
||||
for (uint32_t ii = 0; DXGI_ERROR_NOT_FOUND != m_factory->EnumAdapters(ii, &adapter); ++ii)
|
||||
{
|
||||
adapter->GetDesc(&m_adapterDesc);
|
||||
|
@ -569,206 +617,235 @@ namespace bgfx { namespace d3d12
|
|||
, &m_scd
|
||||
, &m_swapChain
|
||||
);
|
||||
BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Failed to create swap chain.");
|
||||
m_resolution.m_width = BGFX_DEFAULT_WIDTH;
|
||||
m_resolution.m_height = BGFX_DEFAULT_HEIGHT;
|
||||
|
||||
DX_CHECK(m_factory->MakeWindowAssociation( (HWND)g_platformData.nwh
|
||||
, 0
|
||||
| DXGI_MWA_NO_WINDOW_CHANGES
|
||||
| DXGI_MWA_NO_ALT_ENTER
|
||||
) );
|
||||
|
||||
m_numWindows = 1;
|
||||
|
||||
if (BX_ENABLED(BGFX_CONFIG_DEBUG) )
|
||||
BX_WARN(SUCCEEDED(hr), "Failed to create swap chain.");
|
||||
if (FAILED(hr) )
|
||||
{
|
||||
hr = m_device->QueryInterface(__uuidof(ID3D12InfoQueue), (void**)&m_infoQueue);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr) )
|
||||
{
|
||||
m_resolution.m_width = BGFX_DEFAULT_WIDTH;
|
||||
m_resolution.m_height = BGFX_DEFAULT_HEIGHT;
|
||||
|
||||
DX_CHECK(m_factory->MakeWindowAssociation( (HWND)g_platformData.nwh
|
||||
, 0
|
||||
| DXGI_MWA_NO_WINDOW_CHANGES
|
||||
| DXGI_MWA_NO_ALT_ENTER
|
||||
) );
|
||||
|
||||
m_numWindows = 1;
|
||||
|
||||
if (BX_ENABLED(BGFX_CONFIG_DEBUG) )
|
||||
{
|
||||
m_infoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_CORRUPTION, true);
|
||||
m_infoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_ERROR, true);
|
||||
m_infoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_WARNING, false);
|
||||
hr = m_device->QueryInterface(__uuidof(ID3D12InfoQueue), (void**)&m_infoQueue);
|
||||
|
||||
D3D12_INFO_QUEUE_FILTER filter;
|
||||
memset(&filter, 0, sizeof(filter) );
|
||||
|
||||
D3D12_MESSAGE_CATEGORY catlist[] =
|
||||
{
|
||||
D3D12_MESSAGE_CATEGORY_STATE_SETTING,
|
||||
D3D12_MESSAGE_CATEGORY_EXECUTION,
|
||||
};
|
||||
filter.DenyList.NumCategories = BX_COUNTOF(catlist);
|
||||
filter.DenyList.pCategoryList = catlist;
|
||||
m_infoQueue->PushStorageFilter(&filter);
|
||||
|
||||
DX_RELEASE(m_infoQueue, 19);
|
||||
}
|
||||
}
|
||||
|
||||
D3D12_DESCRIPTOR_HEAP_DESC rtvDescHeap;
|
||||
rtvDescHeap.NumDescriptors = 0
|
||||
+ BX_COUNTOF(m_backBufferColor)
|
||||
+ BGFX_CONFIG_MAX_FRAME_BUFFERS*BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS
|
||||
;
|
||||
rtvDescHeap.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
|
||||
rtvDescHeap.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
|
||||
rtvDescHeap.NodeMask = 0;
|
||||
DX_CHECK(m_device->CreateDescriptorHeap(&rtvDescHeap
|
||||
, __uuidof(ID3D12DescriptorHeap)
|
||||
, (void**)&m_rtvDescriptorHeap
|
||||
) );
|
||||
|
||||
D3D12_DESCRIPTOR_HEAP_DESC dsvDescHeap;
|
||||
dsvDescHeap.NumDescriptors = 0
|
||||
+ 1 // reserved for depth backbuffer.
|
||||
+ BGFX_CONFIG_MAX_FRAME_BUFFERS
|
||||
;
|
||||
dsvDescHeap.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
|
||||
dsvDescHeap.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
|
||||
dsvDescHeap.NodeMask = 0;
|
||||
DX_CHECK(m_device->CreateDescriptorHeap(&dsvDescHeap
|
||||
, __uuidof(ID3D12DescriptorHeap)
|
||||
, (void**)&m_dsvDescriptorHeap
|
||||
) );
|
||||
|
||||
for (uint32_t ii = 0; ii < BX_COUNTOF(m_scratchBuffer); ++ii)
|
||||
{
|
||||
m_scratchBuffer[ii].create(BGFX_CONFIG_MAX_DRAW_CALLS*1024
|
||||
, BGFX_CONFIG_MAX_TEXTURES + BGFX_CONFIG_MAX_SHADERS + BGFX_CONFIG_MAX_DRAW_CALLS
|
||||
);
|
||||
}
|
||||
m_samplerAllocator.create(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER
|
||||
, 1024
|
||||
, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS
|
||||
);
|
||||
|
||||
D3D12_DESCRIPTOR_RANGE descRange[] =
|
||||
{
|
||||
{ D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, 0, 0, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND },
|
||||
{ D3D12_DESCRIPTOR_RANGE_TYPE_SRV, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, 0, 0, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND },
|
||||
{ D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0, 0, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND },
|
||||
{ D3D12_DESCRIPTOR_RANGE_TYPE_UAV, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, 0, 0, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND },
|
||||
};
|
||||
BX_STATIC_ASSERT(BX_COUNTOF(descRange) == Rdt::Count);
|
||||
|
||||
D3D12_ROOT_PARAMETER rootParameter[] =
|
||||
{
|
||||
{ D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, { 1, &descRange[Rdt::Sampler] }, D3D12_SHADER_VISIBILITY_ALL },
|
||||
{ D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, { 1, &descRange[Rdt::SRV] }, D3D12_SHADER_VISIBILITY_ALL },
|
||||
{ D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, { 1, &descRange[Rdt::CBV] }, D3D12_SHADER_VISIBILITY_ALL },
|
||||
// { D3D12_ROOT_PARAMETER_TYPE_CBV, { 0, 0 }, D3D12_SHADER_VISIBILITY_ALL },
|
||||
{ D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, { 1, &descRange[Rdt::UAV] }, D3D12_SHADER_VISIBILITY_ALL },
|
||||
};
|
||||
// rootParameter[Rdt::CBV].Constants.ShaderRegister = 0;
|
||||
// rootParameter[Rdt::CBV].Constants.RegisterSpace = 100;
|
||||
// rootParameter[Rdt::CBV].Constants.Num32BitValues = 0;
|
||||
|
||||
D3D12_ROOT_SIGNATURE_DESC descRootSignature;
|
||||
descRootSignature.NumParameters = BX_COUNTOF(rootParameter);
|
||||
descRootSignature.pParameters = rootParameter;
|
||||
descRootSignature.NumStaticSamplers = 0;
|
||||
descRootSignature.pStaticSamplers = NULL;
|
||||
descRootSignature.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
|
||||
|
||||
ID3DBlob* outBlob;
|
||||
ID3DBlob* errorBlob;
|
||||
DX_CHECK(D3D12SerializeRootSignature(&descRootSignature
|
||||
, D3D_ROOT_SIGNATURE_VERSION_1
|
||||
, &outBlob
|
||||
, &errorBlob
|
||||
) );
|
||||
|
||||
DX_CHECK(m_device->CreateRootSignature(0
|
||||
, outBlob->GetBufferPointer()
|
||||
, outBlob->GetBufferSize()
|
||||
, __uuidof(ID3D12RootSignature)
|
||||
, (void**)&m_rootSignature
|
||||
) );
|
||||
|
||||
UniformHandle handle = BGFX_INVALID_HANDLE;
|
||||
for (uint32_t ii = 0; ii < PredefinedUniform::Count; ++ii)
|
||||
{
|
||||
m_uniformReg.add(handle, getPredefinedUniformName(PredefinedUniform::Enum(ii) ), &m_predefinedUniforms[ii]);
|
||||
}
|
||||
|
||||
g_caps.supported |= ( 0
|
||||
| BGFX_CAPS_TEXTURE_3D
|
||||
| BGFX_CAPS_TEXTURE_COMPARE_ALL
|
||||
| BGFX_CAPS_INSTANCING
|
||||
| BGFX_CAPS_VERTEX_ATTRIB_HALF
|
||||
| BGFX_CAPS_FRAGMENT_DEPTH
|
||||
| BGFX_CAPS_BLEND_INDEPENDENT
|
||||
| BGFX_CAPS_COMPUTE
|
||||
| BGFX_CAPS_FRAGMENT_ORDERING
|
||||
// | BGFX_CAPS_SWAP_CHAIN
|
||||
);
|
||||
g_caps.maxTextureSize = 16384;
|
||||
g_caps.maxFBAttachments = bx::uint32_min(16, BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS);
|
||||
|
||||
for (uint32_t ii = 0; ii < TextureFormat::Count; ++ii)
|
||||
{
|
||||
uint8_t support = BGFX_CAPS_FORMAT_TEXTURE_NONE;
|
||||
|
||||
const DXGI_FORMAT fmt = isDepth(TextureFormat::Enum(ii) )
|
||||
? s_textureFormat[ii].m_fmtDsv
|
||||
: s_textureFormat[ii].m_fmt
|
||||
;
|
||||
|
||||
if (DXGI_FORMAT_UNKNOWN != fmt)
|
||||
{
|
||||
D3D12_FEATURE_DATA_FORMAT_SUPPORT data;
|
||||
data.Format = fmt;
|
||||
hr = m_device->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, &data, sizeof(data) );
|
||||
if (SUCCEEDED(hr) )
|
||||
{
|
||||
support |= 0 != (data.Support1 & (0
|
||||
| D3D12_FORMAT_SUPPORT1_TEXTURE2D
|
||||
| D3D12_FORMAT_SUPPORT1_TEXTURE3D
|
||||
| D3D12_FORMAT_SUPPORT1_TEXTURECUBE
|
||||
) )
|
||||
? BGFX_CAPS_FORMAT_TEXTURE_COLOR
|
||||
: BGFX_CAPS_FORMAT_TEXTURE_NONE
|
||||
;
|
||||
m_infoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_CORRUPTION, true);
|
||||
m_infoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_ERROR, true);
|
||||
m_infoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_WARNING, false);
|
||||
|
||||
support |= 0 != (data.Support1 & (0
|
||||
| D3D12_FORMAT_SUPPORT1_BUFFER
|
||||
| D3D12_FORMAT_SUPPORT1_IA_VERTEX_BUFFER
|
||||
| D3D12_FORMAT_SUPPORT1_IA_INDEX_BUFFER
|
||||
) )
|
||||
? BGFX_CAPS_FORMAT_TEXTURE_VERTEX
|
||||
: BGFX_CAPS_FORMAT_TEXTURE_NONE
|
||||
;
|
||||
D3D12_INFO_QUEUE_FILTER filter;
|
||||
memset(&filter, 0, sizeof(filter) );
|
||||
|
||||
support |= 0 != (data.Support1 & (0
|
||||
| D3D12_FORMAT_SUPPORT1_SHADER_LOAD
|
||||
) )
|
||||
? BGFX_CAPS_FORMAT_TEXTURE_IMAGE
|
||||
: BGFX_CAPS_FORMAT_TEXTURE_NONE
|
||||
;
|
||||
D3D12_MESSAGE_CATEGORY catlist[] =
|
||||
{
|
||||
D3D12_MESSAGE_CATEGORY_STATE_SETTING,
|
||||
D3D12_MESSAGE_CATEGORY_EXECUTION,
|
||||
};
|
||||
filter.DenyList.NumCategories = BX_COUNTOF(catlist);
|
||||
filter.DenyList.pCategoryList = catlist;
|
||||
m_infoQueue->PushStorageFilter(&filter);
|
||||
|
||||
support |= 0 != (data.Support1 & (0
|
||||
| D3D12_FORMAT_SUPPORT1_RENDER_TARGET
|
||||
| D3D12_FORMAT_SUPPORT1_DEPTH_STENCIL
|
||||
) )
|
||||
? BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER
|
||||
: BGFX_CAPS_FORMAT_TEXTURE_NONE
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
BX_TRACE("CheckFeatureSupport failed with %x for format %s.", hr, getName(TextureFormat::Enum(ii) ) );
|
||||
DX_RELEASE(m_infoQueue, 19);
|
||||
}
|
||||
}
|
||||
|
||||
g_caps.formats[ii] = support;
|
||||
D3D12_DESCRIPTOR_HEAP_DESC rtvDescHeap;
|
||||
rtvDescHeap.NumDescriptors = 0
|
||||
+ BX_COUNTOF(m_backBufferColor)
|
||||
+ BGFX_CONFIG_MAX_FRAME_BUFFERS*BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS
|
||||
;
|
||||
rtvDescHeap.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
|
||||
rtvDescHeap.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
|
||||
rtvDescHeap.NodeMask = 0;
|
||||
DX_CHECK(m_device->CreateDescriptorHeap(&rtvDescHeap
|
||||
, __uuidof(ID3D12DescriptorHeap)
|
||||
, (void**)&m_rtvDescriptorHeap
|
||||
) );
|
||||
|
||||
D3D12_DESCRIPTOR_HEAP_DESC dsvDescHeap;
|
||||
dsvDescHeap.NumDescriptors = 0
|
||||
+ 1 // reserved for depth backbuffer.
|
||||
+ BGFX_CONFIG_MAX_FRAME_BUFFERS
|
||||
;
|
||||
dsvDescHeap.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
|
||||
dsvDescHeap.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
|
||||
dsvDescHeap.NodeMask = 0;
|
||||
DX_CHECK(m_device->CreateDescriptorHeap(&dsvDescHeap
|
||||
, __uuidof(ID3D12DescriptorHeap)
|
||||
, (void**)&m_dsvDescriptorHeap
|
||||
) );
|
||||
|
||||
for (uint32_t ii = 0; ii < BX_COUNTOF(m_scratchBuffer); ++ii)
|
||||
{
|
||||
m_scratchBuffer[ii].create(BGFX_CONFIG_MAX_DRAW_CALLS*1024
|
||||
, BGFX_CONFIG_MAX_TEXTURES + BGFX_CONFIG_MAX_SHADERS + BGFX_CONFIG_MAX_DRAW_CALLS
|
||||
);
|
||||
}
|
||||
m_samplerAllocator.create(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER
|
||||
, 1024
|
||||
, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS
|
||||
);
|
||||
|
||||
D3D12_DESCRIPTOR_RANGE descRange[] =
|
||||
{
|
||||
{ D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, 0, 0, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND },
|
||||
{ D3D12_DESCRIPTOR_RANGE_TYPE_SRV, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, 0, 0, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND },
|
||||
{ D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0, 0, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND },
|
||||
{ D3D12_DESCRIPTOR_RANGE_TYPE_UAV, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, 0, 0, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND },
|
||||
};
|
||||
BX_STATIC_ASSERT(BX_COUNTOF(descRange) == Rdt::Count);
|
||||
|
||||
D3D12_ROOT_PARAMETER rootParameter[] =
|
||||
{
|
||||
{ D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, { 1, &descRange[Rdt::Sampler] }, D3D12_SHADER_VISIBILITY_ALL },
|
||||
{ D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, { 1, &descRange[Rdt::SRV] }, D3D12_SHADER_VISIBILITY_ALL },
|
||||
{ D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, { 1, &descRange[Rdt::CBV] }, D3D12_SHADER_VISIBILITY_ALL },
|
||||
// { D3D12_ROOT_PARAMETER_TYPE_CBV, { 0, 0 }, D3D12_SHADER_VISIBILITY_ALL },
|
||||
{ D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, { 1, &descRange[Rdt::UAV] }, D3D12_SHADER_VISIBILITY_ALL },
|
||||
};
|
||||
// rootParameter[Rdt::CBV].Constants.ShaderRegister = 0;
|
||||
// rootParameter[Rdt::CBV].Constants.RegisterSpace = 100;
|
||||
// rootParameter[Rdt::CBV].Constants.Num32BitValues = 0;
|
||||
|
||||
D3D12_ROOT_SIGNATURE_DESC descRootSignature;
|
||||
descRootSignature.NumParameters = BX_COUNTOF(rootParameter);
|
||||
descRootSignature.pParameters = rootParameter;
|
||||
descRootSignature.NumStaticSamplers = 0;
|
||||
descRootSignature.pStaticSamplers = NULL;
|
||||
descRootSignature.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
|
||||
|
||||
ID3DBlob* outBlob;
|
||||
ID3DBlob* errorBlob;
|
||||
DX_CHECK(D3D12SerializeRootSignature(&descRootSignature
|
||||
, D3D_ROOT_SIGNATURE_VERSION_1
|
||||
, &outBlob
|
||||
, &errorBlob
|
||||
) );
|
||||
|
||||
DX_CHECK(m_device->CreateRootSignature(0
|
||||
, outBlob->GetBufferPointer()
|
||||
, outBlob->GetBufferSize()
|
||||
, __uuidof(ID3D12RootSignature)
|
||||
, (void**)&m_rootSignature
|
||||
) );
|
||||
|
||||
UniformHandle handle = BGFX_INVALID_HANDLE;
|
||||
for (uint32_t ii = 0; ii < PredefinedUniform::Count; ++ii)
|
||||
{
|
||||
m_uniformReg.add(handle, getPredefinedUniformName(PredefinedUniform::Enum(ii) ), &m_predefinedUniforms[ii]);
|
||||
}
|
||||
|
||||
g_caps.supported |= ( 0
|
||||
| BGFX_CAPS_TEXTURE_3D
|
||||
| BGFX_CAPS_TEXTURE_COMPARE_ALL
|
||||
| BGFX_CAPS_INSTANCING
|
||||
| BGFX_CAPS_VERTEX_ATTRIB_HALF
|
||||
| BGFX_CAPS_FRAGMENT_DEPTH
|
||||
| BGFX_CAPS_BLEND_INDEPENDENT
|
||||
| BGFX_CAPS_COMPUTE
|
||||
| BGFX_CAPS_FRAGMENT_ORDERING
|
||||
// | BGFX_CAPS_SWAP_CHAIN
|
||||
);
|
||||
g_caps.maxTextureSize = 16384;
|
||||
g_caps.maxFBAttachments = bx::uint32_min(16, BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS);
|
||||
|
||||
for (uint32_t ii = 0; ii < TextureFormat::Count; ++ii)
|
||||
{
|
||||
uint8_t support = BGFX_CAPS_FORMAT_TEXTURE_NONE;
|
||||
|
||||
const DXGI_FORMAT fmt = isDepth(TextureFormat::Enum(ii) )
|
||||
? s_textureFormat[ii].m_fmtDsv
|
||||
: s_textureFormat[ii].m_fmt
|
||||
;
|
||||
|
||||
if (DXGI_FORMAT_UNKNOWN != fmt)
|
||||
{
|
||||
D3D12_FEATURE_DATA_FORMAT_SUPPORT data;
|
||||
data.Format = fmt;
|
||||
hr = m_device->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, &data, sizeof(data) );
|
||||
if (SUCCEEDED(hr) )
|
||||
{
|
||||
support |= 0 != (data.Support1 & (0
|
||||
| D3D12_FORMAT_SUPPORT1_TEXTURE2D
|
||||
| D3D12_FORMAT_SUPPORT1_TEXTURE3D
|
||||
| D3D12_FORMAT_SUPPORT1_TEXTURECUBE
|
||||
) )
|
||||
? BGFX_CAPS_FORMAT_TEXTURE_COLOR
|
||||
: BGFX_CAPS_FORMAT_TEXTURE_NONE
|
||||
;
|
||||
|
||||
support |= 0 != (data.Support1 & (0
|
||||
| D3D12_FORMAT_SUPPORT1_BUFFER
|
||||
| D3D12_FORMAT_SUPPORT1_IA_VERTEX_BUFFER
|
||||
| D3D12_FORMAT_SUPPORT1_IA_INDEX_BUFFER
|
||||
) )
|
||||
? BGFX_CAPS_FORMAT_TEXTURE_VERTEX
|
||||
: BGFX_CAPS_FORMAT_TEXTURE_NONE
|
||||
;
|
||||
|
||||
support |= 0 != (data.Support1 & (0
|
||||
| D3D12_FORMAT_SUPPORT1_SHADER_LOAD
|
||||
) )
|
||||
? BGFX_CAPS_FORMAT_TEXTURE_IMAGE
|
||||
: BGFX_CAPS_FORMAT_TEXTURE_NONE
|
||||
;
|
||||
|
||||
support |= 0 != (data.Support1 & (0
|
||||
| D3D12_FORMAT_SUPPORT1_RENDER_TARGET
|
||||
| D3D12_FORMAT_SUPPORT1_DEPTH_STENCIL
|
||||
) )
|
||||
? BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER
|
||||
: BGFX_CAPS_FORMAT_TEXTURE_NONE
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
BX_TRACE("CheckFeatureSupport failed with %x for format %s.", hr, getName(TextureFormat::Enum(ii) ) );
|
||||
}
|
||||
}
|
||||
|
||||
g_caps.formats[ii] = support;
|
||||
}
|
||||
|
||||
postReset();
|
||||
}
|
||||
return true;
|
||||
|
||||
error:
|
||||
switch (errorState)
|
||||
{
|
||||
default:
|
||||
case 4:
|
||||
m_cmd.shutdown();
|
||||
DX_RELEASE(m_device, 0);
|
||||
case 3:
|
||||
DX_RELEASE(m_factory, 0);
|
||||
#if USE_D3D12_DYNAMIC_LIB
|
||||
case 2:
|
||||
bx::dlclose(m_dxgidll);
|
||||
case 1:
|
||||
bx::dlclose(m_d3d12dll);
|
||||
#endif // USE_D3D12_DYNAMIC_LIB
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
|
||||
postReset();
|
||||
return false;
|
||||
}
|
||||
|
||||
~RendererContextD3D12()
|
||||
void shutdown()
|
||||
{
|
||||
preReset();
|
||||
|
||||
|
@ -811,6 +888,7 @@ namespace bgfx { namespace d3d12
|
|||
m_cmd.shutdown();
|
||||
|
||||
DX_RELEASE(m_device, 0);
|
||||
DX_RELEASE(m_factory, 0);
|
||||
|
||||
#if USE_D3D12_DYNAMIC_LIB
|
||||
bx::dlclose(m_d3d12dll);
|
||||
|
@ -2188,12 +2266,17 @@ data.NumQualityLevels = 0;
|
|||
RendererContextI* rendererCreate()
|
||||
{
|
||||
s_renderD3D12 = BX_NEW(g_allocator, RendererContextD3D12);
|
||||
s_renderD3D12->init();
|
||||
if (!s_renderD3D12->init() )
|
||||
{
|
||||
BX_DELETE(g_allocator, s_renderD3D12);
|
||||
s_renderD3D12 = NULL;
|
||||
}
|
||||
return s_renderD3D12;
|
||||
}
|
||||
|
||||
void rendererDestroy()
|
||||
{
|
||||
s_renderD3D12->shutdown();
|
||||
BX_DELETE(g_allocator, s_renderD3D12);
|
||||
s_renderD3D12 = NULL;
|
||||
}
|
||||
|
|
|
@ -291,8 +291,10 @@ namespace bgfx { namespace d3d9
|
|||
{
|
||||
}
|
||||
|
||||
void init()
|
||||
bool init()
|
||||
{
|
||||
uint32_t errorState = 0;
|
||||
|
||||
m_fbh.idx = invalidHandle;
|
||||
memset(m_uniforms, 0, sizeof(m_uniforms) );
|
||||
memset(&m_resolution, 0, sizeof(m_resolution) );
|
||||
|
@ -323,7 +325,14 @@ namespace bgfx { namespace d3d9
|
|||
m_params.BackBufferHeight = rect.bottom-rect.top;
|
||||
|
||||
m_d3d9dll = bx::dlopen("d3d9.dll");
|
||||
BGFX_FATAL(NULL != m_d3d9dll, Fatal::UnableToInitialize, "Failed to load d3d9.dll.");
|
||||
BX_WARN(NULL != m_d3d9dll, "Failed to load d3d9.dll.");
|
||||
|
||||
if (NULL == m_d3d9dll)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
errorState = 1;
|
||||
|
||||
if (BX_ENABLED(BGFX_CONFIG_DEBUG_PIX) )
|
||||
{
|
||||
|
@ -351,12 +360,25 @@ namespace bgfx { namespace d3d9
|
|||
#endif // BGFX_CONFIG_RENDERER_DIRECT3D9EX
|
||||
{
|
||||
Direct3DCreate9 = (Direct3DCreate9Fn)bx::dlsym(m_d3d9dll, "Direct3DCreate9");
|
||||
BGFX_FATAL(NULL != Direct3DCreate9, Fatal::UnableToInitialize, "Function Direct3DCreate9 not found.");
|
||||
BX_WARN(NULL != Direct3DCreate9, "Function Direct3DCreate9 not found.");
|
||||
|
||||
if (NULL == Direct3DCreate9)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
m_d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
|
||||
m_pool = D3DPOOL_MANAGED;
|
||||
}
|
||||
|
||||
BGFX_FATAL(m_d3d9, Fatal::UnableToInitialize, "Unable to create Direct3D.");
|
||||
BX_WARN(NULL != m_d3d9, "Unable to create Direct3D.");
|
||||
|
||||
if (NULL == m_d3d9)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
errorState = 2;
|
||||
|
||||
m_adapter = D3DADAPTER_DEFAULT;
|
||||
m_deviceType = BGFX_PCI_ID_SOFTWARE_RASTERIZER == g_caps.vendorId
|
||||
|
@ -442,7 +464,14 @@ namespace bgfx { namespace d3d9
|
|||
#endif // BGFX_CONFIG_RENDERER_DIRECT3D9EX
|
||||
}
|
||||
|
||||
BGFX_FATAL(m_device, Fatal::UnableToInitialize, "Unable to create Direct3D9 device.");
|
||||
BX_WARN(NULL != m_device, "Unable to create Direct3D9 device.");
|
||||
|
||||
if (NULL == m_device)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
errorState = 3;
|
||||
|
||||
m_numWindows = 1;
|
||||
|
||||
|
@ -456,15 +485,23 @@ namespace bgfx { namespace d3d9
|
|||
DX_CHECK(m_device->GetDeviceCaps(&m_caps) );
|
||||
|
||||
// For shit GPUs that can create DX9 device but can't do simple stuff. GTFO!
|
||||
BGFX_FATAL( (D3DPTEXTURECAPS_SQUAREONLY & m_caps.TextureCaps) == 0, Fatal::MinimumRequiredSpecs, "D3DPTEXTURECAPS_SQUAREONLY");
|
||||
BGFX_FATAL( (D3DPTEXTURECAPS_MIPMAP & m_caps.TextureCaps) == D3DPTEXTURECAPS_MIPMAP, Fatal::MinimumRequiredSpecs, "D3DPTEXTURECAPS_MIPMAP");
|
||||
BGFX_FATAL( (D3DPTEXTURECAPS_ALPHA & m_caps.TextureCaps) == D3DPTEXTURECAPS_ALPHA, Fatal::MinimumRequiredSpecs, "D3DPTEXTURECAPS_ALPHA");
|
||||
BGFX_FATAL(m_caps.VertexShaderVersion >= D3DVS_VERSION(2, 0) && m_caps.PixelShaderVersion >= D3DPS_VERSION(2, 1)
|
||||
, Fatal::MinimumRequiredSpecs
|
||||
BX_WARN( (D3DPTEXTURECAPS_SQUAREONLY & m_caps.TextureCaps) == 0, "D3DPTEXTURECAPS_SQUAREONLY");
|
||||
BX_WARN( (D3DPTEXTURECAPS_MIPMAP & m_caps.TextureCaps) == D3DPTEXTURECAPS_MIPMAP, "D3DPTEXTURECAPS_MIPMAP");
|
||||
BX_WARN( (D3DPTEXTURECAPS_ALPHA & m_caps.TextureCaps) == D3DPTEXTURECAPS_ALPHA, "D3DPTEXTURECAPS_ALPHA");
|
||||
BX_WARN(m_caps.VertexShaderVersion >= D3DVS_VERSION(2, 0) && m_caps.PixelShaderVersion >= D3DPS_VERSION(2, 1)
|
||||
, "Shader Model Version (vs: %x, ps: %x)."
|
||||
, m_caps.VertexShaderVersion
|
||||
, m_caps.PixelShaderVersion
|
||||
);
|
||||
|
||||
if ( (D3DPTEXTURECAPS_SQUAREONLY & m_caps.TextureCaps) != 0
|
||||
|| (D3DPTEXTURECAPS_MIPMAP & m_caps.TextureCaps) != D3DPTEXTURECAPS_MIPMAP
|
||||
|| (D3DPTEXTURECAPS_ALPHA & m_caps.TextureCaps) != D3DPTEXTURECAPS_ALPHA
|
||||
|| !(m_caps.VertexShaderVersion >= D3DVS_VERSION(2, 0) && m_caps.PixelShaderVersion >= D3DPS_VERSION(2, 1) ) )
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
BX_TRACE("Max vertex shader 3.0 instr. slots: %d", m_caps.MaxVertexShader30InstructionSlots);
|
||||
BX_TRACE("Max vertex shader constants: %d", m_caps.MaxVertexShaderConst);
|
||||
BX_TRACE("Max fragment shader 2.0 instr. slots: %d", m_caps.PS20Caps.NumInstructionSlots);
|
||||
|
@ -632,6 +669,50 @@ namespace bgfx { namespace d3d9
|
|||
postReset();
|
||||
|
||||
m_initialized = true;
|
||||
|
||||
return true;
|
||||
|
||||
error:
|
||||
switch (errorState)
|
||||
{
|
||||
default:
|
||||
|
||||
case 3:
|
||||
#if BGFX_CONFIG_RENDERER_DIRECT3D9EX
|
||||
if (NULL != m_d3d9ex)
|
||||
{
|
||||
DX_RELEASE(m_deviceEx, 1);
|
||||
DX_RELEASE(m_device, 0);
|
||||
}
|
||||
else
|
||||
#endif // BGFX_CONFIG_RENDERER_DIRECT3D9EX
|
||||
{
|
||||
DX_RELEASE(m_device, 0);
|
||||
}
|
||||
|
||||
case 2:
|
||||
#if BGFX_CONFIG_RENDERER_DIRECT3D9EX
|
||||
if (NULL != m_d3d9ex)
|
||||
{
|
||||
DX_RELEASE(m_d3d9, 1);
|
||||
DX_RELEASE(m_d3d9ex, 0);
|
||||
}
|
||||
else
|
||||
#endif // BGFX_CONFIG_RENDERER_DIRECT3D9EX
|
||||
{
|
||||
DX_RELEASE(m_d3d9, 0);
|
||||
}
|
||||
|
||||
#if BX_PLATFORM_WINDOWS
|
||||
case 1:
|
||||
bx::dlclose(m_d3d9dll);
|
||||
#endif // BX_PLATFORM_WINDOWS
|
||||
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void shutdown()
|
||||
|
@ -1800,7 +1881,11 @@ namespace bgfx { namespace d3d9
|
|||
RendererContextI* rendererCreate()
|
||||
{
|
||||
s_renderD3D9 = BX_NEW(g_allocator, RendererContextD3D9);
|
||||
s_renderD3D9->init();
|
||||
if (!s_renderD3D9->init() )
|
||||
{
|
||||
BX_DELETE(g_allocator, s_renderD3D9);
|
||||
s_renderD3D9 = NULL;
|
||||
}
|
||||
return s_renderD3D9;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue