I am currently implementing occlusion queries with auxiliary FBO in the freeGlut based application, when I encountered a problem.

The tutorial of FBOs (https://www.opengl.org/wiki/Framebuf...in_framebuffer) says following:
Can you bind the main framebuffer's depth buffer as a depth buffer for your FBO? No. You must create a depth texture or a depth Render Buffer.
Does GL 3.0 allow using the main depth buffer? No.

How ever, when after occlusion queries, when I dump content of color and depth buffers, the result indicate the main and auxiliary depth buffers are some how shared :O

Main FBO: Click image for larger version. 

Name:	Screenshot from 2014-05-27 10:34:06.jpg 
Views:	295 
Size:	16.6 KB 
ID:	1319
Left image: color buffer, right image: 16 bit depth buffer as seen by a 8 bit viewer.

Auxiliary FBO: Click image for larger version. 

Name:	Screenshot from 2014-05-27 10:34:35.jpg 
Views:	255 
Size:	20.5 KB 
ID:	1320
Left image: color buffer, right image: 16 bit depth buffer as seen by a 8 bit viewer.

As seen from images above, the auxiliary FBO buffers has
a) aux FBO color buffer has either used main(?) depth buffer for depth test or the aux depth buffer is not cleared and content has copied from main FBO
b) aux FBO depth buffer has not been cleared before updating


have I done something wrong or have I hit by a driver bug??


The freeGlut and openGL initialization:
Code :
glutInitContextVersion( 3, 0 );
glutInitContextFlags( GLUT_DEBUG );
glutInitContextProfile( GLUT_CORE_PROFILE );
 
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL | GLUT_ACCUM );

The auxiliary FBO initialization (based on this - https://www.opengl.org/wiki/Framebuf...replacement.29):
Code :
s->exact_visibility->data.aux_framebuffer_id = 0;
glGenFramebuffers( 1, &s->exact_visibility->data.aux_framebuffer_id );
assert( s->exact_visibility->data.aux_framebuffer_id != 0 );
glBindFramebuffer( GL_FRAMEBUFFER, s->exact_visibility->data.aux_framebuffer_id );
 
#if defined(DEBUG_OCCLUSION_QUERY)
glGenRenderbuffers( 1, &s->exact_visibility->data.aux_colorbuffer_id );
glBindRenderbuffer( GL_RENDERBUFFER, s->exact_visibility->data.aux_colorbuffer_id );
glRenderbufferStorage( GL_RENDERBUFFER, GL_RGBA8, INITIAL_BUFFER_SIZE, INITIAL_BUFFER_SIZE );
glFramebufferRenderbuffer( GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, s->exact_visibility->data.aux_colorbuffer_id );
#endif
 
glGenRenderbuffers( 1, &s->exact_visibility->data.aux_depthbuffer_id );
glBindRenderbuffer( GL_RENDERBUFFER, s->exact_visibility->data.aux_depthbuffer_id );
#if defined(DEBUG_OCCLUSION_QUERY)
glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, INITIAL_BUFFER_SIZE, INITIAL_BUFFER_SIZE );
#else
glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT, INITIAL_BUFFER_SIZE, INITIAL_BUFFER_SIZE );
#endif
glFramebufferRenderbuffer( GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, s->exact_visibility->data.aux_depthbuffer_id );
 
 
GLenum const	status = glCheckFramebufferStatus( GL_DRAW_FRAMEBUFFER );
switch( status )
{
case GL_FRAMEBUFFER_COMPLETE:
break;
...


Occlusion query rendering:
Code :
glBindFramebuffer( GL_FRAMEBUFFER, s->exact_visibility->data.aux_framebuffer_id );
glViewport( 0, 0, INITIAL_BUFFER_SIZE, INITIAL_BUFFER_SIZE );
 
/* X+ */
static struct vector3 const		dir_Xp = { 1.0f, 0.0f, 0.0f };
static struct vector3 const		up_Y = { 0.0f, 1.0f, 0.0f };
render_exact_set_camera( s, spot, &dir_Xp, &up_Y );
if( render_exact_direction( s, visible_meshes, visible_dyns, mesh_cell, dyn_cell ) != res_ok )
{
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
return res_failed;
}
...
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
Function render_exact_direction():
Code :
#if defined(DEBUG_OCCLUSION_QUERY)
{
GLint	tmp1 = 0;
glGetIntegerv( GL_FRAMEBUFFER_BINDING, &tmp1 );
assert( tmp1 != 0 );
 
GLint	tmp2 = 0;
glGetFramebufferAttachmentParameteriv( GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &tmp2 );
assert( tmp2 != 0 );
 
GLint	tmp3 = 0;
glGetFramebufferAttachmentParameteriv( GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &tmp3 );
assert( tmp3 != 0 );
assert( tmp2 == tmp3 );
}
#endif
 
#if 0
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
glClear( GL_DEPTH_BUFFER_BIT );
glBindFramebuffer( GL_FRAMEBUFFER, s->exact_visibility->data.aux_framebuffer_id );
#endif
 
#if defined(DEBUG_OCCLUSION_QUERY)
glClearColor( 0.5f, 0.5f, 0.5f, 0.0f );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
#else
glClear( GL_DEPTH_BUFFER_BIT );
#endif
 
if( render_exact_hw_meshes( s, visible_meshes, mesh_cell ) != res_ok )
{
return res_failed;
}
...

And finally function exact_render_textured_mesh() called by function render_exact_hw_meshes()
Code :
...
#if defined(DEBUG_OCCLUSION_QUERY)
	{
		GLint	tmp1 = 0;
		glGetIntegerv( GL_FRAMEBUFFER_BINDING, &tmp1 );
		assert( tmp1 != 0 );
 
		GLint	tmp2 = 0;
		glGetFramebufferAttachmentParameteriv( GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &tmp2 );
		assert( tmp2 != 0 );
 
		GLint	tmp3 = 0;
		glGetFramebufferAttachmentParameteriv( GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &tmp3 );
		assert( tmp3 != 0 );
		assert( tmp2 == tmp3 );
	}
#endif
 
	render_draw_triangles( s, m->ntriangles, m->indices );

As seen from code samples, the auxiliary depth buffer IS cleared before rendering and to make thinks even nastier, if main depth buffer is cleared too, the result is different (it shouldn't affect the result). If the state menagement is to trust, it thinks that
a) auxiliary FBO is binded before rendering
b) a depth buffer is attached to FBO
and
c) the read and write depth buffers are the same


This effect is present in two desktops I have tested:
1) Ubuntu 14.04, nvidia-331-updates, GeForce GTX 550 Ti/PCIe/SSE2
and
2) Ubuntu 14.04, nvidia-331, Quadro FX 1800M/PCIe/SSE2

Any thoughts what could be wrong?