intel: add GL_EXT_framebuffer blit extension
authorBrian Paul <brianp@vmware.com>
Thu, 22 Jan 2009 22:43:40 +0000 (15:43 -0700)
committerBrian Paul <brianp@vmware.com>
Thu, 22 Jan 2009 22:43:40 +0000 (15:43 -0700)
This functionality is required by GL_ARB_framebuffer_object.
For now, implement it in terms of glCopyPixels().  This will need to be
revisted though.

src/mesa/drivers/dri/intel/intel_context.c
src/mesa/drivers/dri/intel/intel_fbo.c

index c4a24d73972d4e3643b732bb3b640998a6be0139..3a4e652ae5edf27ab0fec318e28a0ddcd509e813 100644 (file)
@@ -84,6 +84,7 @@ int INTEL_DEBUG = (0);
 #define need_GL_EXT_cull_vertex
 #define need_GL_EXT_fog_coord
 #define need_GL_EXT_framebuffer_object
+#define need_GL_EXT_framebuffer_blit
 #define need_GL_EXT_multi_draw_arrays
 #define need_GL_EXT_point_parameters
 #define need_GL_EXT_secondary_color
@@ -421,8 +422,9 @@ static const struct dri_extension arb_oq_extensions[] = {
 };
 
 static const struct dri_extension ttm_extensions[] = {
-   { "GL_ARB_pixel_buffer_object",        NULL },
-   { "GL_EXT_framebuffer_object",         GL_EXT_framebuffer_object_functions },
+   { "GL_ARB_pixel_buffer_object",      NULL },
+   { "GL_EXT_framebuffer_blit",         GL_EXT_framebuffer_blit_functions },
+   { "GL_EXT_framebuffer_object",       GL_EXT_framebuffer_object_functions },
    { NULL, NULL }
 };
 
index 47217f756ca85922784a122e5fb61a09156f39d4..05847ee5fea61c893753e7acc298242a67048154 100644 (file)
@@ -27,6 +27,7 @@
 
 
 #include "main/imports.h"
+#include "main/macros.h"
 #include "main/mtypes.h"
 #include "main/fbobject.h"
 #include "main/framebuffer.h"
@@ -636,6 +637,74 @@ intel_validate_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb)
 }
 
 
+/**
+ * Called from glBlitFramebuffer().
+ * For now, we're doing an approximation with glCopyPixels().
+ * XXX we need to bypass all the per-fragment operations, except scissor.
+ */
+static void
+intel_blit_framebuffer(GLcontext *ctx,
+                       GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+                       GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+                       GLbitfield mask, GLenum filter)
+{
+   const GLfloat xZoomSave = ctx->Pixel.ZoomX;
+   const GLfloat yZoomSave = ctx->Pixel.ZoomY;
+   GLsizei width, height;
+   GLfloat xFlip = 1.0F, yFlip = 1.0F;
+
+   if (srcX1 < srcX0) {
+      GLint tmp = srcX1;
+      srcX1 = srcX0;
+      srcX0 = tmp;
+      xFlip = -1.0F;
+   }
+
+   if (srcY1 < srcY0) {
+      GLint tmp = srcY1;
+      srcY1 = srcY0;
+      srcY0 = tmp;
+      yFlip = -1.0F;
+   }
+
+   width = srcX1 - srcX0;
+   height = srcY1 - srcY0;
+
+   ctx->Pixel.ZoomX = xFlip * (dstX1 - dstX0) / (srcX1 - srcY0);
+   ctx->Pixel.ZoomY = yFlip * (dstY1 - dstY0) / (srcY1 - srcY0);
+
+   if (ctx->Pixel.ZoomX < 0.0F) {
+      dstX0 = MAX2(dstX0, dstX1);
+   }
+   else {
+      dstX0 = MIN2(dstX0, dstX1);
+   }
+
+   if (ctx->Pixel.ZoomY < 0.0F) {
+      dstY0 = MAX2(dstY0, dstY1);
+   }
+   else {
+      dstY0 = MIN2(dstY0, dstY1);
+   }
+
+   if (mask & GL_COLOR_BUFFER_BIT) {
+      ctx->Driver.CopyPixels(ctx, srcX0, srcY0, width, height,
+                             dstX0, dstY0, GL_COLOR);
+   }
+   if (mask & GL_DEPTH_BUFFER_BIT) {
+      ctx->Driver.CopyPixels(ctx, srcX0, srcY0, width, height,
+                             dstX0, dstY0, GL_DEPTH);
+   }
+   if (mask & GL_STENCIL_BUFFER_BIT) {
+      ctx->Driver.CopyPixels(ctx, srcX0, srcY0, width, height,
+                             dstX0, dstY0, GL_STENCIL);
+   }
+      
+   ctx->Pixel.ZoomX = xZoomSave;
+   ctx->Pixel.ZoomY = yZoomSave;
+}
+
+
 /**
  * Do one-time context initializations related to GL_EXT_framebuffer_object.
  * Hook in device driver functions.
@@ -651,4 +720,5 @@ intel_fbo_init(struct intel_context *intel)
    intel->ctx.Driver.FinishRenderTexture = intel_finish_render_texture;
    intel->ctx.Driver.ResizeBuffers = intel_resize_buffers;
    intel->ctx.Driver.ValidateFramebuffer = intel_validate_framebuffer;
+   intel->ctx.Driver.BlitFramebuffer = intel_blit_framebuffer;
 }