diff options
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/state_tracker/st_cb_drawpixels.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index bb8a083883e..03fc1340e7b 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -40,6 +40,8 @@ #include "st_draw.h" #include "st_program.h" #include "st_cb_drawpixels.h" +#include "st_cb_readpixels.h" +#include "st_cb_fbo.h" #include "st_cb_texture.h" #include "st_draw.h" #include "st_format.h" @@ -1059,6 +1061,78 @@ st_Bitmap(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, static void +copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, + GLsizei width, GLsizei height, + GLint dstx, GLint dsty) +{ + struct st_context *st = ctx->st; + struct pipe_context *pipe = st->pipe; + struct st_renderbuffer *rbRead = st_renderbuffer(ctx->ReadBuffer->_StencilBuffer); + struct st_renderbuffer *rbDraw = st_renderbuffer(ctx->DrawBuffer->_StencilBuffer); + struct pipe_surface *psRead = rbRead->surface; + struct pipe_surface *psDraw = rbDraw->surface; + ubyte *readMap, *drawMap; + ubyte *buffer; + int i; + + buffer = malloc(width * height * sizeof(ubyte)); + if (!buffer) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels(stencil)"); + return; + } + + /* map the stencil buffers */ + readMap = pipe->region_map(pipe, psRead->region); + drawMap = pipe->region_map(pipe, psDraw->region); + + /* this will do stencil pixel transfer ops */ + st_read_stencil_pixels(ctx, srcx, srcy, width, height, GL_UNSIGNED_BYTE, + &ctx->DefaultPacking, buffer); + + /* draw */ + /* XXX PixelZoom not handled yet */ + for (i = 0; i < height; i++) { + ubyte *dst; + const ubyte *src; + int y; + + y = dsty + i; + + if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { + y = ctx->DrawBuffer->Height - y - 1; + } + + dst = drawMap + (y * psDraw->region->pitch + dstx) * psDraw->region->cpp; + src = buffer + i * width; + + switch (psDraw->format) { + case PIPE_FORMAT_S8_Z24: + { + uint *dst4 = (uint *) dst; + int j; + for (j = 0; j < width; j++) { + *dst4 = (*dst4 & 0xffffff) | (src[j] << 24); + dst4++; + } + } + break; + case PIPE_FORMAT_U_S8: + memcpy(dst, src, width); + break; + default: + assert(0); + } + } + + free(buffer); + + /* unmap the stencil buffers */ + pipe->region_unmap(pipe, psRead->region); + pipe->region_unmap(pipe, psDraw->region); +} + + +static void st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, GLsizei width, GLsizei height, GLint dstx, GLint dsty, GLenum type) @@ -1067,6 +1141,11 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, st_validate_state(st); + if (type == GL_STENCIL) { + copy_stencil_pixels(ctx, srcx, srcy, width, height, dstx, dsty); + return; + } + /* allocate a texture of size width x height */ /* blit/copy framebuffer region into texture */ |