Looks like no one’s replied in a while. To start the conversation again, simply ask a new question.

GL Framebuffer Completeness & Blitting Issues

Hi,


I have the following piece of test code that I made after encountering a blitting issue on the application I was working on.

There are 3 issues that are illustrated by this test code:

1) glCheckFramebufferStatus gives reversed status on the read and draw buffer. If the buffers are incomplete, it returns 0x8CDB for READ and 0x8CDC for DRAW which is flipped according to the definition in the header file.


2) I am unable to make the FBO complete unless I attach a color attachment, even though I called glDrawBuffer(GL_NONE), glReadBuffer(GL_NONE), which according to my understanding, is supposed to do away with this requirement for completeness.


3) On my ATI Radeon HD 5770 Mac Pro, even if I use the dummy attachment, the blitting fails on a D24S8 but succeeds D32. "Fail" here means failing a source and destination comparison verification check. I have done this check using bytes, ints and floats and the results are consistent. When I tested this on my MacBook Pro with a Nvidia 560m, there were no errors for either D32 or D24S8.


Is there anyone out there who can shed some light on this?

Are these bugs or did I miss something obvious? I will like to do depth-buffer-only blitting without using a dummy attachment if possible.

If these are known issues, what is the recommended solution?



In this test code, I am trying to blit a depth-only FBO to another depth-only FBO. Depending on the parameters passed in, the test can be performed with D24S8 or D32, and with/without a dummy color attachment.

To ensure that OpenGL is initialized properly, the rest of the test application displays a colored rotating cube when run.

- (void) RunTest_DepthBufferBlit:(bool)isPackedStencil useDummyAttachment:(bool)useDummy

{

int err = glGetError(); //Clears out previous errors

NSLog(@"DepthBufferBlit %@ %@", isPackedStencil ? @"DepthStencil" : @"Depth", useDummy ? @"With Dummy Color Attachment" : @"");


/*

#define GL_FRAMEBUFFER_COMPLETE 0x8CD5

#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6

#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7

#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB

#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC

#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD

*/

int width = 256;

int height= 256;


// Generates 2 framebuffers, one as READ_FRAMEBUFFER and the other as DRAW_FRAMEBFFER.

GLuint framebuffers[2] = {0, 0};

glGenFramebuffers(2, framebuffers);

err = glGetError();

if (err != 0)

NSLog(@"DepthBufferBlit - Gen FBO Fail: %d", err);


GLuint texName[3] = { 0, 0, 0 };

// Create source, destination and dummy buffer

{

glGenTextures (3, texName);

err = glGetError();

if (err != 0)

NSLog(@"DepthBufferBlit - Gen Textures Fail: %d", err);

unsigned char* buffer = (unsigned char*)malloc(4 * width * height);

memset(buffer, 0, 4 * width * height);

float* depthBuffer = (float*)malloc(4 * width * height);

for (int i = 0; i < width*height; i++)

{

if (i%2 == 0)

depthBuffer[i] = 2.0f;

if (i%5 == 0)

depthBuffer[i] = 5.0f;

}


for (int i = 0; i < 3; i++)

{

glBindTexture (GL_TEXTURE_RECTANGLE, texName[i]);

err = glGetError();

if (err != 0)

NSLog(@"DepthBufferBlit - Bind Texture %d Fail: %d", texName[i], err);


glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_LINEAR);


GLint internalFormat = isPackedStencil ? GL_DEPTH_STENCIL : GL_DEPTH_COMPONENT32;

if (i == 0)

{

glTexImage2D(GL_TEXTURE_RECTANGLE, 0, internalFormat, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, depthBuffer);

}

else if (i == 2)

{

glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA , width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

}

else

{

glTexImage2D(GL_TEXTURE_RECTANGLE, 0, internalFormat, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, buffer);

}

err = glGetError();

if (err != 0)

NSLog(@"DepthBufferBlit - Create Texture %d Fail: %d", texName[i], err);

}

free(buffer);

free(depthBuffer);

}


GLint attachment = isPackedStencil ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT;


glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffers[0]);

if (useDummy)

glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE, texName[2], 0);

glFramebufferTexture2D(GL_READ_FRAMEBUFFER, attachment, GL_TEXTURE_RECTANGLE, texName[0], 0);


glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffers[1]);

if (useDummy)

glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE, texName[2], 0);

glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, GL_TEXTURE_RECTANGLE, texName[1], 0);


glReadBuffer(GL_NONE);

glDrawBuffer(GL_NONE);


err = glGetError();

if (err != 0)

NSLog(@"DepthBufferBlit - glFramebufferTexture2D: %d", err);


int dfbo = glCheckFramebufferStatus(GL_READ_FRAMEBUFFER); //Apple Bug: Flipped status

int rfbo = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); //Apple Bug: Flipped status


if (dfbo != GL_FRAMEBUFFER_COMPLETE || rfbo != GL_FRAMEBUFFER_COMPLETE)

{

NSLog(@"DepthBufferBlit FBO {%i,%i} Fail - Read = %x, Write = %x\n", width, height, rfbo, dfbo);


// Restore the framebuffer binding.

glBindFramebuffer(GL_FRAMEBUFFER, 0);


// Deletes the 2 framebuffers.

glDeleteFramebuffers(2, framebuffers);


// Deletes the 3 textures

glDeleteTextures(3, texName);

return;

}

if (isPackedStencil)

{

glBlitFramebuffer(0, 0, width, height,

0, 0, width, height, GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);

}

else {

glBlitFramebuffer(0, 0, width, height,

0, 0, width, height, GL_DEPTH_BUFFER_BIT, GL_NEAREST);

}


err = glGetError();

if (err != 0)

NSLog(@"DepthBufferBlit - Blitting: %d", err);


int errCount = 0;



// Check texture contents

// 256 x 256 = 65536

float tex[65536] = { 0 };

float tex2[65536] = { 0 };

glBindFramebuffer(GL_FRAMEBUFFER, framebuffers[0]);

glReadPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_FLOAT, tex);

glBindFramebuffer(GL_FRAMEBUFFER, framebuffers[1]);

glReadPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_FLOAT, tex2);


for (int i = 0; i < 65536; i++)

{

float val = abs(tex[i] - tex2[i]);

if (val > 0.000001)

errCount++;

}


if (errCount > 0)

NSLog(@"DepthBufferBlit - Differences = %d", errCount);

else {

NSLog(@"DepthBufferBlit %@ Completed Successfully.", isPackedStencil ? @"DepthStencil" : @"Depth");

}


// Restore the framebuffer binding.

glBindFramebuffer(GL_FRAMEBUFFER, 0);


// Deletes the 2 framebuffers.

glDeleteFramebuffers(2, framebuffers);


// Deletes the 3 textures

glDeleteTextures(3, texName);

return;

}



- (void) RunSingleShotTests

{

/* glBlitFrameBuffer */

[self RunTest_DepthBufferBlit:NO useDummyAttachment:NO];NSLog(@" ");

[self RunTest_DepthBufferBlit:NO useDummyAttachment:YES];NSLog(@" ");

[self RunTest_DepthBufferBlit:YES useDummyAttachment:NO];NSLog(@" ");

[self RunTest_DepthBufferBlit:YES useDummyAttachment:YES];

}



Results after running the above sample on 10.7.3 with both CoreProfile and LegacyProfile (with a few minor changes to make it GL 2.1 compatible):

2012-04-27 15:52:51.871 CocoaGLCoreProfile[56222:403] DepthBufferBlit Depth (D32)

2012-04-27 15:52:51.874 CocoaGLCoreProfile[56222:403] DepthBufferBlit FBO {256,256} Fail - Read = 8cdc, Write = 8cdb

2012-04-27 15:52:51.874 CocoaGLCoreProfile[56222:403]

2012-04-27 15:52:51.875 CocoaGLCoreProfile[56222:403] DepthBufferBlit Depth (D32) With Dummy Color Attachment

2012-04-27 15:52:51.886 CocoaGLCoreProfile[56222:403] DepthBufferBlit Depth Completed Successfully.

2012-04-27 15:52:51.887 CocoaGLCoreProfile[56222:403]

2012-04-27 15:52:51.887 CocoaGLCoreProfile[56222:403] DepthBufferBlit DepthStencil (D24S8)

2012-04-27 15:52:51.888 CocoaGLCoreProfile[56222:403] DepthBufferBlit FBO {256,256} Fail - Read = 8cdc, Write = 8cdb

2012-04-27 15:52:51.889 CocoaGLCoreProfile[56222:403]

2012-04-27 15:52:51.889 CocoaGLCoreProfile[56222:403] DepthBufferBlit DepthStencil (D24S8) With Dummy Color Attachment

2012-04-27 15:52:51.892 CocoaGLCoreProfile[56222:403] DepthBufferBlit - Differences = 9832



Thanks in advance.

Mac Pro, Mac OS X (10.7.3), ATI Radeon HD 5770

Posted on Apr 27, 2012 4:11 PM

Reply
2 replies

Jun 2, 2012 10:52 AM in response to Yu Jye

Hi Yu,


I don't think that you are missing something. I have got the same issue in my code, which
runs on MacOS and IOS. On iOS you DONT need a dummy attachement ( OpenGL ES 2.0)

whereas on OpenGL Core Profile 3.2 I got the situation you describe.


As I am also interessted in finding a solution please keep us posted if you find one, I will do
the same.


Greetings,


Gordon

Jun 3, 2012 9:10 AM in response to gba_go2b

Hi,


This was actually the wrong forum so I reposted this quesion and got my answer in the developer forums.

It turned out you have to call:


glDrawBuffer(GL_NONE)

glReadBuffer(GL_NONE)


on BOTH the source and destination buffers. i.e Both buffers have to be read and draw complete.

This was why I got a seemingly flipped status on the buffers when I checked them.


Cheers.

YJ

GL Framebuffer Completeness & Blitting Issues

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple ID.