+ _mesa_lock_texture(ctx, texObj);
+ ctx->Driver.GenerateMipmap(ctx, target, texObj);
+ _mesa_unlock_texture(ctx, texObj);
+}
+
+
+#if FEATURE_EXT_framebuffer_blit
+void GLAPIENTRY
+_mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+ FLUSH_VERTICES(ctx, _NEW_BUFFERS);
+
+ if (ctx->NewState) {
+ _mesa_update_state(ctx);
+ }
+
+ if (!ctx->ReadBuffer) {
+ /* XXX */
+ }
+
+ /* check for complete framebuffers */
+ if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT ||
+ ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
+ "glBlitFramebufferEXT(incomplete draw/read buffers)");
+ return;
+ }
+
+ if (filter != GL_NEAREST && filter != GL_LINEAR) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBlitFramebufferEXT(filter)");
+ return;
+ }
+
+ if (mask & ~(GL_COLOR_BUFFER_BIT |
+ GL_DEPTH_BUFFER_BIT |
+ GL_STENCIL_BUFFER_BIT)) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glBlitFramebufferEXT(mask)");
+ return;
+ }
+
+ /* depth/stencil must be blitted with nearest filtering */
+ if ((mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
+ && filter != GL_NEAREST) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glBlitFramebufferEXT(depth/stencil requires GL_NEAREST filter");
+ return;
+ }
+
+ if (mask & GL_STENCIL_BUFFER_BIT) {
+ struct gl_renderbuffer *readRb = ctx->ReadBuffer->_StencilBuffer;
+ struct gl_renderbuffer *drawRb = ctx->DrawBuffer->_StencilBuffer;
+ if (readRb->StencilBits != drawRb->StencilBits) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glBlitFramebufferEXT(stencil buffer size mismatch");
+ return;
+ }
+ }
+
+ if (mask & GL_DEPTH_BUFFER_BIT) {
+ struct gl_renderbuffer *readRb = ctx->ReadBuffer->_DepthBuffer;
+ struct gl_renderbuffer *drawRb = ctx->DrawBuffer->_DepthBuffer;
+ if (readRb->DepthBits != drawRb->DepthBits) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glBlitFramebufferEXT(depth buffer size mismatch");
+ return;
+ }
+ }
+
+ if (!ctx->Extensions.EXT_framebuffer_blit) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebufferEXT");
+ return;
+ }
+
+ ASSERT(ctx->Driver.BlitFramebuffer);
+ ctx->Driver.BlitFramebuffer(ctx,
+ srcX0, srcY0, srcX1, srcY1,
+ dstX0, dstY0, dstX1, dstY1,
+ mask, filter);