后续:异步屏幕外查询性能

Follow up: Asynchronous off-screen query performance

本文关键字:查询 性能 屏幕 异步 后续      更新时间:2023-10-16

我最近问了这个问题:

如何执行异步外部查询?

我听到的,但尚未确认,窗户上的渲染比渲染到Framebuffer更昂贵。首先,谁能对此发表评论?我可以绘制多个场景以比窗口更快地绘制框架吗?还有其他选项,例如pbuffers还是PBO?

我已经开始玩Framebuffers,但是我无法让查询工作。这是我到目前为止设置的一些伪造代码:

glfwWindowHint(GLFW_VISIBLE, GL_FALSE);
window = glfwCreateWindow(1, 1, "OpenGL", NULL, NULL);
glfwMakeContextCurrent(window);
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
glGenRenderbuffers(1, &rbo);
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, size, size);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo);
glEnable(GL_DEPTH_TEST);
glGenQueries(numberOfQueries, queries);
for (scene in scenesToRender)
{
    glClear(GL_DEPTH_BUFFER_BIT);

    glDepthFunc(GL_LESS);
    drawShadingObjects(scene);
    glBeginQuery(GL_SAMPLES_PASSED, queries[index]);
    glDepthFunc(GL_LEQUAL);
    drawShadedObject(scene);
    glEndQuery(GL_SAMPLES_PASSED);
}
collectQueryResults();
deleteBuffers();

到目前为止一切都运行,但是所有查询都返回" 0"。绘制到框架缓冲器时与绘制窗口缓冲区不同的绘制时是否有一些查询?

再次,我的两个问题是:

  1. 我可以绘制多个场景以比窗口更快地绘制框架吗?还有其他选项,例如pbuffers还是PBO?
  2. 在绘制到框架缓冲器时与绘制窗口缓冲区时不同的查询是否有一些?

尝试这样的东西:

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <vector>
using namespace std;
const unsigned int sz = 1024;
void drawScene( unsigned int multiplier )
{
    glViewport( 0, 0, sz, sz );
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glRotatef( (float)glfwGetTime() * 50.f * multiplier, 0.f, 0.f, 1.f);
    glBegin(GL_TRIANGLES);
    glColor3f(1.f, 0.f, 0.f);
    glVertex3f(-0.6f, -0.4f, 0.f);
    glColor3f(0.f, 1.f, 0.f);
    glVertex3f(0.6f, -0.4f, 0.f);
    glColor3f(0.f, 0.f, 1.f);
    glVertex3f(0.f, 0.6f, 0.f);
    glEnd();
}
bool available( const vector< GLuint >& queries )
{
    for( size_t i = 0; i < queries.size(); ++i )
    {
        GLuint available = 0;
        glGetQueryObjectuiv( queries[i], GL_QUERY_RESULT_AVAILABLE, &available );
        if( GL_FALSE == available )
            return false;
    }
    return true;
}
int main()
{
    glfwInit();
    GLFWwindow* window = glfwCreateWindow( 400, 400, "Simple example", NULL, NULL );
    glfwMakeContextCurrent( window );
    glewInit();
    if( !glewIsSupported( "GL_VERSION_2_1" ) )
        return -1;
    if( !glewIsSupported( "GL_EXT_framebuffer_object" ) )
        return -1;
    GLuint fbo = 0;
    glGenFramebuffersEXT( 1, &fbo );
    glBindFramebufferEXT( GL_DRAW_FRAMEBUFFER_EXT, fbo );
    GLuint rbo0 = 0;
    glGenRenderbuffersEXT( 1, &rbo0 );
    glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, rbo0 );
    glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_RGBA, sz, sz );
    glFramebufferRenderbufferEXT( GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, rbo0 );
    GLuint rbo1 = 0;
    glGenRenderbuffersEXT( 1, &rbo1 );
    glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, rbo1 );
    glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, sz, sz );
    glFramebufferRenderbufferEXT( GL_DRAW_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rbo1 );
    GLenum status = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
    if( status != GL_FRAMEBUFFER_COMPLETE_EXT )
        return -1;
    glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
    vector< GLuint > queries( 10 );
    glGenQueries( queries.size(), &queries[0] );
    glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fbo );
    for( size_t i  = 0; i < queries.size(); ++i )
    {
        glBeginQuery( GL_SAMPLES_PASSED, queries[i] );
        drawScene( i + 1 );
        glEndQuery( GL_SAMPLES_PASSED );
    }
    glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
    // wait for queries to become available
    unsigned int cnt = 0;
    while( !available( queries ) )
    {
        cnt++;
    }
    // all queries available, display query results
    cout << "cnt: " << cnt << endl;
    for( size_t i = 0; i < queries.size(); ++i )
    {
        GLuint samples = 0;
        glGetQueryObjectuiv( queries[i], GL_QUERY_RESULT, &samples );
        cout << i << ": " << samples << endl;
    }
    cout << endl;
    glfwDestroyWindow( window );
    glfwTerminate();
    return 0;
}

我系统上的代表输出:

cnt: 1884
0: 157288
1: 157288
2: 157289
3: 157288
4: 157287
5: 157286
6: 157292
7: 157286
8: 157289
9: 157288