Files
renderdoc/renderdoc/driver/ihv/amd/official/RGP/DevDriverAPI/ADLGetDriverVersion.cpp
T
2018-05-25 08:33:12 +01:00

261 lines
9.1 KiB
C++

//=============================================================================
/// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
/// \author AMD Developer Tools Team
/// \file
/// \brief Retrieve driver version information for AMD Radeon Drivers on Windows using ADL
//=============================================================================
// To compile from the windows CMD prompt into a standalone command-line executable for test
// - use the following commands with Visual Studio 2017
//
// > "c:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\vsvars32.bat"
// > cl ADLGetDriverVersion.cpp -I <path to adl_sdk.h> -D COMMAND_LINE_TEST /EHsc
#ifdef _WIN32
#include <windows.h>
#include <sstream>
#include "adl_sdk.h"
#include "ADLGetDriverVersion.h"
// Definitions of the used ADL function pointers.
typedef int(*ADL2_MAIN_CONTROL_CREATE)(ADL_MAIN_MALLOC_CALLBACK, int, ADL_CONTEXT_HANDLE*);
typedef int(*ADL2_MAIN_CONTROL_DESTROY)(ADL_CONTEXT_HANDLE);
typedef int(*ADL2_GRAPHICS_VERSION_GET)(ADL_CONTEXT_HANDLE context, ADLVersionsInfo * lpVersionsInfo);
// Memory allocation function for use with ADL
static void* __stdcall ADL_Main_Memory_Alloc(int iSize)
{
void* lpBuffer = malloc(iSize);
return lpBuffer;
}
//-----------------------------------------------------------------------------
/// Parse version string returned by the driver via ADL to extract version info
/// \param versionString The string returned from the driver via ADL
/// \param major The major version number
/// \param minor The minor version number
/// \param subminor The subminor version number
/// \return true if successful, or false on error
/// NOTE: This function always returns true since it is assumed that all AMD
/// drivers, including internal/mainline/staging builds with version numbers
/// that are not properly set up are valid.
//-----------------------------------------------------------------------------
static bool parseDriverVersionString(char *versionString, unsigned int &major, unsigned int &minor, unsigned int &subminor)
{
static const unsigned int s_DEFAULT_VERSION_NUMBER = 9999;
// set version number to a known value to handle AMD drivers with differing version numbers. Custom drivers may
// not have a major version but they still need to pass this test
major = minor = subminor = s_DEFAULT_VERSION_NUMBER;
std::string strDriverVersion(versionString);
#ifdef COMMAND_LINE_TEST
printf("\nVersion string from driver: %s\n", versionString);
#endif
// driver version looks like: 13.35.1005-140131a-167669E-ATI or 14.10-140115n-021649E-ATI, etc...
// truncate at the first dash
strDriverVersion = strDriverVersion.substr(0, strDriverVersion.find("-", 0));
size_t pos = 0;
std::string strToken;
std::string strDelimiter = ".";
std::stringstream ss;
// parse the major driver version (start of string to first ".")
pos = strDriverVersion.find(strDelimiter);
if (pos == std::string::npos)
{
// delimiter not found, so could be a custom driver
return true;
}
strToken = strDriverVersion.substr(0, pos);
ss.str(strToken);
if ((ss >> major).fail())
{
major = s_DEFAULT_VERSION_NUMBER;
return true;
}
strDriverVersion.erase(0, pos + strDelimiter.length()); // Delete section of string already parsed
// parse the minor driver version
bool subminorAvailable = false;
pos = strDriverVersion.find(strDelimiter);
if (pos != std::string::npos)
{
// Delimiter found
strToken = strDriverVersion.substr(0, pos);
strDriverVersion.erase(0, pos + strDelimiter.length());
subminorAvailable = true;
}
else
{
// No delimeter - use entire string
strToken = strDriverVersion;
}
ss.clear();
ss.str(strToken);
if ((ss >> minor).fail())
{
major = s_DEFAULT_VERSION_NUMBER;
minor = s_DEFAULT_VERSION_NUMBER;
return true;
}
// parse the sub-minor driver version
if (subminorAvailable)
{
pos = strDriverVersion.find(strDelimiter);
if (pos != std::string::npos)
{
// Delimiter found
strToken = strDriverVersion.substr(0, pos);
}
else
{
strToken = strDriverVersion;
}
ss.clear();
ss.str(strToken);
if ((ss >> subminor).fail())
{
major = s_DEFAULT_VERSION_NUMBER;
minor = s_DEFAULT_VERSION_NUMBER;
subminor = s_DEFAULT_VERSION_NUMBER;
return true;
}
}
return true;
}
//-----------------------------------------------------------------------------
/// Use ADL on Windows to retrieve the driver version number
/// \param majorVar The major version number
/// \param minorVer The minor version number
/// \param subminorVer The subminor version number
/// \return true if successful, or false on error
//-----------------------------------------------------------------------------
bool ADLGetDriverVersion(unsigned int& majorVer, unsigned int& minorVer, unsigned int& subminorVer)
{
bool retStatus = false;
HINSTANCE hDLL = LoadLibrary(TEXT("atiadlxx.dll"));
if (NULL == hDLL)
{
// A 32 bit calling application on 64 bit OS will fail to LoadLIbrary.
// Try to load the 32 bit library (atiadlxy.dll) instead
hDLL = LoadLibrary(TEXT("atiadlxy.dll"));
}
if (NULL != hDLL)
{
ADL2_MAIN_CONTROL_CREATE ADL2_Main_Control_Create = (ADL2_MAIN_CONTROL_CREATE)GetProcAddress(hDLL, "ADL2_Main_Control_Create");;
ADL2_MAIN_CONTROL_DESTROY ADL2_Main_Control_Destroy = (ADL2_MAIN_CONTROL_DESTROY)GetProcAddress(hDLL, "ADL2_Main_Control_Destroy");
ADL2_GRAPHICS_VERSION_GET ADL2_Graphics_Versions_Get = (ADL2_GRAPHICS_VERSION_GET)GetProcAddress(hDLL, "ADL2_Graphics_Versions_Get");
if (NULL != ADL2_Main_Control_Create &&
NULL != ADL2_Main_Control_Destroy &&
NULL != ADL2_Graphics_Versions_Get
)
{
ADL_CONTEXT_HANDLE adlContext = NULL;
if (ADL_OK == ADL2_Main_Control_Create(ADL_Main_Memory_Alloc, 1, &adlContext))
{
ADLVersionsInfo versionsInfo;
int ADLResult = ADL2_Graphics_Versions_Get(adlContext, &versionsInfo);
if (ADL_OK == ADLResult || ADL_OK_WARNING == ADLResult)
{
retStatus = parseDriverVersionString(versionsInfo.strDriverVer, majorVer, minorVer, subminorVer);
}
ADL2_Main_Control_Destroy(adlContext);
}
}
FreeLibrary(hDLL);
}
return retStatus;
}
//-----------------------------------------------------------------------------
/// Use ADL on Windows to retrieve the driver version string
/// \param outVersionName Pointer to s string to receive the version number.
/// Presetnly, the string should be at least ADL_MAX_PATH bytes long
/// \return true if successful, or false on error
//-----------------------------------------------------------------------------
bool ADLGetDriverVersionString(char* outVersionString)
{
bool retStatus = false;
HINSTANCE hDLL = LoadLibrary(TEXT("atiadlxx.dll"));
if (NULL == hDLL)
{
// A 32 bit calling application on 64 bit OS will fail to LoadLIbrary.
// Try to load the 32 bit library (atiadlxy.dll) instead
hDLL = LoadLibrary(TEXT("atiadlxy.dll"));
}
if (NULL != hDLL)
{
ADL2_MAIN_CONTROL_CREATE ADL2_Main_Control_Create = (ADL2_MAIN_CONTROL_CREATE)GetProcAddress(hDLL, "ADL2_Main_Control_Create");;
ADL2_MAIN_CONTROL_DESTROY ADL2_Main_Control_Destroy = (ADL2_MAIN_CONTROL_DESTROY)GetProcAddress(hDLL, "ADL2_Main_Control_Destroy");
ADL2_GRAPHICS_VERSION_GET ADL2_Graphics_Versions_Get = (ADL2_GRAPHICS_VERSION_GET)GetProcAddress(hDLL, "ADL2_Graphics_Versions_Get");
if (NULL != ADL2_Main_Control_Create &&
NULL != ADL2_Main_Control_Destroy &&
NULL != ADL2_Graphics_Versions_Get
)
{
ADL_CONTEXT_HANDLE adlContext = NULL;
if (ADL_OK == ADL2_Main_Control_Create(ADL_Main_Memory_Alloc, 1, &adlContext))
{
ADLVersionsInfo versionsInfo;
int ADLResult = ADL2_Graphics_Versions_Get(adlContext, &versionsInfo);
if (ADL_OK == ADLResult || ADL_OK_WARNING == ADLResult)
{
strcpy_s(outVersionString, ADL_MAX_PATH, versionsInfo.strDriverVer);
}
ADL2_Main_Control_Destroy(adlContext);
}
}
FreeLibrary(hDLL);
}
return retStatus;
}
#endif // _WIN32
#ifdef COMMAND_LINE_TEST
int main()
{
unsigned int major, minor, subminor;
if (ADLGetDriverVersion(major, minor, subminor) == true)
{
printf("\nDriver Major Version: %d", major);
printf("\nDriver Minor Version: %d", minor);
if (subminor != 0)
{
printf("\nDriver SubMinor Version: %d", subminor);
}
}
else
{
printf("\nUnable to retrieve driver version information");
}
printf("\n");
}
#endif