[Mesa-dev] [PATCH 02/24] Add MapRenderbuffer implementations for software drivers.

Eric Anholt eric at anholt.net
Fri Oct 28 12:49:52 PDT 2011


Mesa core's is generic for things like osmesa.

For swrast_dri.so, we have to do Y flipping.  The front-buffer path
isn't actually tested, though, because both before and after it fails
with a BadMatch in XGetImage.
---
 src/mesa/drivers/common/driverfuncs.c     |    2 +
 src/mesa/drivers/dri/swrast/swrast.c      |   84 +++++++++++++++++++++++++++--
 src/mesa/drivers/dri/swrast/swrast_priv.h |    5 ++
 src/mesa/main/renderbuffer.c              |   27 +++++++++
 src/mesa/main/renderbuffer.h              |   12 ++++
 src/mesa/swrast/s_texrender.c             |    1 +
 6 files changed, 127 insertions(+), 4 deletions(-)

diff --git a/src/mesa/drivers/common/driverfuncs.c b/src/mesa/drivers/common/driverfuncs.c
index 263d402..42259f8 100644
--- a/src/mesa/drivers/common/driverfuncs.c
+++ b/src/mesa/drivers/common/driverfuncs.c
@@ -179,6 +179,8 @@ _mesa_init_driver_functions(struct dd_function_table *driver)
 
    driver->NewFramebuffer = _mesa_new_framebuffer;
    driver->NewRenderbuffer = _mesa_new_soft_renderbuffer;
+   driver->MapRenderbuffer = _mesa_map_soft_renderbuffer;
+   driver->UnmapRenderbuffer = _mesa_unmap_soft_renderbuffer;
    driver->RenderTexture = _swrast_render_texture;
    driver->FinishRenderTexture = _swrast_finish_render_texture;
    driver->FramebufferRenderbuffer = _mesa_framebuffer_renderbuffer;
diff --git a/src/mesa/drivers/dri/swrast/swrast.c b/src/mesa/drivers/dri/swrast/swrast.c
index 75d2525..bc115e8 100644
--- a/src/mesa/drivers/dri/swrast/swrast.c
+++ b/src/mesa/drivers/dri/swrast/swrast.c
@@ -291,7 +291,7 @@ swrast_alloc_front_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
     rb->Data = NULL;
     rb->Width = width;
     rb->Height = height;
-
+    rb->RowStride = width;
     xrb->pitch = bytes_per_line(width * xrb->bpp, 32);
 
     return GL_TRUE;
@@ -315,7 +315,8 @@ swrast_alloc_back_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
 }
 
 static struct swrast_renderbuffer *
-swrast_new_renderbuffer(const struct gl_config *visual, GLboolean front)
+swrast_new_renderbuffer(const struct gl_config *visual, __DRIdrawable *dPriv,
+			GLboolean front)
 {
     struct swrast_renderbuffer *xrb = calloc(1, sizeof *xrb);
     GLuint pixel_format;
@@ -329,6 +330,7 @@ swrast_new_renderbuffer(const struct gl_config *visual, GLboolean front)
 
     pixel_format = choose_pixel_format(visual);
 
+    xrb->dPriv = dPriv;
     xrb->Base.Delete = swrast_delete_renderbuffer;
     if (front) {
 	xrb->Base.AllocStorage = swrast_alloc_front_storage;
@@ -375,6 +377,78 @@ swrast_new_renderbuffer(const struct gl_config *visual, GLboolean front)
     return xrb;
 }
 
+static void
+swrast_map_renderbuffer(struct gl_context *ctx,
+			struct gl_renderbuffer *rb,
+			GLuint x, GLuint y, GLuint w, GLuint h,
+			GLbitfield mode,
+			GLubyte **out_map,
+			GLint *out_stride)
+{
+   struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
+   GLubyte *map = rb->Data;
+   int cpp = _mesa_get_format_bytes(rb->Format);
+   int stride = rb->RowStride * cpp;
+
+   if (rb->AllocStorage == swrast_alloc_front_storage) {
+      __DRIdrawable *dPriv = xrb->dPriv;
+      __DRIscreen *sPriv = dPriv->driScreenPriv;
+
+      xrb->map_mode = mode;
+      xrb->map_x = x;
+      xrb->map_y = y;
+      xrb->map_w = w;
+      xrb->map_h = h;
+
+      stride = w * cpp;
+      rb->Data = malloc(h * stride);
+
+      sPriv->swrast_loader->getImage(dPriv, x, y, w, h,
+				     (char *)rb->Data,
+				     dPriv->loaderPrivate);
+
+      *out_map = rb->Data;
+      *out_stride = stride;
+      return;
+   }
+
+   ASSERT(rb->Data);
+
+   if (rb->AllocStorage == swrast_alloc_back_storage) {
+      map += (rb->Height - 1) * stride;
+      stride = -stride;
+   }
+
+   map += y * stride;
+   map += x * cpp;
+
+   *out_map = map;
+   *out_stride = stride;
+}
+
+static void
+swrast_unmap_renderbuffer(struct gl_context *ctx,
+			  struct gl_renderbuffer *rb)
+{
+   struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
+
+   if (rb->AllocStorage == swrast_alloc_front_storage) {
+      __DRIdrawable *dPriv = xrb->dPriv;
+      __DRIscreen *sPriv = dPriv->driScreenPriv;
+
+      if (xrb->map_mode & GL_MAP_WRITE_BIT) {
+	 sPriv->swrast_loader->putImage(dPriv, __DRI_SWRAST_IMAGE_OP_DRAW,
+					xrb->map_x, xrb->map_y,
+					xrb->map_w, xrb->map_h,
+					rb->Data,
+					dPriv->loaderPrivate);
+      }
+
+      free(rb->Data);
+      rb->Data = NULL;
+   }
+}
+
 static GLboolean
 dri_create_buffer(__DRIscreen * sPriv,
 		  __DRIdrawable * dPriv,
@@ -406,12 +480,12 @@ dri_create_buffer(__DRIscreen * sPriv,
     _mesa_initialize_window_framebuffer(fb, visual);
 
     /* add front renderbuffer */
-    frontrb = swrast_new_renderbuffer(visual, GL_TRUE);
+    frontrb = swrast_new_renderbuffer(visual, dPriv, GL_TRUE);
     _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontrb->Base);
 
     /* add back renderbuffer */
     if (visual->doubleBufferMode) {
-	backrb = swrast_new_renderbuffer(visual, GL_FALSE);
+	backrb = swrast_new_renderbuffer(visual, dPriv, GL_FALSE);
 	_mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backrb->Base);
     }
 
@@ -576,6 +650,8 @@ swrast_init_driver_functions(struct dd_function_table *driver)
     driver->GetBufferSize = NULL;
     driver->Viewport = viewport;
     driver->ChooseTextureFormat = swrastChooseTextureFormat;
+    driver->MapRenderbuffer = swrast_map_renderbuffer;
+    driver->UnmapRenderbuffer = swrast_unmap_renderbuffer;
 }
 
 static const char *es2_extensions[] = {
diff --git a/src/mesa/drivers/dri/swrast/swrast_priv.h b/src/mesa/drivers/dri/swrast/swrast_priv.h
index bdb52ef..50e6a83 100644
--- a/src/mesa/drivers/dri/swrast/swrast_priv.h
+++ b/src/mesa/drivers/dri/swrast/swrast_priv.h
@@ -102,6 +102,11 @@ swrast_drawable(struct gl_framebuffer *fb)
 
 struct swrast_renderbuffer {
     struct gl_renderbuffer Base;
+    __DRIdrawable *dPriv;
+
+    /* GL_MAP_*_BIT, used for mapping of front buffer. */
+    GLbitfield map_mode;
+   int map_x, map_y, map_w, map_h;
 
     /* renderbuffer pitch (in bytes) */
     GLuint pitch;
diff --git a/src/mesa/main/renderbuffer.c b/src/mesa/main/renderbuffer.c
index 70011e6..5dd46cc 100644
--- a/src/mesa/main/renderbuffer.c
+++ b/src/mesa/main/renderbuffer.c
@@ -1716,6 +1716,33 @@ _mesa_soft_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *
 }
 
 
+void
+_mesa_map_soft_renderbuffer(struct gl_context *ctx,
+			    struct gl_renderbuffer *rb,
+			    GLuint x, GLuint y, GLuint w, GLuint h,
+			    GLbitfield mode,
+			    GLubyte **out_map,
+			    GLint *out_stride)
+{
+   GLubyte *map = rb->Data;
+   int cpp = _mesa_get_format_bytes(rb->Format);
+   int stride = rb->RowStride * cpp;
+
+   ASSERT(rb->Data);
+
+   map += y * stride;
+   map += x * cpp;
+
+   *out_map = map;
+   *out_stride = stride;
+}
+
+void
+_mesa_unmap_soft_renderbuffer(struct gl_context *ctx,
+			      struct gl_renderbuffer *rb)
+{
+}
+
 
 /**********************************************************************/
 /**********************************************************************/
diff --git a/src/mesa/main/renderbuffer.h b/src/mesa/main/renderbuffer.h
index de471cd..cb0d712 100644
--- a/src/mesa/main/renderbuffer.h
+++ b/src/mesa/main/renderbuffer.h
@@ -46,6 +46,18 @@ _mesa_delete_renderbuffer(struct gl_renderbuffer *rb);
 extern struct gl_renderbuffer *
 _mesa_new_soft_renderbuffer(struct gl_context *ctx, GLuint name);
 
+void
+_mesa_map_soft_renderbuffer(struct gl_context *ctx,
+			    struct gl_renderbuffer *rb,
+			    GLuint x, GLuint y, GLuint w, GLuint h,
+			    GLbitfield mode,
+			    GLubyte **out_map,
+			    GLint *out_stride);
+
+void
+_mesa_unmap_soft_renderbuffer(struct gl_context *ctx,
+			      struct gl_renderbuffer *rb);
+
 extern void
 _mesa_set_renderbuffer_accessors(struct gl_renderbuffer *rb);
 
diff --git a/src/mesa/swrast/s_texrender.c b/src/mesa/swrast/s_texrender.c
index e2b9215..83e7a6a 100644
--- a/src/mesa/swrast/s_texrender.c
+++ b/src/mesa/swrast/s_texrender.c
@@ -563,6 +563,7 @@ update_wrapper(struct gl_context *ctx, struct gl_renderbuffer_attachment *att)
 
    trb->Base.Width = trb->TexImage->Base.Width;
    trb->Base.Height = trb->TexImage->Base.Height;
+   trb->Base.RowStride = trb->TexImage->RowStride;
    trb->Base.InternalFormat = trb->TexImage->Base.InternalFormat;
    trb->Base.Format = trb->TexImage->Base.TexFormat;
 
-- 
1.7.7



More information about the mesa-dev mailing list