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 <brianp@vmware.com>
This commit is contained in:
Eric Anholt
2011-10-13 12:02:43 -07:00
parent a25a452fbe
commit 76d1275474
6 changed files with 127 additions and 4 deletions

View File

@@ -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;

View File

@@ -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[] = {

View File

@@ -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;

View File

@@ -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)
{
}
/**********************************************************************/
/**********************************************************************/

View File

@@ -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);

View File

@@ -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;