static struct gl_framebuffer IncompleteFramebuffer;
-#define IS_CUBE_FACE(TARGET) \
- ((TARGET) >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && \
- (TARGET) <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
+static INLINE GLboolean
+is_cube_face(GLenum target)
+{
+ return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
+ target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
+}
+
+
+/**
+ * Is the given FBO a user-created FBO?
+ */
+static INLINE GLboolean
+is_user_fbo(const struct gl_framebuffer *fb)
+{
+ return fb->Name != 0;
+}
+
+
+/**
+ * Is the given FBO a window system FBO (like an X window)?
+ */
+static INLINE GLboolean
+is_winsys_fbo(const struct gl_framebuffer *fb)
+{
+ return fb->Name == 0;
+}
static void
{
GLuint i;
- assert(fb->Name > 0);
+ assert(is_user_fbo(fb));
switch (attachment) {
case GL_COLOR_ATTACHMENT0_EXT:
_mesa_get_fb0_attachment(struct gl_context *ctx, struct gl_framebuffer *fb,
GLenum attachment)
{
- assert(fb->Name == 0);
+ assert(is_winsys_fbo(fb));
switch (attachment) {
case GL_FRONT_LEFT:
case GL_RG:
fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED;
return;
- case GL_RGB:
+
+ default:
switch (rb->Format) {
+ /* XXX This list is likely incomplete. */
case MESA_FORMAT_RGB9_E5_FLOAT:
fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED;
return;
default:;
+ /* render buffer format is supported by software rendering */
}
- break;
-
- default:
- /* render buffer format is supported by software rendering */
- ;
}
}
}
GLint i;
GLuint j;
- assert(fb->Name != 0);
+ assert(is_user_fbo(fb));
numImages = 0;
fb->Width = 0;
}
#if FEATURE_GL
- if (ctx->API == API_OPENGL) {
+ if (ctx->API == API_OPENGL && !ctx->Extensions.ARB_ES2_compatibility) {
/* Check that all DrawBuffers are present */
for (j = 0; j < ctx->Const.MaxDrawBuffers; j++) {
if (fb->ColorDrawBuffer[j] != GL_NONE) {
_mesa_BindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
}
- if (ctx->DrawBuffer->Name) {
+ if (is_user_fbo(ctx->DrawBuffer)) {
detach_renderbuffer(ctx, ctx->DrawBuffer, rb);
}
- if (ctx->ReadBuffer->Name && ctx->ReadBuffer != ctx->DrawBuffer) {
+ if (is_user_fbo(ctx->ReadBuffer)
+ && ctx->ReadBuffer != ctx->DrawBuffer) {
detach_renderbuffer(ctx, ctx->ReadBuffer, rb);
}
ctx->Extensions.ARB_framebuffer_object ? GL_INTENSITY : 0;
case GL_RGB9_E5:
return ctx->Extensions.EXT_texture_shared_exponent ? GL_RGB : 0;
+ case GL_R11F_G11F_B10F:
+ return ctx->Extensions.EXT_packed_float ? GL_RGB : 0;
/* XXX add integer formats eventually */
default:
return 0;
struct gl_renderbuffer *rb = (struct gl_renderbuffer *) userData;
/* If this is a user-created FBO */
- if (fb->Name) {
+ if (is_user_fbo(fb)) {
GLuint i;
for (i = 0; i < BUFFER_COUNT; i++) {
struct gl_renderbuffer_attachment *att = fb->Attachment + i;
GLuint i;
ASSERT(ctx->Driver.RenderTexture);
- if (fb->Name == 0)
+ if (is_winsys_fbo(fb))
return; /* can't render to texture with winsys framebuffers */
for (i = 0; i < BUFFER_COUNT; i++) {
static void
check_end_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb)
{
- if (fb->Name == 0)
+ if (is_winsys_fbo(fb))
return; /* can't render to texture with winsys framebuffers */
if (ctx->Driver.FinishRenderTexture) {
return 0;
}
- if (buffer->Name == 0) {
+ if (is_winsys_fbo(buffer)) {
/* The window system / default framebuffer is always complete */
return GL_FRAMEBUFFER_COMPLETE_EXT;
}
}
/* check framebuffer binding */
- if (fb->Name == 0) {
+ if (is_winsys_fbo(fb)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glFramebufferTexture%sEXT", caller);
return;
}
else {
err = (texObj->Target == GL_TEXTURE_CUBE_MAP)
- ? !IS_CUBE_FACE(textarget)
+ ? !is_cube_face(textarget)
: (texObj->Target != textarget);
}
}
if ((texture != 0) &&
(textarget != GL_TEXTURE_2D) &&
(textarget != GL_TEXTURE_RECTANGLE_ARB) &&
- (!IS_CUBE_FACE(textarget))) {
+ (!is_cube_face(textarget))) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glFramebufferTexture2DEXT(textarget=0x%x)", textarget);
return;
return;
}
- if (fb->Name == 0) {
+ if (is_winsys_fbo(fb)) {
/* Can't attach new renderbuffers to a window system framebuffer */
_mesa_error(ctx, GL_INVALID_OPERATION, "glFramebufferRenderbufferEXT");
return;
return;
}
- if (buffer->Name == 0) {
+ if (is_winsys_fbo(buffer)) {
/* the default / window-system FBO */
att = _mesa_get_fb0_attachment(ctx, buffer, attachment);
}
switch (pname) {
case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT:
- *params = buffer->Name == 0 ? GL_FRAMEBUFFER_DEFAULT : att->Type;
+ *params = is_winsys_fbo(buffer) ? GL_FRAMEBUFFER_DEFAULT : att->Type;
return;
case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT:
if (att->Type == GL_RENDERBUFFER_EXT) {
if (att->Type == GL_TEXTURE) {
*params = att->TextureLevel;
}
+ else if (att->Type == GL_NONE) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetFramebufferAttachmentParameterivEXT(pname)");
+ }
else {
_mesa_error(ctx, GL_INVALID_ENUM,
"glGetFramebufferAttachmentParameterivEXT(pname)");
*params = 0;
}
}
+ else if (att->Type == GL_NONE) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetFramebufferAttachmentParameterivEXT(pname)");
+ }
else {
_mesa_error(ctx, GL_INVALID_ENUM,
"glGetFramebufferAttachmentParameterivEXT(pname)");
*params = 0;
}
}
+ else if (att->Type == GL_NONE) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetFramebufferAttachmentParameterivEXT(pname)");
+ }
else {
_mesa_error(ctx, GL_INVALID_ENUM,
"glGetFramebufferAttachmentParameterivEXT(pname)");
_mesa_error(ctx, GL_INVALID_ENUM,
"glGetFramebufferAttachmentParameterivEXT(pname)");
}
+ else if (att->Type == GL_NONE) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetFramebufferAttachmentParameterivEXT(pname)");
+ }
else {
if (ctx->Extensions.EXT_framebuffer_sRGB && ctx->Const.sRGBCapable) {
*params = _mesa_get_format_color_encoding(att->Renderbuffer->Format);
"glGetFramebufferAttachmentParameterivEXT(pname)");
return;
}
+ else if (att->Type == GL_NONE) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetFramebufferAttachmentParameterivEXT(pname)");
+ }
else {
gl_format format = att->Renderbuffer->Format;
if (format == MESA_FORMAT_CI8 || format == MESA_FORMAT_S8) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glGetFramebufferAttachmentParameterivEXT(pname)");
}
+ else if (att->Type == GL_NONE) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetFramebufferAttachmentParameterivEXT(pname)");
+ }
else if (att->Texture) {
const struct gl_texture_image *texImage =
_mesa_select_tex_image(ctx, att->Texture, att->Texture->Target,
att->Renderbuffer->Format);
}
else {
- *params = 0;
+ _mesa_problem(ctx, "glGetFramebufferAttachmentParameterivEXT:"
+ " invalid FBO attachment structure");
}
return;
default:
if (mask & GL_COLOR_BUFFER_BIT) {
colorReadRb = readFb->_ColorReadBuffer;
colorDrawRb = drawFb->_ColorDrawBuffers[0];
+
+ /* From the EXT_framebuffer_object spec:
+ *
+ * "If a buffer is specified in <mask> and does not exist in both
+ * the read and draw framebuffers, the corresponding bit is silently
+ * ignored."
+ */
+ if ((colorReadRb == NULL) || (colorDrawRb == NULL)) {
+ colorReadRb = colorDrawRb = NULL;
+ mask &= ~GL_COLOR_BUFFER_BIT;
+ }
}
else {
colorReadRb = colorDrawRb = NULL;
if (mask & GL_STENCIL_BUFFER_BIT) {
struct gl_renderbuffer *readRb = readFb->_StencilBuffer;
struct gl_renderbuffer *drawRb = drawFb->_StencilBuffer;
- if (!readRb ||
- !drawRb ||
- _mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS) !=
- _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS)) {
+
+ /* From the EXT_framebuffer_object spec:
+ *
+ * "If a buffer is specified in <mask> and does not exist in both
+ * the read and draw framebuffers, the corresponding bit is silently
+ * ignored."
+ */
+ if ((readRb == NULL) || (drawRb == NULL)) {
+ readRb = drawRb = NULL;
+ mask &= ~GL_STENCIL_BUFFER_BIT;
+ }
+ else if (_mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS) !=
+ _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glBlitFramebufferEXT(stencil buffer size mismatch)");
return;
if (mask & GL_DEPTH_BUFFER_BIT) {
struct gl_renderbuffer *readRb = readFb->_DepthBuffer;
struct gl_renderbuffer *drawRb = drawFb->_DepthBuffer;
- if (!readRb ||
- !drawRb ||
- _mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS) !=
- _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS)) {
+
+ /* From the EXT_framebuffer_object spec:
+ *
+ * "If a buffer is specified in <mask> and does not exist in both
+ * the read and draw framebuffers, the corresponding bit is silently
+ * ignored."
+ */
+ if ((readRb == NULL) || (drawRb == NULL)) {
+ readRb = drawRb = NULL;
+ mask &= ~GL_DEPTH_BUFFER_BIT;
+ }
+ else if (_mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS) !=
+ _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glBlitFramebufferEXT(depth buffer size mismatch)");
return;