diff --git a/include/bgfx.c99.h b/include/bgfx.c99.h index 43effbcc5..b7e930edb 100644 --- a/include/bgfx.c99.h +++ b/include/bgfx.c99.h @@ -272,6 +272,15 @@ typedef struct bgfx_texture_info } bgfx_texture_info_t; +/** + */ +typedef struct bgfx_caps_gpu +{ + uint16_t vendorId; + uint16_t deviceId; + +} bgfx_caps_gpu_t; + /** * Renderer capabilities. */ @@ -293,6 +302,11 @@ typedef struct bgfx_caps uint16_t maxViews; /* < Maximum views. */ uint16_t maxDrawCalls; /* < Maximum draw calls. */ uint8_t maxFBAttachments; /* < Maximum frame buffer attachments. */ + uint8_t numGPUs; /* < */ + + uint16_t vendorId; /* < */ + uint16_t deviceId; /* < */ + bgfx_caps_gpu_t gpu[4]; /* < */ /** * Supported texture formats. diff --git a/include/bgfx.h b/include/bgfx.h index dd3b4c5db..0581e7a38 100644 --- a/include/bgfx.h +++ b/include/bgfx.h @@ -315,6 +315,18 @@ namespace bgfx uint16_t maxViews; ///< Maximum views. uint16_t maxDrawCalls; ///< Maximum draw calls. uint8_t maxFBAttachments; ///< Maximum frame buffer attachments. + uint8_t numGPUs; ///< + + uint16_t vendorId; ///< + uint16_t deviceId; ///< + + struct GPU + { + uint16_t vendorId; + uint16_t deviceId; + }; + + GPU gpu[4]; ///< /// Supported texture formats. /// - `BGFX_CAPS_FORMAT_TEXTURE_NONE` - not supported @@ -517,7 +529,7 @@ namespace bgfx /// /// @attention C99 equivalent is `bgfx_init`. /// - void init(RendererType::Enum _type = RendererType::Count, CallbackI* _callback = NULL, bx::ReallocatorI* _reallocator = NULL); + 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); /// Shutdown bgfx library. /// diff --git a/include/bgfxdefines.h b/include/bgfxdefines.h index d7bfd6276..f8878a9e0 100644 --- a/include/bgfxdefines.h +++ b/include/bgfxdefines.h @@ -333,4 +333,10 @@ #define BGFX_SUBMIT_EYE_MASK UINT8_C(0x03) #define BGFX_SUBMIT_EYE_FIRST BGFX_SUBMIT_EYE_LEFT +/// +#define BGFX_PCI_ID_NONE UINT16_C(0x0000) +#define BGFX_PCI_ID_AMD UINT16_C(0x1002) +#define BGFX_PCI_ID_INTEL UINT16_C(0x8086) +#define BGFX_PCI_ID_NVIDIA UINT16_C(0x10de) + #endif // BGFX_DEFINES_H_HEADER_GUARD diff --git a/src/bgfx.cpp b/src/bgfx.cpp index db3bb3318..1a7e59d5f 100644 --- a/src/bgfx.cpp +++ b/src/bgfx.cpp @@ -1977,7 +1977,7 @@ again: return s_rendererCreator[_type].name; } - void init(RendererType::Enum _type, CallbackI* _callback, bx::ReallocatorI* _allocator) + void init(RendererType::Enum _type, uint16_t _vendorId, uint16_t _deviceId, CallbackI* _callback, bx::ReallocatorI* _allocator) { BX_CHECK(NULL == s_ctx, "bgfx is already initialized."); BX_TRACE("Init..."); @@ -1989,6 +1989,8 @@ again: g_caps.maxViews = BGFX_CONFIG_MAX_VIEWS; g_caps.maxDrawCalls = BGFX_CONFIG_MAX_DRAW_CALLS; g_caps.maxFBAttachments = 1; + g_caps.vendorId = _vendorId; + g_caps.deviceId = _deviceId; if (NULL != _allocator) { @@ -3015,6 +3017,8 @@ 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, struct bgfx_callback_interface* _callback, struct bgfx_reallocator_interface* _allocator) { return bgfx::init(bgfx::RendererType::Enum(_type) + , BGFX_PCI_ID_NONE + , 0 , reinterpret_cast(_callback) , reinterpret_cast(_allocator) ); diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index 7f840dc0f..6dafafbf9 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -513,7 +513,10 @@ namespace bgfx { namespace d3d11 m_driverType = D3D_DRIVER_TYPE_HARDWARE; IDXGIAdapter* adapter; - for (uint32_t ii = 0; DXGI_ERROR_NOT_FOUND != factory->EnumAdapters(ii, &adapter); ++ii) + for (uint32_t ii = 0 + ; DXGI_ERROR_NOT_FOUND != factory->EnumAdapters(ii, &adapter) && ii < BX_COUNTOF(g_caps.gpu) + ; ++ii + ) { DXGI_ADAPTER_DESC desc; hr = adapter->GetDesc(&desc); @@ -536,6 +539,19 @@ namespace bgfx { namespace d3d11 , desc.SharedSystemMemory ); + g_caps.gpu[ii].vendorId = (uint16_t)desc.VendorId; + g_caps.gpu[ii].deviceId = (uint16_t)desc.DeviceId; + ++g_caps.numGPUs; + + if ( (BGFX_PCI_ID_NONE != g_caps.vendorId || 0 != g_caps.deviceId) + && (BGFX_PCI_ID_NONE == g_caps.vendorId || desc.VendorId == g_caps.vendorId) + && ( 0 == g_caps.deviceId || desc.DeviceId == g_caps.deviceId) ) + { + m_adapter = adapter; + m_adapter->AddRef(); + m_driverType = D3D_DRIVER_TYPE_UNKNOWN; + } + if (BX_ENABLED(BGFX_CONFIG_DEBUG_PERFHUD) && 0 != strstr(description, "PerfHUD") ) { @@ -594,6 +610,11 @@ namespace bgfx { namespace d3d11 } BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Unable to create Direct3D11 device."); + if (NULL != m_adapter) + { + DX_RELEASE(m_adapter, 2); + } + IDXGIDevice* device = NULL; hr = E_FAIL; for (uint32_t ii = 0; ii < BX_COUNTOF(s_deviceIIDs) && FAILED(hr); ++ii) @@ -616,6 +637,8 @@ namespace bgfx { namespace d3d11 hr = adapter->GetDesc(&m_adapterDesc); BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Unable to create Direct3D11 device."); + g_caps.vendorId = (uint16_t)m_adapterDesc.VendorId; + g_caps.deviceId = (uint16_t)m_adapterDesc.DeviceId; #if BX_PLATFORM_WINRT hr = adapter->GetParent(__uuidof(IDXGIFactory2), (void**)&m_factory); diff --git a/src/renderer_d3d9.cpp b/src/renderer_d3d9.cpp index d1381054c..83b08b729 100644 --- a/src/renderer_d3d9.cpp +++ b/src/renderer_d3d9.cpp @@ -359,26 +359,36 @@ namespace bgfx { namespace d3d9 m_adapter = D3DADAPTER_DEFAULT; m_deviceType = D3DDEVTYPE_HAL; - uint32_t adapterCount = m_d3d9->GetAdapterCount(); - for (uint32_t ii = 0; ii < adapterCount; ++ii) + uint8_t numGPUs = bx::uint32_min(BX_COUNTOF(g_caps.gpu), m_d3d9->GetAdapterCount() ); + for (uint32_t ii = 0; ii < numGPUs; ++ii) { - D3DADAPTER_IDENTIFIER9 identifier; - HRESULT hr = m_d3d9->GetAdapterIdentifier(ii, 0, &identifier); + D3DADAPTER_IDENTIFIER9 desc; + HRESULT hr = m_d3d9->GetAdapterIdentifier(ii, 0, &desc); if (SUCCEEDED(hr) ) { BX_TRACE("Adapter #%d", ii); - BX_TRACE("\tDriver: %s", identifier.Driver); - BX_TRACE("\tDescription: %s", identifier.Description); - BX_TRACE("\tDeviceName: %s", identifier.DeviceName); + BX_TRACE("\tDriver: %s", desc.Driver); + BX_TRACE("\tDescription: %s", desc.Description); + BX_TRACE("\tDeviceName: %s", desc.DeviceName); BX_TRACE("\tVendorId: 0x%08x, DeviceId: 0x%08x, SubSysId: 0x%08x, Revision: 0x%08x" - , identifier.VendorId - , identifier.DeviceId - , identifier.SubSysId - , identifier.Revision + , desc.VendorId + , desc.DeviceId + , desc.SubSysId + , desc.Revision ); + g_caps.gpu[ii].vendorId = (uint16_t)desc.VendorId; + g_caps.gpu[ii].deviceId = (uint16_t)desc.DeviceId; + + if ( (BGFX_PCI_ID_NONE != g_caps.vendorId || 0 != g_caps.deviceId) + && (BGFX_PCI_ID_NONE == g_caps.vendorId || desc.VendorId == g_caps.vendorId) + && ( 0 == g_caps.deviceId || desc.DeviceId == g_caps.deviceId) ) + { + m_adapter = ii; + } + #if BGFX_CONFIG_DEBUG_PERFHUD - if (0 != strstr(identifier.Description, "PerfHUD") ) + if (0 != strstr(desc.Description, "PerfHUD") ) { m_adapter = ii; m_deviceType = D3DDEVTYPE_REF; @@ -388,8 +398,10 @@ namespace bgfx { namespace d3d9 } DX_CHECK(m_d3d9->GetAdapterIdentifier(m_adapter, 0, &m_identifier) ); - m_amd = m_identifier.VendorId == 0x1002; - m_nvidia = m_identifier.VendorId == 0x10de; + m_amd = m_identifier.VendorId == BGFX_PCI_ID_AMD; + m_nvidia = m_identifier.VendorId == BGFX_PCI_ID_NVIDIA; + g_caps.vendorId = (uint16_t)m_identifier.VendorId; + g_caps.deviceId = (uint16_t)m_identifier.DeviceId; uint32_t behaviorFlags[] = {