FBO & mipmapped fp16 cube maps

Out of curiosity, does anyone know if NVIDIA’s latest graphics driver for Linux (1.0-7676) is supposed to support mipmapping of fp16 cube maps for FBOs? It seems to work well for RGB8, but appears to fail for RGB16F. I’d be grateful for any info on the subject.

Hi fahlen,

It depends on what kind of hardware you
have. The GeForce 6 and 7 series both have
support for mipmapped fp16 cube maps, but no
hardware previous to that does.

What kind of hardware are you using?

Thanks -
Cass

Hi Cass,

Thanks for your reply. I have a GeForce 6800 GT and so it can’t be a hardware issue. As I was doing cut & paste of the code below, I noticed that the following old line of code hadn’t been removed. That’s why the RGB8 format worked fine.

 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_GENERATE_MIPMAP, GL_TRUE); 

It’s probably a coding error on my part. I’ve tried exchanging the RGB16F format for RGBA16F, but that didn’t work (think I read somewhere only fp16x2 and fp16x4 are supported). Perhaps I don’t use glGenerateMipmapEXT correctly.

GLuint createCubeMap(const Vector3& center, unsigned int size)
{
	GLfloat dirUpVecs[6][6] = {
		{  1.0,  0.0,  0.0, 0.0, -1.0,  0.0 }, 
		{ -1.0,  0.0,  0.0, 0.0, -1.0,  0.0 },
		{  0.0,  1.0,  0.0, 0.0,  0.0,  1.0 },
		{  0.0, -1.0,  0.0, 0.0,  0.0, -1.0 },
		{  0.0,  0.0,  1.0, 0.0, -1.0,  0.0 },
		{  0.0,  0.0, -1.0, 0.0, -1.0,  0.0 }
	};
	
	GLuint cubeMap, rb, fb;
	
	// Initialize color cube texture -----------------------------------
	glGenTextures(1, &cubeMap);
	glBindTexture(GL_TEXTURE_CUBE_MAP, cubeMap);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_GENERATE_MIPMAP, GL_TRUE);
	
	glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA16F_ARB, size, size, 0, GL_RGBA, GL_HALF_FLOAT_ARB, NULL);
	glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA16F_ARB, size, size, 0, GL_RGBA, GL_HALF_FLOAT_ARB, NULL);
	glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA16F_ARB, size, size, 0, GL_RGBA, GL_HALF_FLOAT_ARB, NULL);
	glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA16F_ARB, size, size, 0, GL_RGBA, GL_HALF_FLOAT_ARB, NULL);
	glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA16F_ARB, size, size, 0, GL_RGBA, GL_HALF_FLOAT_ARB, NULL);
	glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA16F_ARB, size, size, 0, GL_RGBA, GL_HALF_FLOAT_ARB, NULL);
	glGenerateMipmapEXT(GL_TEXTURE_CUBE_MAP);

	// Initialize depth renderbuffer -----------------------------------
	glGenRenderbuffersEXT(1, &rb);
	glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb);
	glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, size, size);

	// Assemble framebuffer object -------------------------------------
	glGenFramebuffersEXT(1, &fb);
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
							  GL_TEXTURE_CUBE_MAP_POSITIVE_X, cubeMap, 0);
	glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
								 GL_RENDERBUFFER_EXT, rb);
								 
	if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT)
		cout << "Framebuffer object not complete..." << endl;

	int viewport[4];
	glGetIntegerv(GL_VIEWPORT, viewport);
	glViewport(0, 0, size, size);				// Set viewport dimensions equal those of texture

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(90.0, 1.0, zNear, zFar);			// 90º fovy, 1.0 aspect ratio
	glMatrixMode(GL_MODELVIEW);
	
	// Generate maps for all 6 sides
	for (int i = 0; i < 6; ++i)
	{
		glLoadIdentity();
		gluLookAt(center.x, center.y, center.z,
				  dirUpVecs[i][0], dirUpVecs[i][1], dirUpVecs[i][2],
				  dirUpVecs[i][3], dirUpVecs[i][4], dirUpVecs[i][5]);

		glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
								  GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, cubeMap, 0);
		draw();
	}
	
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);		// Render to framebuffer
	glGenerateMipmapEXT(GL_TEXTURE_CUBE_MAP);		// Create mipmap chain

	reshape(viewport[2], viewport[3]);			// Restore viewport and projection matrix
	return cubeMap;
}

You’d make my day if you could point me to what I’m doing wrong :slight_smile: Thanks again!

/Markus

I wonder if this is a bug with automatic mipmap generation? Have you tried loading the mipmap
chain by hand?

Also, what driver version are you using?

Thanks -
Cass

I’m using driver version 1.0-7676. As for loading the mipmap chain by hand, I will give it a try as soon as I get home today, and I’ll let you know.

You seem to be right about the automatic mipmap generation. By loading the mipmap chain by hand I get a complete framebuffer object. If this indeed is a driver bug, do you know if there’s a new driver release planned any time soon?

Thanks,
Markus

Checking…

Hi fahlen, can you get me a simple repro app?
(email is fine)