#include "buffers.h"
#include "context.h"
+#include "enums.h"
#include "fbobject.h"
#include "framebuffer.h"
#include "hash.h"
#include "teximage.h"
#include "texobj.h"
#include "texstore.h"
+#include "texstate.h"
/** Set this to 1 to help debug FBO incompleteness problems */
#define DEBUG_FBO 0
+/** Set this to 1 to debug/log glBlitFramebuffer() calls */
+#define DEBUG_BLIT 0
+
/**
* Notes:
/* always update these fields */
att->TextureLevel = level;
- if (IS_CUBE_FACE(texTarget)) {
- att->CubeMapFace = texTarget - GL_TEXTURE_CUBE_MAP_POSITIVE_X;
- }
- else {
- att->CubeMapFace = 0;
- }
+ att->CubeMapFace = _mesa_tex_target_to_face(texTarget);
att->Zoffset = zoffset;
att->Complete = GL_FALSE;
}
FLUSH_CURRENT(ctx, _NEW_BUFFERS);
- /* The above doesn't fully flush the drivers in the way that a
- * glFlush does, but that is required here:
- */
- if (ctx->Driver.Flush)
- ctx->Driver.Flush(ctx);
-
if (renderbuffer) {
newRb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
struct gl_renderbuffer_attachment *att = fb->Attachment + i;
struct gl_texture_object *texObj = att->Texture;
if (texObj
- && att->Texture->Image[att->CubeMapFace][att->TextureLevel]) {
+ && texObj->Image[att->CubeMapFace][att->TextureLevel]) {
ctx->Driver.RenderTexture(ctx, fb, att);
}
}
}
FLUSH_CURRENT(ctx, _NEW_BUFFERS);
- if (ctx->Driver.Flush) {
- ctx->Driver.Flush(ctx);
- }
if (framebuffer) {
/* Binding a user-created framebuffer object */
ASSERT_OUTSIDE_BEGIN_END(ctx);
FLUSH_CURRENT(ctx, _NEW_BUFFERS);
- /* The above doesn't fully flush the drivers in the way that a
- * glFlush does, but that is required here:
- */
- if (ctx->Driver.Flush)
- ctx->Driver.Flush(ctx);
for (i = 0; i < n; i++) {
if (framebuffers[i] > 0) {
return;
}
- if (texObj && attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
- /* the texture format must be depth+stencil */
- const struct gl_texture_image *texImg;
- texImg = texObj->Image[0][texObj->BaseLevel];
- if (!texImg || texImg->_BaseFormat != GL_DEPTH_STENCIL) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glFramebufferTexture%sEXT(texture is not"
- " DEPTH_STENCIL format)", caller);
- return;
- }
- }
-
FLUSH_CURRENT(ctx, _NEW_BUFFERS);
- /* The above doesn't fully flush the drivers in the way that a
- * glFlush does, but that is required here:
- */
- if (ctx->Driver.Flush)
- ctx->Driver.Flush(ctx);
_glthread_LOCK_MUTEX(fb->Mutex);
if (texObj) {
att = _mesa_get_attachment(ctx, fb, attachment);
if (att == NULL) {
_mesa_error(ctx, GL_INVALID_ENUM,
- "glFramebufferRenderbufferEXT(attachment)");
+ "glFramebufferRenderbufferEXT(invalid attachment %s)",
+ _mesa_lookup_enum_by_nr(attachment));
return;
}
rb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
if (!rb) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glFramebufferRenderbufferEXT(renderbuffer)");
+ "glFramebufferRenderbufferEXT(non-existant"
+ " renderbuffer %u)", renderbuffer);
return;
}
}
FLUSH_CURRENT(ctx, _NEW_BUFFERS);
- /* The above doesn't fully flush the drivers in the way that a
- * glFlush does, but that is required here:
- */
- if (ctx->Driver.Flush)
- ctx->Driver.Flush(ctx);
assert(ctx->Driver.FramebufferRenderbuffer);
ctx->Driver.FramebufferRenderbuffer(ctx, fb, attachment, rb);
}
FLUSH_CURRENT(ctx, _NEW_BUFFERS);
- /* The above doesn't fully flush the drivers in the way that a
- * glFlush does, but that is required here:
- */
- if (ctx->Driver.Flush)
- ctx->Driver.Flush(ctx);
switch (pname) {
case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT:
return;
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
#if FEATURE_EXT_framebuffer_blit
+
+static const struct gl_renderbuffer_attachment *
+find_attachment(const struct gl_framebuffer *fb, const struct gl_renderbuffer *rb)
+{
+ GLuint i;
+ for (i = 0; i < Elements(fb->Attachment); i++) {
+ if (fb->Attachment[i].Renderbuffer == rb)
+ return &fb->Attachment[i];
+ }
+ return NULL;
+}
+
+
+
/**
* Blit rectangular region, optionally from one framebuffer to another.
*
return;
}
+ /* Debug code */
+ if (DEBUG_BLIT) {
+ _mesa_printf("glBlitFramebuffer(%d, %d, %d, %d, %d, %d, %d, %d,"
+ " 0x%x, 0x%x)\n",
+ srcX0, srcY0, srcX1, srcY1,
+ dstX0, dstY0, dstX1, dstY1,
+ mask, filter);
+ if (colorReadRb) {
+ const struct gl_renderbuffer_attachment *att;
+
+ att = find_attachment(readFb, colorReadRb);
+ _mesa_printf(" Src FBO %u RB %u (%dx%d) ",
+ readFb->Name, colorReadRb->Name,
+ colorReadRb->Width, colorReadRb->Height);
+ if (att && att->Texture) {
+ _mesa_printf("Tex %u tgt 0x%x level %u face %u",
+ att->Texture->Name,
+ att->Texture->Target,
+ att->TextureLevel,
+ att->CubeMapFace);
+ }
+ _mesa_printf("\n");
+
+ att = find_attachment(drawFb, colorDrawRb);
+ _mesa_printf(" Dst FBO %u RB %u (%dx%d) ",
+ drawFb->Name, colorDrawRb->Name,
+ colorDrawRb->Width, colorDrawRb->Height);
+ if (att && att->Texture) {
+ _mesa_printf("Tex %u tgt 0x%x level %u face %u",
+ att->Texture->Name,
+ att->Texture->Target,
+ att->TextureLevel,
+ att->CubeMapFace);
+ }
+ _mesa_printf("\n");
+ }
+ }
+
ASSERT(ctx->Driver.BlitFramebuffer);
ctx->Driver.BlitFramebuffer(ctx,
srcX0, srcY0, srcX1, srcY1,