osmesa: fix glReadPixels, etc
authorBrian Paul <brianp@vmware.com>
Thu, 12 Jan 2012 18:52:22 +0000 (11:52 -0700)
committerBrian Paul <brianp@vmware.com>
Thu, 12 Jan 2012 20:49:15 +0000 (13:49 -0700)
Needed to implement the Map/UnmapRenderbuffer() driver hooks.
This fixes glRead/Draw/CopyPixels, etc.

See https://bugs.freedesktop.org/show_bug.cgi?id=44723

Note: This is a candidate for the 8.0 branch.

Tested-by: Kevin Hobbs <hobbsk@ohiou.edu>
src/mesa/drivers/osmesa/osmesa.c

index acfe6295667c757ef12195a0d9f5951beaf612bb..67d329faf701cb5b4e80942afccc8ad7628c6428 100644 (file)
@@ -56,6 +56,8 @@
 #include "vbo/vbo.h"
 
 
+#define OSMESA_RENDERBUFFER_CLASS 0x053
+
 
 /**
  * OSMesa rendering context, derived from core Mesa struct gl_context.
@@ -932,11 +934,12 @@ new_osmesa_renderbuffer(struct gl_context *ctx, GLenum format, GLenum type)
       rb->RefCount = 1;
       rb->Delete = osmesa_delete_renderbuffer;
       rb->AllocStorage = osmesa_renderbuffer_storage;
+      rb->ClassID = OSMESA_RENDERBUFFER_CLASS;
 
       rb->InternalFormat = GL_RGBA;
       switch (type) {
       case GL_UNSIGNED_BYTE:
-         rb->Format = MESA_FORMAT_RGBA8888;
+         rb->Format = MESA_FORMAT_RGBA8888_REV;
          break;
       case GL_UNSIGNED_SHORT:
          rb->Format = MESA_FORMAT_RGBA_16;
@@ -959,6 +962,56 @@ new_osmesa_renderbuffer(struct gl_context *ctx, GLenum format, GLenum type)
 }
 
 
+
+static void
+osmesa_MapRenderbuffer(struct gl_context *ctx,
+                       struct gl_renderbuffer *rb,
+                       GLuint x, GLuint y, GLuint w, GLuint h,
+                       GLbitfield mode,
+                       GLubyte **mapOut, GLint *rowStrideOut)
+{
+   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
+
+   if (rb->ClassID == OSMESA_RENDERBUFFER_CLASS) {
+      /* this is an OSMesa renderbuffer which wraps user memory */
+      const GLuint bpp = _mesa_get_format_bytes(rb->Format);
+      GLint rowStride; /* in bytes */
+
+      if (osmesa->userRowLength)
+         rowStride = osmesa->userRowLength * bpp;
+      else
+         rowStride = rb->Width * bpp;
+
+      if (!osmesa->yup) {
+         /* Y=0 is top line of window */
+         y = rb->Height - y - 1;
+         *rowStrideOut = -rowStride;
+      }
+      else {
+         *rowStrideOut = rowStride;
+      }
+
+      *mapOut = (GLubyte *) rb->Data + y * rowStride + x * bpp;
+   }
+   else {
+      _swrast_map_soft_renderbuffer(ctx, rb, x, y, w, h, mode,
+                                    mapOut, rowStrideOut);
+   }
+}
+
+
+static void
+osmesa_UnmapRenderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb)
+{
+   if (rb->ClassID == OSMESA_RENDERBUFFER_CLASS) {
+      /* no-op */
+   }
+   else {
+      _swrast_unmap_soft_renderbuffer(ctx, rb);
+   }
+}
+
+
 /**********************************************************************/
 /*****                    Public Functions                        *****/
 /**********************************************************************/
@@ -1157,6 +1210,9 @@ OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits,
          tnl = TNL_CONTEXT(ctx);
          tnl->Driver.RunPipeline = _tnl_run_pipeline;
 
+         ctx->Driver.MapRenderbuffer = osmesa_MapRenderbuffer;
+         ctx->Driver.UnmapRenderbuffer = osmesa_UnmapRenderbuffer;
+
          /* Extend the software rasterizer with our optimized line and triangle
           * drawing functions.
           */