Rendering into layered textures

Hi,

I’ve been running into an issue with rendering into a layered texture (shadowmaps, to be precise). This post is about creating a 2D array texture and binding each layer individually through glNamedFramebufferTextureLayer. It is NOT about using a geometry shader to render into the layered texture.

The issue I’m running into is that rendering into each individual layer seems to be working fine, but every time I change the layer it seems like the contents of other layers get overwritten. I’m checking the contents through Nvidia’s Nsight.
So for example I have a texture with 3 layers. If I bind layer 0 and draw into it, then bind layer 1 and draw into it, layers 0 and 1 end up with the same content. If I bind layer 3 and draw into it then layers 0, 1 and 2 end up with the same content. What’s even weirder is that the moment I switch layers and issue a clear or draw, the previous layers will have the same content as what the current draw will eventually end up rendering (that result shouldn’t even exist at this point). This might just be an issue with how Nsight displays the texture but in the end it does seem like all layers contain the result of the last layer rendered to.
So I was wondering if there’s some switch or flag that I need to set or if there’s something wrong in the driver. This is on an nvidia card, drivers 358.87, running an OpenGL 4.5 context on Windows 7.

Here’s some example code that I’ve used for testing.
Other things I’ve tried:

  • Just have one texture for color instead of an array
  • Create texture views on each layer and bind using glNamedFramebufferTexture
  • Create three framebuffers and attach each layer individually
  • Clear the buffers one layer at a time instead of all of them at once

Nothing seems to fix the issue at hand, though. Any suggestions?


static const GLint s = 512;
GLuint depth_tex = 0, col_tex = 0;
glCreateTextures( GL_TEXTURE_2D_ARRAY, 1, &depth_tex );
glCreateTextures( GL_TEXTURE_2D_ARRAY, 1, &col_tex );
glTextureStorage3D( depth_tex, 1, GL_DEPTH_COMPONENT32F, s, s, 3 );
glTextureStorage3D( col_tex, 1, GL_RGBA8, s, s, 3 );

glBindFramebuffer( GL_DRAW_FRAMEBUFFER, 1 ); // you can assume "1" is valid here
glViewport( 0, 0, s, s );

glNamedFramebufferTexture( 1, GL_COLOR_ATTACHMENT0, col_tex, 0 );
glNamedFramebufferTexture( 1, GL_DEPTH_ATTACHMENT, depth_tex, 0 );
glClearColor( 0.7f, 0.3f, 0.3f, 0.f );
glClearDepthf( 1.f );
glDepthMask( GL_TRUE );
glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

glNamedFramebufferTextureLayer( 1, GL_COLOR_ATTACHMENT0, col_tex, 0, 0 );
glNamedFramebufferTextureLayer( 1, GL_DEPTH_ATTACHMENT, depth_tex, 0, 0 );
// draw something....
glTextureBarrier();

glNamedFramebufferTextureLayer( 1, GL_COLOR_ATTACHMENT0, col_tex, 0, 1 );
glNamedFramebufferTextureLayer( 1, GL_DEPTH_ATTACHMENT, depth_tex, 0, 1 );
// draw something....
glTextureBarrier();

glNamedFramebufferTextureLayer( 1, GL_COLOR_ATTACHMENT0, col_tex, 0, 2 );
glNamedFramebufferTextureLayer( 1, GL_DEPTH_ATTACHMENT, depth_tex, 0, 2 );
// draw something....
glTextureBarrier();