engine: add a method to retrieve all available GPUs (only for Vulkan), add r_refdll_loaded cvar to indicate current loaded renderer

This commit is contained in:
Alibek Omarov 2021-12-10 03:42:38 +03:00 committed by Ivan Avdeev
parent 84b358b096
commit 350ab21209
8 changed files with 111 additions and 10 deletions

View File

@ -20,6 +20,7 @@ GNU General Public License for more details.
#include "input.h"
#include "server.h" // !!svgame.hInstance
#include "vid_common.h"
#include "ref_common.h"
static void UI_UpdateUserinfo( void );
@ -1118,6 +1119,7 @@ static char *pfnParseFile( char *buf, char *token )
return COM_ParseFile( buf, token, INT_MAX );
}
// engine callbacks
static ui_enginefuncs_t gEngfuncs =
{
@ -1233,7 +1235,8 @@ static ui_extendedfuncs_t gExtendedfuncs =
Con_UtfMoveRight,
pfnGetRenderers,
Sys_DoubleTime,
_COM_ParseFileSafe
_COM_ParseFileSafe,
R_GetRenderDevice
};
void UI_UnloadProgs( void )

View File

@ -16,6 +16,7 @@ convar_t *r_showtree;
convar_t *gl_msaa_samples;
convar_t *gl_clear;
convar_t *r_refdll;
convar_t *r_refdll_loaded;
void R_GetTextureParms( int *w, int *h, int texnum )
{
@ -551,6 +552,7 @@ static qboolean R_LoadRenderer( const char *refopt )
return false;
}
Cvar_FullSet( "r_refdll_loaded", refopt, FCVAR_READ_ONLY );
Con_Reportf( "Renderer %s initialized\n", refdll );
return true;
@ -637,6 +639,65 @@ void R_CollectRendererNames( void )
ref.numRenderers = cur;
}
const ref_device_t *R_GetRenderDevice( unsigned int idx )
{
if( !Q_stricmp( r_refdll_loaded->string, "vk" ))
{
if( !ref.dllFuncs.pfnGetVulkanRenderDevice )
return NULL;
return ref.dllFuncs.pfnGetVulkanRenderDevice( idx );
}
// TODO: implement?
return NULL;
}
static const char *R_DeviceTypeToString( ref_device_type_t type )
{
switch( type )
{
case REF_DEVICE_TYPE_DISCRETE_GPU:
return "^2Discrete^7";
case REF_DEVICE_TYPE_INTERGRATED_GPU:
return "^3Integrated^7";
case REF_DEVICE_TYPE_VIRTUAL_GPU:
return "^4Virtual^7";
case REF_DEVICE_TYPE_CPU:
return "^5Software^7";
}
return "^6Unknown^7";
}
static void R_GetRenderDevices_f( void )
{
int i = 0;
const ref_device_t *device = NULL;
if( Q_stricmp( r_refdll_loaded->string, "vk" ) ||
!ref.dllFuncs.pfnGetVulkanRenderDevice )
{
Con_Printf( "Renderer %s doesn't implement this!\n", r_refdll_loaded->string );
return;
}
Con_Printf( "Num ID Type Name\n" );
Con_Printf( "------------------------------------------------\n" );
for( i = 0;; i++ )
{
device = R_GetRenderDevice( i );
if( !device )
break;
Con_Printf( "%-3i %-4x:%-4x %-10s %s\n",
i, device->deviceID, device->vendorID,
R_DeviceTypeToString( device->deviceType ), device->deviceName );
}
}
qboolean R_Init( void )
{
qboolean success = false;
@ -650,6 +711,7 @@ qboolean R_Init( void )
gl_clear = Cvar_Get( "gl_clear", "0", FCVAR_ARCHIVE, "clearing screen after each frame" );
r_showtree = Cvar_Get( "r_showtree", "0", FCVAR_ARCHIVE, "build the graph of visible BSP tree" );
r_refdll = Cvar_Get( "r_refdll", "", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "choose renderer implementation, if supported" );
r_refdll_loaded = Cvar_Get( "r_refdll_loaded", "", FCVAR_READ_ONLY, "currently loaded renderer" );
// cvars that are expected to exist
Cvar_Get( "r_speeds", "0", FCVAR_ARCHIVE, "shows renderer speeds" );
@ -673,6 +735,8 @@ qboolean R_Init( void )
Cvar_Get( "r_drawentities", "1", FCVAR_CHEAT, "render entities" );
Cvar_Get( "cl_himodels", "1", FCVAR_ARCHIVE, "draw high-resolution player models in multiplayer" );
Cmd_AddCommand( "r_show_devices", R_GetRenderDevices_f, "print all available GPUs in the system" );
// cvars are created, execute video config
Cbuf_AddText( "exec video.cfg" );
Cbuf_Execute();

View File

@ -52,6 +52,7 @@ extern convar_t *gl_clear;
qboolean R_Init( void );
void R_Shutdown( void );
void R_UpdateRefState( void );
const ref_device_t *R_GetRenderDevice( unsigned int idx );
extern triangleapi_t gTriApi;

View File

@ -28,6 +28,7 @@ GNU General Public License for more details.
#include "r_efx.h"
#include "com_image.h"
#include "ref_vulkan.h"
#include "ref_device.h"
#define REF_API_VERSION 1
@ -621,6 +622,9 @@ typedef struct ref_interface_s
void (*VGUI_DrawQuad)( const vpoint_t *ul, const vpoint_t *lr );
void (*VGUI_GetTextureSizes)( int *width, int *height );
int (*VGUI_GenerateTexture)( void );
// only Vulkan manages devices in renderer code
const ref_device_t *(*pfnGetVulkanRenderDevice)( unsigned int idx );
} ref_interface_t;
typedef int (*REFAPI)( int version, ref_interface_t *pFunctionTable, ref_api_t* engfuncs, ref_globals_t *pGlobals );

View File

@ -317,13 +317,15 @@ static int enumerateDevices( vk_available_device_t **available_devices ) {
VkPhysicalDevice *physical_devices = NULL;
uint32_t num_physical_devices = 0;
vk_available_device_t *this_device = NULL;
string device_current;
XVK_CHECK(vkEnumeratePhysicalDevices(vk_core.instance, &num_physical_devices, physical_devices));
physical_devices = Mem_Malloc(vk_core.pool, sizeof(VkPhysicalDevice) * num_physical_devices);
XVK_CHECK(vkEnumeratePhysicalDevices(vk_core.instance, &num_physical_devices, physical_devices));
gEngine.Con_Reportf("Have %u devices:\n", num_physical_devices);
vk_core.num_devices = num_physical_devices;
vk_core.devices = Mem_Calloc( vk_core.pool, num_physical_devices * sizeof( *vk_core.devices ));
*available_devices = Mem_Malloc(vk_core.pool, num_physical_devices * sizeof(vk_available_device_t));
this_device = *available_devices;
for (uint32_t i = 0; i < num_physical_devices; ++i) {
@ -335,12 +337,28 @@ static int enumerateDevices( vk_available_device_t **available_devices ) {
vkGetPhysicalDeviceProperties(physical_devices[i], &props);
// Store devices list in vk_core.device_list for vk_device_list
Q_snprintf( device_current, sizeof(device_current), "\n%04x:%04x - %s", props.vendorID, props.deviceID, props.deviceName );
Q_strncat( vk_core.device_list, device_current, MAX_STRING );
if (i == num_physical_devices-1) {
Q_strncat( vk_core.device_list, "\n", MAX_STRING );
// Store devices list in vk_core.devices for pfnGetRenderDevices
vk_core.devices[i].vendorID = props.vendorID;
vk_core.devices[i].deviceID = props.deviceID;
switch( props.deviceType )
{
case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
vk_core.devices[i].deviceType = REF_DEVICE_TYPE_INTERGRATED_GPU;
break;
case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
vk_core.devices[i].deviceType = REF_DEVICE_TYPE_DISCRETE_GPU;
break;
case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU:
vk_core.devices[i].deviceType = REF_DEVICE_TYPE_VIRTUAL_GPU;
break;
case VK_PHYSICAL_DEVICE_TYPE_CPU:
vk_core.devices[i].deviceType = REF_DEVICE_TYPE_CPU;
break;
default:
vk_core.devices[i].deviceType = REF_DEVICE_TYPE_OTHER;
break;
}
Q_strncpy( vk_core.devices[i].deviceName, props.deviceName, sizeof( vk_core.devices[i].deviceName ));
gEngine.Con_Printf("\t%u: %04x:%04x %d %s %u.%u.%u %u.%u.%u\n",
i, props.vendorID, props.deviceID, props.deviceType, props.deviceName,

View File

@ -67,7 +67,6 @@ typedef struct vulkan_core_s {
physical_device_t physical_device;
VkDevice device;
string device_list;
VkQueue queue;
VkCommandPool command_pool;
@ -77,6 +76,9 @@ typedef struct vulkan_core_s {
vk_buffer_t staging;
VkSampler default_sampler;
unsigned int num_devices;
ref_device_t *devices;
} vulkan_core_t;
extern vulkan_core_t vk_core;

View File

@ -29,5 +29,4 @@ void VK_LoadCvarsAfterInit( void )
} else {
vk_rtx = gEngine.Cvar_Get( "vk_rtx", "0", FCVAR_READ_ONLY, "DISABLED: not supported by your hardware/software" );
}
vk_device_list = gEngine.Cvar_Get( "vk_device_list", vk_core.device_list, FCVAR_READ_ONLY, "List video devices" );
}
}

View File

@ -484,6 +484,14 @@ static int VGUI_GenerateTexture( void )
return 0;
}
static const ref_device_t *pfnGetRenderDevice( unsigned int idx )
{
if( idx >= vk_core.num_devices )
return NULL;
return &vk_core.devices[idx];
}
ref_interface_t gReffuncs =
{
.R_Init = R_VkInit,
@ -630,6 +638,8 @@ ref_interface_t gReffuncs =
VGUI_DrawQuad,
VGUI_GetTextureSizes,
VGUI_GenerateTexture,
pfnGetRenderDevice,
};
int EXPORT GetRefAPI( int version, ref_interface_t *funcs, ref_api_t *engfuncs, ref_globals_t *globals )