mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-07-17 21:17:09 +00:00
261 lines
9.1 KiB
C++
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
|