尝试使用INTEL_performance_queryOpenGL 的扩展来获取 GPU 使用情况的一般指标。问题是对于大多数操作,包括列出扩展,它需要一个context需要 X-server 和一些Display.
不幸的是,我一个都没有。(对服务器的纯 SSH 访问)。但是,我知道安装和配置了英特尔真正的显卡。
主文件
#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_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})
我如何才能访问这些显卡值和扩展名(不需要绘图上下文)?
有关的:
在没有 X-Window 系统 Mesa 驱动程序的情况下使用 OpenGL 不是解决方案。
http://renderingpipeline.com/2012/05/windowless-opengl/ 这仅在 X 服务器可用时有效。它实际上是上面显示为“uselessSetup”的解决方案
在 linux 中没有 X.org 的 OpenGL 我可以创建一个上下文,但在 2 个可用设备中,第一个返回“当 API 显式选择硬件设备时不允许强制软件渲染”。而第二个是虚拟台面驱动程序(无需访问真正的 OpenGL 硬件)。