Deferred renderer issue on AMD only

Based on this tutorial,
I had allot of problems getting AMD based GPU’s to work.

I will post snippets of code bellow to detail the issue, but a simplistic explanation of the issue is that there is an issue with the depth test. I can see background objects tear infront of closer objects etc.

I contacted the original author regarding the issue, he does not seem to have access to AMD hardware so the question is open to be resolved, and I hope someone here have had similar issues.

The tutorial are covered in 3 stages, basic deferred shading to the final example using stencil buffer to draw a sphere (for point lights) to make GLSL only process the light volume.

Code can be downloaded from the tutorial, but to make it convenient I will post the important areas (and order of execution) here.

Edit:
There are a few additions in the code samples bellow, as compared to the original tutorial, but the same issues are confirmed on AMD gpu’s in its original state by multiple systems (6k/7k series).

Static types:

	enum GBUFFER_TEXTURE_TYPE {
		GBUFFER_TEXTURE_TYPE_POSITION,
		GBUFFER_TEXTURE_TYPE_NORMAL,
		GBUFFER_TEXTURE_TYPE_TANGENT,
		GBUFFER_TEXTURE_TYPE_DIFFUSE_COLOR,
		GBUFFER_TEXTURE_TYPE_NORMAL_COLOR,
		GBUFFER_TEXTURE_TYPE_SPECULAR_COLOR,
		GBUFFER_NUM_TEXTURES


		m_shaderLight.setUniform("PositionTex", GBUFFER_TEXTURE_TYPE_POSITION);
		m_shaderLight.setUniform("NormalTex", GBUFFER_TEXTURE_TYPE_NORMAL);
		m_shaderLight.setUniform("TangentTex", GBUFFER_TEXTURE_TYPE_TANGENT);
		m_shaderLight.setUniform("ColorDiffuseTex", GBUFFER_TEXTURE_TYPE_DIFFUSE_COLOR);
		m_shaderLight.setUniform("ColorNormalTex", GBUFFER_TEXTURE_TYPE_NORMAL_COLOR);
		m_shaderLight.setUniform("ColorSpecularTex", GBUFFER_TEXTURE_TYPE_SPECULAR_COLOR);


	};

InitFBO


	if (m_fbo != 0) {
		glDeleteFramebuffers(1, &m_fbo);
	}

	if (m_depthTexture != 0) {
		glDeleteTextures(1, &m_depthTexture);
	}
	if (m_finalTexture != 0) {
		glDeleteTextures(1, &m_finalTexture);
	}

	for (size_t i = 0; i < ArraySize(m_textures); i++) {
		if (m_textures[i] != 0) {
			glDeleteTextures(1, &m_textures[i]);
		}
	}

	// Create the FBO
	glGenFramebuffers(1, &m_fbo);    
	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo);

	// Create the gbuffer textures
	glGenTextures(ArraySize(m_textures), m_textures);

	glGenTextures(1, &m_depthTexture);

	glGenTextures(1, &m_finalTexture);

	for (unsigned int i = 0 ; i < ArraySize(m_textures) ; i++) {
		glBindTexture(GL_TEXTURE_2D, m_textures[i]);
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, m_windowWidth, m_windowHeight, 0, GL_RGBA, GL_FLOAT, NULL);
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, m_textures[i], 0);
	}

	// depth
	glBindTexture(GL_TEXTURE_2D, m_depthTexture);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH32F_STENCIL8, m_windowWidth, m_windowHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
	glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_depthTexture, 0);

	// final
	glBindTexture(GL_TEXTURE_2D, m_finalTexture);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_windowWidth, m_windowHeight, 0, GL_RGB, GL_FLOAT, NULL);
	glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT6, GL_TEXTURE_2D, m_finalTexture, 0);	

	GLenum Status = glCheckFramebufferStatus(GL_FRAMEBUFFER);

	if (Status != GL_FRAMEBUFFER_COMPLETE) {
		printf("FB error, status: 0x%x
", Status);
		return false;
	}

Pass Geometry:

	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo);
	glDrawBuffer(GL_COLOR_ATTACHMENT6);
	glClear(GL_COLOR_BUFFER_BIT);


	glViewport(0, 0, m_windowWidth, m_windowHeight);

	static GLenum DrawBuffers[] = { GL_COLOR_ATTACHMENT0, 
									GL_COLOR_ATTACHMENT1,
									GL_COLOR_ATTACHMENT2,
									GL_COLOR_ATTACHMENT3,
									GL_COLOR_ATTACHMENT4,
									GL_COLOR_ATTACHMENT5};

	glDrawBuffers(ArraySize(DrawBuffers), DrawBuffers);

	// Only the geometry pass updates the depth buffer
	glDepthMask(GL_TRUE);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glEnable(GL_DEPTH_TEST);

        draw geometry here...

        glDepthMask(GL_FALSE);	

Pass Light: (Will only demonstrate directional light, stencil done in point light)


		glDrawBuffer(GL_COLOR_ATTACHMENT6);
		
		for (unsigned int i = 0 ; i < ArraySize(m_textures); i++) {
			glActiveTexture(GL_TEXTURE0 + i);		
			glBindTexture(GL_TEXTURE_2D, m_textures[GBUFFER_TEXTURE_TYPE_POSITION + i]);
		}
 
		glUniformSubroutinesuiv( GL_FRAGMENT_SHADER, 1, &GLSLSubFSLightDirectional);

		glDisable(GL_DEPTH_TEST);
		glEnable(GL_BLEND);
		glBlendEquation(GL_FUNC_ADD);
		glBlendFunc(GL_ONE, GL_ONE);

		m_shaderLight.setUniform(UniformLightMVP, mat4(1));
		// Render the quad
		glBindVertexArray(m_quad);
		glDrawArrays(GL_TRIANGLES, 0, 6);  

		glDisable(GL_BLEND);

Then finally…

	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_effectFBO);
	glBindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo);
	glReadBuffer(GL_COLOR_ATTACHMENT6);

	glBlitFramebuffer(0, 0, m_windowWidth, m_windowHeight, 
		0, 0, m_windowWidth, m_windowHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);

Results:

Nvidia good

[ATTACH=CONFIG]522[/ATTACH]

AMD

Models disappears or blend into each other depending on camera angle

[ATTACH=CONFIG]521[/ATTACH]

Any feedback is greatly appreciated, if we find an answer I will credit whomever and let the author update the article so everyone can benefit from it.

Thanks.

I have a few AMD cards but not on a Linux system unfortunately. Have you tried rendering the depth buffer to the screen to see if it is valid and correct?

Try GL_DEPTH24_STENCIL8 instead of GL_DEPTH32F_STENCIL8.

No change :frowning:

Good point, added some debug overlay (from gbuffer), cant see it in the depth, normal, tangent textures either. So it happens in the geometry pass. Narrows it down a bit.

I solved this issue, not sure how to edit the original title (seems to be locked for edit after some period)

Will incorporate the fix in original tutorial, if the fix is working well for everyone. Will need some time to determine the exact issue as I had to rewrite how I set up the color attachments to the FBO, partially based on “OpenGL 4.0 Shading Language” book.