0

尝试使用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 硬件)。

4

0 回答 0