[Mesa-dev] [PATCH 05/24] radeon: Add implementation of MapRenderbuffer.

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


Unlike intel, we do a blit to/from GTT memory in order to
untile/retile the renderbuffer data, since we don't have fence
registers for accessing it.

(There is software tiling code in radeon_tile.c, but it's unused and
doesn't support macro tiling)
---
 .../drivers/dri/radeon/radeon_common_context.h     |    4 +
 src/mesa/drivers/dri/radeon/radeon_fbo.c           |   94 ++++++++++++++++++++
 2 files changed, 98 insertions(+), 0 deletions(-)

diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.h b/src/mesa/drivers/dri/radeon/radeon_common_context.h
index 1b23481..899e57d 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common_context.h
+++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h
@@ -86,6 +86,10 @@ struct radeon_renderbuffer
 	/* unsigned int offset; */
 	unsigned int pitch;
 
+	struct radeon_bo *map_bo;
+	GLbitfield map_mode;
+	int map_x, map_y, map_w, map_h;
+
 	uint32_t draw_offset; /* FBO */
 	/* boo Xorg 6.8.2 compat */
 	int has_surface;
diff --git a/src/mesa/drivers/dri/radeon/radeon_fbo.c b/src/mesa/drivers/dri/radeon/radeon_fbo.c
index 4b64cac..cf89fe5 100644
--- a/src/mesa/drivers/dri/radeon/radeon_fbo.c
+++ b/src/mesa/drivers/dri/radeon/radeon_fbo.c
@@ -70,6 +70,98 @@ radeon_delete_renderbuffer(struct gl_renderbuffer *rb)
   free(rrb);
 }
 
+static void
+radeon_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 radeon_context *const rmesa = RADEON_CONTEXT(ctx);
+   struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
+   GLubyte *map;
+   GLboolean ok;
+   int stride, ret;
+
+   assert(rrb && rrb->bo);
+
+   /* Make a temporary buffer and blit the current contents of the renderbuffer
+    * out to it.  This gives us linear access to the buffer, instead of having
+    * to do detiling in software.
+    */
+   assert(!rrb->map_bo);
+   rrb->map_bo = radeon_bo_open(rmesa->radeonScreen->bom, 0,
+				rrb->pitch * h, 4,
+				RADEON_GEM_DOMAIN_GTT, 0);
+   rrb->map_mode = mode;
+   rrb->map_x = x;
+   rrb->map_y = y;
+   rrb->map_w = w;
+   rrb->map_h = h;
+
+   ok = rmesa->vtbl.check_blit(rb->Format);
+   assert(ok);
+
+   ok = rmesa->vtbl.blit(ctx, rrb->bo, rrb->draw_offset,
+			 rb->Format, rrb->pitch / rrb->cpp,
+			 rb->Width, rb->Height,
+			 x, y,
+			 rrb->map_bo, 0,
+			 rb->Format, rrb->pitch / rrb->cpp,
+			 w, h,
+			 0, 0,
+			 w, h,
+			 GL_FALSE);
+   assert(ok);
+
+   radeon_bo_wait(rrb->map_bo);
+   ret = radeon_bo_map(rrb->map_bo, !!(mode & GL_MAP_WRITE_BIT));
+   assert(!ret);
+
+   map = rrb->map_bo->ptr;
+   stride = rrb->pitch;
+
+   if (rb->Name == 0) {
+      map += stride * (rb->Height - 1);
+      stride = -stride;
+   }
+
+   map += x * _mesa_get_format_bytes(rb->Format);
+   map += (int)y * stride;
+
+   *out_map = map;
+   *out_stride = stride;
+}
+
+static void
+radeon_unmap_renderbuffer(struct gl_context *ctx,
+			  struct gl_renderbuffer *rb)
+{
+   struct radeon_context *const rmesa = RADEON_CONTEXT(ctx);
+   struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
+   GLboolean ok;
+
+   radeon_bo_unmap(rrb->map_bo);
+
+   if (rrb->map_mode & GL_MAP_WRITE_BIT) {
+      ok = rmesa->vtbl.blit(ctx, rrb->map_bo, 0,
+			    rb->Format, rrb->pitch / rrb->cpp,
+			    rrb->map_w, rrb->map_h,
+			    0, 0,
+			    rrb->bo, rrb->draw_offset,
+			    rb->Format, rrb->pitch / rrb->cpp,
+			    rb->Width, rb->Height,
+			    rrb->map_x, rrb->map_y,
+			    rrb->map_w, rrb->map_h,
+			    GL_FALSE);
+      assert(ok);
+   }
+
+   radeon_bo_unref(rrb->map_bo);
+   rrb->map_bo = NULL;
+}
+
 static void *
 radeon_get_pointer(struct gl_context *ctx, struct gl_renderbuffer *rb,
 		   GLint x, GLint y)
@@ -639,6 +731,8 @@ void radeon_fbo_init(struct radeon_context *radeon)
 #if FEATURE_EXT_framebuffer_object
   radeon->glCtx->Driver.NewFramebuffer = radeon_new_framebuffer;
   radeon->glCtx->Driver.NewRenderbuffer = radeon_new_renderbuffer;
+  radeon->glCtx->Driver.MapRenderbuffer = radeon_map_renderbuffer;
+  radeon->glCtx->Driver.UnmapRenderbuffer = radeon_unmap_renderbuffer;
   radeon->glCtx->Driver.BindFramebuffer = radeon_bind_framebuffer;
   radeon->glCtx->Driver.FramebufferRenderbuffer = radeon_framebuffer_renderbuffer;
   radeon->glCtx->Driver.RenderTexture = radeon_render_texture;
-- 
1.7.7



More information about the mesa-dev mailing list