Browse Source

Added ability to select GPU.

Branimir Karadžić 10 years ago
parent
commit
eeb491883d
6 changed files with 88 additions and 17 deletions
  1. 14 0
      include/bgfx.c99.h
  2. 13 1
      include/bgfx.h
  3. 6 0
      include/bgfxdefines.h
  4. 5 1
      src/bgfx.cpp
  5. 24 1
      src/renderer_d3d11.cpp
  6. 26 14
      src/renderer_d3d9.cpp

+ 14 - 0
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.

+ 13 - 1
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.
 	///

+ 6 - 0
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

+ 5 - 1
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<bgfx::CallbackI*>(_callback)
 		, reinterpret_cast<bx::ReallocatorI*>(_allocator)
 		);

+ 24 - 1
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);

+ 26 - 14
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[] =
 			{