diff options
author | Brian Paul <[email protected]> | 2012-01-12 11:52:22 -0700 |
---|---|---|
committer | Brian Paul <[email protected]> | 2012-01-12 13:49:15 -0700 |
commit | cb254b75d7d971b3f1baab45a82cedf0bd6c36c4 (patch) | |
tree | d1eac5fb511f01000afb65f8772d0dc6ca69e70d | |
parent | 062a4b601edaaea193397bd5d86fea11ceec04f4 (diff) |
osmesa: fix glReadPixels, etc
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 <[email protected]>
-rw-r--r-- | src/mesa/drivers/osmesa/osmesa.c | 58 |
1 files changed, 57 insertions, 1 deletions
diff --git a/src/mesa/drivers/osmesa/osmesa.c b/src/mesa/drivers/osmesa/osmesa.c index acfe6295667..67d329faf70 100644 --- a/src/mesa/drivers/osmesa/osmesa.c +++ b/src/mesa/drivers/osmesa/osmesa.c @@ -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. */ |