Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 5 of 5

Thread: ARB_occlusion_query flickering when high FPS

  1. #1
    Intern Contributor
    Join Date
    Nov 2011
    Posts
    51

    ARB_occlusion_query flickering when high FPS

    I'm using OpenGL 3.30 with Shaders (with HW instancing) but I've got a flickering effect on whole scene when I'm trying to execute occlusion queries during high framerates (usually > 100). More pfs I get, then more flickers I get.
    With 60 or less fps I get no flickering effect.

    YouTube video: http://www.youtube.com/watch?v=i1alFoXrAqY

    Pseudo-Code:
    1. Enable off screen rendering to FrameBufferObject
    2. glColorMask(0,0,0,0)
    3. glDepthMask(0)
    4. for each object to render {
      1. Bind VertexBufferObject() to Shader
      2. glBeginQuery(GL_SAMPLES_PASSED)
      3. save QUERY_ID and OBJECT_ID for later use
      4. glDrawArraysInstanced(...)
      5. glEndQuery(GL_SAMPLES_PASSED)

    5. }
    6. while glGetQueryObjectuiv(GL_QUERY_RESULT_AVAILABLE) == 0 {...}
    7. verify if QUERY_ID is visible and set OBJECT_ID the same
    8. glDepthMask(1)
    9. glColorMask(1,1,1,1)
    10. Disable off screen rendering and return to default FrameBuffer
    11. normal Rendering Pass which renders only objects which had QUERY_ID passed as "visible"


    I know this is not the good way to "wait" (list point #6) Querie results, but I don't understand why rendering "off screen" (to a FrameBufferObject) starts to flickering in default Framebuffer....Even if I exchange list point #6 with a delay Sleep(500) I get no flickering effect, so the problem is not caused due to wait Query results.

    Any idea?

    PS: If i remove those piece of code (firsts 10 list points) I get no flickering
    PS2: left-bottom text is rendered outside rendering pass
    Last edited by tdname; 09-06-2013 at 11:51 AM.

  2. #2
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    3,224
    Quote Originally Posted by tdname View Post
    I'm using OpenGL 3.30 with Shaders (with HW instancing) but I've got a flickering effect on whole scene when I'm trying to execute occlusion queries during high framerates (usually > 100). More pfs I get, then more flickers I get.
    With 60 or less fps I get no flickering effect. ...

    6. while glGetQueryObjectuiv(GL_QUERY_RESULT_AVAILABLE) == 0 {...}

    ...I don't understand why rendering "off screen" (to a FrameBufferObject) starts to flickering in default Framebuffer....Even if I exchange list point #6 with a delay Sleep(500) I get no flickering effect, so the problem is not caused due to wait Query results.
    The latter statement does not follow.

    First, are you rendering with double buffering and sync-to-vblank (i.e. framelock) enabled? If not, stop there and fix that.

    Second, 60Hz is 16.66ms/frame. 100Hz is 10ms/frame. Put a glFinish after your SwapBuffers(), and time after this point on the last frame to this same point on the next frame. How long is it? Is it sometimes greater than your vsync frame rate (probably by a multiple)? If so, you're overrunning your frame time budget. You need to fix that. I'd guess that (if you're framelocked correctly) sometimes you're peeking over 10 ms/frame.

    And to the point of the efficiency of halting the GPU pipeline and fetching query results back to the CPU to use for conditionally submitting further GPU work, there are more efficient ways to accomplish this which don't involve CPU-GPU synchronization. For instance, look at conditional rendering. Or you can use transform feedback to serialize only objects that pass a frustum and course occlusion cull, and use that in the draw pass. Also look at the recently introduced ARB_query_buffer_object.

    And if for some reason you really, really want to keep the CPU get query approach in-place, be sure you're at least doing a glFlush() after submitting your last query before you do the get queries. If you don't your queries might just sit idle on the CPU side for a while in a to-GPU "send buffer" and thus not get promptly processed on the GPU.

    I don't completely understand why your default framebuffer is flickering. If you are clearing the color buffer, are single buffered (an error), are framelocked, and are overrunning your frametime budget (also an error), I could potentially see something like this happening.
    Last edited by Dark Photon; 09-06-2013 at 06:59 PM.

  3. #3
    Advanced Member Frequent Contributor
    Join Date
    Apr 2010
    Posts
    791
    Have you checked that the occlusion queries produce sensible results across multiple frames, i.e. they don't change from frame to frame without a change in camera or object position to explain that change?

    You disable depth writes while rendering for the occlusion queries, which seems odd to me since the only objects that should be classified as occluded under these circumstances are those outside the view frustum everything else will be visible: there is nothing to occlude it.

  4. #4
    Intern Contributor
    Join Date
    Nov 2011
    Posts
    51
    Quote Originally Posted by Dark Photon View Post
    are you rendering with double buffering and sync-to-vblank enabled? If not, stop there and fix that
    Double Buffering is active but VSync not due to test the framerate.
    I've implemented an option (with a checkbox) to enable or disable VSync before start my engine. I'm usual to disable it when I want to see if newest source code changes have improved or not the speed of rendering...and how much improved...
    If I enable VSync I get no any flickering effect.
    Sorry for this my lack in before explanation.

    Quote Originally Posted by Dark Photon View Post
    If so, you're overrunning your frame time budget
    I'll test your suggestion tomorrow (now I'm not at home), but I don't understand what you were meaning with those words I've quoted (english is not my main language, and I don't understand well the meaning of your phrase)...

    Quote Originally Posted by Dark Photon View Post
    sometimes you're peeking over 10 ms/frame
    Of course the milliseconds can reach 5ms when 200fps are reached.
    But it should not happen. If the milliseconds goes down, the Query time remains fixed. In my code I'm waiting Queries results with the loop at row #6 of previously pseudo-code, so the FrameTime should not fall below certain values which mainly depends on this loop at #6.
    Even if the whole rendering could take only 1ms, the loop at #6 increase this milliseconds until all Queries are done.
    Infact if I replace #6 with "Sleep(500)" I get very low framerate.
    With #6 if all Queries are not done the code remains in the loop, in other works the code remains in same frame waiting in the loop.......or not?

    Even with "glFinish()" between #5 and #6 (of pseudo-code) the flickering still present

    Quote Originally Posted by Dark Photon View Post
    Unfortunately I've already discarded conditional rendering because the CPU doesn't knows nothing about conditional rendering result, so I'm not able to set any source code's variable with occlusion result. I need this query result at CPU time to discard even its object's childs which could be INSIDE its boundaries. Example: please consider a box which physically contains small balls...if the box is occluded, I don't need to check occlusion (neither with conditional render) for each contained ball in it. To do this I need a variable filled with Occlusion Query result.
    Conditional rendering only tries to render the object, but can't instructs the CPU of its result.

    Quote Originally Posted by Dark Photon View Post
    recently introduced ARB_query_buffer_object
    Unfortunately my GPU is on a notebook and supports at least OpenGL 3.3....

    Quote Originally Posted by Dark Photon View Post
    If you are clearing the color buffer
    I clear the FrameBuffer on which I render on "off screen" to execute occlusion culling rendering, but not the default framebuffer on which I render at the end, this because all scene pixels are always renewed every frame (I'm using sky boxes/spheres), so I chose to discard that not useful function call.

    Quote Originally Posted by carsten neumann
    You disable depth writes while rendering for the occlusion queries
    I understand your doubt but all OcclusionQuery examples I've found online had this piece of code in it...
    Last edited by tdname; 09-08-2013 at 01:03 AM.

  5. #5
    Member Regular Contributor
    Join Date
    Jun 2013
    Posts
    498
    Quote Originally Posted by carsten neumann View Post
    You disable depth writes while rendering for the occlusion queries, which seems odd to me since the only objects that should be classified as occluded under these circumstances are those outside the view frustum everything else will be visible: there is nothing to occlude it.
    Disabling depth writes is fine if you're just trying to query whether a given object is occluded by whatever is already in the depth buffer. Moreover, if the mesh used for the occlusion query is just a bounding volume, or if you're skipping alpha tests (or some other aspect of the rendering process which affects which fragments are drawn), then disabling depth writes is necessary.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •