From 76d1275474d7b5ac2f0edf5856ae1c5fc234f0d9 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 13 Oct 2011 12:02:43 -0700 Subject: [PATCH] Add MapRenderbuffer implementations for software drivers. 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. Reviewed-by: Brian Paul --- 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 920271626a9..27ea559b3d3 100644 --- a/src/mesa/drivers/common/driverfuncs.c +++ b/src/mesa/drivers/common/driverfuncs.c @@ -180,6 +180,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 75d25253eb4..bc115e8cf1a 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 bdb52ef26f1..50e6a83d578 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 70011e6b24a..5dd46cc9ad0 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 de471cd6b22..cb0d712ebe6 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 e2b921512f2..83e7a6a039e 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; -- 2.30.2