libobs: Add function to enumerate video adapters

The gs_enum_adapters function is an optional implementation to allow
enumeration of available graphics adapters that can be used with the
program.  The ID associated with the adapter can be an index or a hash
depending on the implementation.
master
jp9000 2015-01-14 21:08:33 -08:00
parent 05fc9c5b78
commit 1cb02d5879
6 changed files with 78 additions and 0 deletions

View File

@ -469,6 +469,56 @@ const char *device_preprocessor_name(void)
return "_D3D11";
}
static inline void EnumD3DAdapters(
bool (*callback)(void*, const char*, uint32_t),
void *param)
{
ComPtr<IDXGIFactory1> factory;
ComPtr<IDXGIAdapter1> adapter;
HRESULT hr;
UINT i = 0;
IID factoryIID = (GetWinVer() >= 0x602) ? dxgiFactory2 :
__uuidof(IDXGIFactory1);
hr = CreateDXGIFactory1(factoryIID, (void**)factory.Assign());
if (FAILED(hr))
throw HRError("Failed to create DXGIFactory", hr);
while (factory->EnumAdapters1(i++, adapter.Assign()) == S_OK) {
DXGI_ADAPTER_DESC desc;
char name[512] = "";
hr = adapter->GetDesc(&desc);
if (FAILED(hr))
continue;
/* ignore microsoft's 'basic' renderer' */
if (desc.VendorId == 0x1414 && desc.DeviceId == 0x8c)
continue;
os_wcs_to_utf8(desc.Description, 0, name, sizeof(name));
if (!callback(param, name, i - 1))
break;
}
}
bool device_enum_adapters(
bool (*callback)(void *param, const char *name, uint32_t id),
void *param)
{
try {
EnumD3DAdapters(callback, param);
return true;
} catch (HRError error) {
blog(LOG_WARNING, "Failed enumerating devices: %s (%08lX)",
error.str, error.hr);
return false;
}
}
int device_create(gs_device_t **p_device, const gs_init_data *data)
{
gs_device *device = NULL;

View File

@ -25,6 +25,9 @@ extern "C" {
EXPORT const char *device_get_name(void);
EXPORT int device_get_type(void);
EXPORT bool device_enum_adapters(
bool (*callback)(void *param, const char *name, uint32_t id),
void *param);
EXPORT const char *device_preprocessor_name(void);
EXPORT int device_create(gs_device_t **device, const struct gs_init_data *data);
EXPORT void device_destroy(gs_device_t *device);

View File

@ -42,6 +42,7 @@ bool load_graphics_imports(struct gs_exports *exports, void *module,
GRAPHICS_IMPORT(device_get_name);
GRAPHICS_IMPORT(device_get_type);
GRAPHICS_IMPORT_OPTIONAL(device_enum_adapters);
GRAPHICS_IMPORT(device_preprocessor_name);
GRAPHICS_IMPORT(device_create);
GRAPHICS_IMPORT(device_destroy);

View File

@ -26,6 +26,9 @@
struct gs_exports {
const char *(*device_get_name)(void);
int (*device_get_type)(void);
bool (*device_enum_adapters)(
bool (*callback)(void*, const char*, uint32_t),
void*);
const char *(*device_preprocessor_name)(void);
int (*device_create)(gs_device_t **device,
const struct gs_init_data *data);

View File

@ -36,6 +36,24 @@ static __thread graphics_t *thread_graphics = NULL;
#define IMMEDIATE_COUNT 512
void gs_enum_adapters(
bool (*callback)(void *param, const char *name, uint32_t id),
void *param)
{
graphics_t *graphics = thread_graphics;
if (graphics && graphics->exports.device_enum_adapters) {
if (graphics->exports.device_enum_adapters(callback, param)) {
return;
}
}
/* If the subsystem does not currently support device enumeration of
* adapters or fails to enumerate adapters, just set it to one adapter
* named "Default" */
callback(param, "Default", 0);
}
extern void gs_init_image_deps(void);
extern void gs_free_image_deps(void);

View File

@ -447,6 +447,9 @@ struct gs_init_data {
EXPORT const char *gs_get_device_name(void);
EXPORT int gs_get_device_type(void);
EXPORT void gs_enum_adapters(
bool (*callback)(void *param, const char *name, uint32_t id),
void *param);
EXPORT int gs_create(graphics_t **graphics, const char *module,
const struct gs_init_data *data);