Trying to use INTEL_performance_query
extension of OpenGL to get general metrics of the GPU usage. The problem is that for most operations, including listing extensions, it is needed a context
which requires X-server, and some Display
.
Unfortunately, I don't have any of them. (Pure SSH access to a server). However, I know an Intel real graphic card is installed and configured.
main.cpp
#include <cassert>
#include <exception>
#include <iostream>
#include <unordered_set>
#include <GL/glew.h>
#include <GL/gl.h>
#include <GL/glx.h>
void uselessSetup()
{
using glXCreateContextAttribsARBProc = GLXContext (*)(Display*, GLXFBConfig, GLXContext, bool, const int*);
using glXMakeContextCurrentARBProc = bool (*)(Display*, GLXDrawable, GLXDrawable, GLXContext);
static glXCreateContextAttribsARBProc glXCreateContextAttribsARB = nullptr;
static glXMakeContextCurrentARBProc glXMakeContextCurrentARB = nullptr;
glXCreateContextAttribsARB = reinterpret_cast<glXCreateContextAttribsARBProc>(glXGetProcAddressARB( reinterpret_cast<const GLubyte *>("glXCreateContextAttribsARB")));
glXMakeContextCurrentARB = reinterpret_cast<glXMakeContextCurrentARBProc>(glXGetProcAddressARB( reinterpret_cast<const GLubyte *>("glXMakeContextCurrent")));
Display* display = XOpenDisplay( nullptr );
static int visualAttribs[] = { None };
int numberOfFramebufferConfigurations = 0;
GLXFBConfig* fbConfigs = glXChooseFBConfig( display, DefaultScreen(display), visualAttribs, &numberOfFramebufferConfigurations );
int context_attribs[] =
{
GLX_CONTEXT_MAJOR_VERSION_ARB, 4,
GLX_CONTEXT_MINOR_VERSION_ARB, 2,
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB,
GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
None
};
GLXContext openGLContext = glXCreateContextAttribsARB( nullptr, nullptr, 0, true, context_attribs);
int pbufferAttribs[] =
{
GLX_PBUFFER_WIDTH, 32,
GLX_PBUFFER_HEIGHT, 32,
None
};
GLXPbuffer pbuffer = glXCreatePbuffer( display, fbConfigs[0], pbufferAttribs );
// clean up:
XFree( fbConfigs );
XSync( display, false );
if ( !glXMakeContextCurrentARB( display, pbuffer, pbuffer, openGLContext ) )
{
std::string_view msg = "Error: could not create headless context.";
std::cerr << msg << std::endl;
assert(false);
throw std::runtime_error(msg.data());
}
GLenum err = glewInit();
if (GLEW_OK != err)
{
std::string msg = std::string{"Error: "} + reinterpret_cast<const char*>(glewGetErrorString(err));
std::cerr << msg << std::endl;
assert(false);
throw std::runtime_error(msg);
}
}
std::unordered_set<std::string> supportedExtensions()
{
std::unordered_set<std::string> ret;
GLint n=0;
glGetIntegerv(GL_NUM_EXTENSIONS, &n);
std::cout << "There are: " << n << " extensions" << std::endl;
for (GLint i=0; i<n; i++)
{
const std::string extension = reinterpret_cast<const char*>(glGetStringi(GL_EXTENSIONS, i));
ret.insert(extension);
}
return ret;
}
int main(int, char**)
{
// I CANT DO THIS!!!
//uselessSetup();
std::cout << "OpenGL version: " << reinterpret_cast<const char*>(glGetString(GL_VERSION)) << std::endl;
std::cout << "Vendor : " << reinterpret_cast<const char*>(glGetString(GL_VENDOR)) << std::endl;
std::cout << "Renderer : " << reinterpret_cast<const char*>(glGetString(GL_RENDERER)) << std::endl;
const auto extensions = supportedExtensions();
std::cout << "Supported extensions:" << std::endl;
for (const auto& ext: extensions)
{
std::cout << " " << ext << std::endl;
}
if ( extensions.find("INTEL_performance_query")!=extensions.cend())
{
std::cerr << "INTEL_performance_query not supported" << std::endl;
}
return 0;
}
CMake:
cmake_minimum_required(VERSION 3.13)
cmake_policy( SET CMP0076 NEW )
project("GPU_profiler")
set(TARGET "GPU_profiler")
add_executable(${TARGET})
target_compile_options( ${TARGET} PRIVATE -Wall -pedantic -Wno-padded)
target_compile_features( ${TARGET} PUBLIC cxx_std_17)
find_package(GLEW REQUIRED)
include_directories(${GLEW_INCLUDE_DIRS})
#Build this project
set ( SOURCES main.cpp)
set ( HEADERS "")
set ( LIBS
${GLEW_LIBRARIES}
GL
GLX
X11
)
target_sources( ${TARGET} PRIVATE ${SOURCES} PRIVATE ${HEADERS})
target_link_libraries(${TARGET} ${LIBS})
How can I get access to those graphic card values and extensions (which should not require a drawing context)?
Related:
Using OpenGL Without X-Window System Mesa driver is not a solution.
http://renderingpipeline.com/2012/05/windowless-opengl/ This works only when an X-server is available. It's actually the solution shown above as "uselessSetup"
OpenGL without X.org in linux I Could create a context, but out of the 2 available devices, the first returns "Not allowed to force software rendering when API explicitly selects a hardware device". While the second is a virtual mesa driver (without access to real OpenGL hardware).