diff options
Diffstat (limited to 'src/mesa/state_tracker/st_cb_drawpixels.c')
-rw-r--r-- | src/mesa/state_tracker/st_cb_drawpixels.c | 112 |
1 files changed, 84 insertions, 28 deletions
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index ebb1d1142a..2027b713ce 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -53,6 +53,8 @@ #include "st_format.h" #include "st_mesa_to_tgsi.h" #include "st_texture.h" +#include "st_inlines.h" + #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_inlines.h" @@ -144,6 +146,8 @@ combined_drawpix_fragment_program(GLcontext *ctx) st->pixel_xfer.xfer_prog_sn = st->pixel_xfer.program->serialNo; st->pixel_xfer.user_prog_sn = st->fp->serialNo; st->pixel_xfer.combined_prog_sn = stfp->serialNo; + /* can't reference new program directly, already have a reference on it */ + st_reference_fragprog(st, &st->pixel_xfer.combined_prog, NULL); st->pixel_xfer.combined_prog = stfp; } @@ -351,8 +355,7 @@ make_texture(struct st_context *st, if (!pixels) return NULL; - pt = st_texture_create(st, PIPE_TEXTURE_2D, pipeFormat, 0, width, height, - 1, 0, + pt = st_texture_create(st, PIPE_TEXTURE_2D, pipeFormat, 0, width, height, 1, PIPE_TEXTURE_USAGE_SAMPLER); if (!pt) { _mesa_unmap_drawpix_pbo(ctx, unpack); @@ -369,9 +372,9 @@ make_texture(struct st_context *st, /* we'll do pixel transfer in a fragment shader */ ctx->_ImageTransferState = 0x0; - transfer = screen->get_tex_transfer(screen, pt, 0, 0, 0, - PIPE_TRANSFER_WRITE, 0, 0, - width, height); + transfer = st_no_flush_get_tex_transfer(st, pt, 0, 0, 0, + PIPE_TRANSFER_WRITE, 0, 0, + width, height); /* map texture transfer */ dest = screen->transfer_map(screen, transfer); @@ -491,7 +494,7 @@ draw_quad(GLcontext *ctx, GLfloat x0, GLfloat y0, GLfloat z, /* allocate/load buffer object with vertex data */ buf = pipe_buffer_create(pipe->screen, 32, PIPE_BUFFER_USAGE_VERTEX, sizeof(verts)); - pipe_buffer_write(pipe->screen, buf, 0, sizeof(verts), verts); + st_no_flush_pipe_buffer_write(st, buf, 0, sizeof(verts), verts); util_draw_vertex_buffer(pipe, buf, 0, PIPE_PRIM_QUADS, @@ -627,13 +630,12 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, struct pipe_context *pipe = st->pipe; struct pipe_screen *screen = pipe->screen; struct st_renderbuffer *strb; + enum pipe_transfer_usage usage; struct pipe_transfer *pt; const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0; GLint skipPixels; ubyte *stmap; - pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); - strb = st_renderbuffer(ctx->DrawBuffer-> Attachment[BUFFER_STENCIL].Renderbuffer); @@ -641,9 +643,15 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, y = ctx->DrawBuffer->Height - y - height; } - pt = screen->get_tex_transfer(screen, strb->texture, 0, 0, 0, - PIPE_TRANSFER_WRITE, x, y, - width, height); + if(format != GL_DEPTH_STENCIL && + pf_get_component_bits( strb->format, PIPE_FORMAT_COMP_Z ) != 0) + usage = PIPE_TRANSFER_READ_WRITE; + else + usage = PIPE_TRANSFER_WRITE; + + pt = st_cond_flush_get_tex_transfer(st_context(ctx), strb->texture, 0, 0, 0, + usage, x, y, + width, height); stmap = screen->transfer_map(screen, pt); @@ -693,6 +701,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, case PIPE_FORMAT_S8_UNORM: { ubyte *dest = stmap + spanY * pt->stride + spanX; + assert(usage == PIPE_TRANSFER_WRITE); memcpy(dest, sValues, spanWidth); } break; @@ -700,6 +709,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, if (format == GL_DEPTH_STENCIL) { uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4); GLint k; + assert(usage == PIPE_TRANSFER_WRITE); for (k = 0; k < spanWidth; k++) { dest[k] = zValues[k] | (sValues[k] << 24); } @@ -707,6 +717,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, else { uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4); GLint k; + assert(usage == PIPE_TRANSFER_READ_WRITE); for (k = 0; k < spanWidth; k++) { dest[k] = (dest[k] & 0xffffff) | (sValues[k] << 24); } @@ -716,13 +727,15 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, if (format == GL_DEPTH_STENCIL) { uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4); GLint k; + assert(usage == PIPE_TRANSFER_WRITE); for (k = 0; k < spanWidth; k++) { - dest[k] = zValues[k] | (sValues[k] << 24); + dest[k] = (zValues[k] << 8) | (sValues[k] & 0xff); } } else { uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4); GLint k; + assert(usage == PIPE_TRANSFER_READ_WRITE); for (k = 0; k < spanWidth; k++) { dest[k] = (dest[k] & 0xffffff00) | (sValues[k] & 0xff); } @@ -756,7 +769,6 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, struct st_vertex_program *stvp; struct st_context *st = ctx->st; struct pipe_surface *ps; - GLuint bufferFormat; const GLfloat *color; if (format == GL_STENCIL_INDEX || @@ -784,8 +796,6 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, color = NULL; } - bufferFormat = ps->format; - /* draw with textured quad */ { struct pipe_texture *pt @@ -810,6 +820,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, { struct st_renderbuffer *rbDraw = st_renderbuffer(ctx->DrawBuffer->_StencilBuffer); struct pipe_screen *screen = ctx->st->pipe->screen; + enum pipe_transfer_usage usage; struct pipe_transfer *ptDraw; ubyte *drawMap; ubyte *buffer; @@ -826,9 +837,15 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, &ctx->DefaultPacking, buffer); - ptDraw = screen->get_tex_transfer(screen, rbDraw->texture, 0, 0, 0, - PIPE_TRANSFER_WRITE, dstx, dsty, - width, height); + if(pf_get_component_bits( rbDraw->format, PIPE_FORMAT_COMP_Z ) != 0) + usage = PIPE_TRANSFER_READ_WRITE; + else + usage = PIPE_TRANSFER_WRITE; + + ptDraw = st_cond_flush_get_tex_transfer(st_context(ctx), + rbDraw->texture, 0, 0, 0, + usage, dstx, dsty, + width, height); assert(ptDraw->block.width == 1); assert(ptDraw->block.height == 1); @@ -857,6 +874,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, { uint *dst4 = (uint *) dst; int j; + assert(usage == PIPE_TRANSFER_READ_WRITE); for (j = 0; j < width; j++) { *dst4 = (*dst4 & 0xffffff) | (src[j] << 24); dst4++; @@ -867,6 +885,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, { uint *dst4 = (uint *) dst; int j; + assert(usage == PIPE_TRANSFER_READ_WRITE); for (j = 0; j < width; j++) { *dst4 = (*dst4 & 0xffffff00) | (src[j] & 0xff); dst4++; @@ -874,6 +893,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, } break; case PIPE_FORMAT_S8_UNORM: + assert(usage == PIPE_TRANSFER_WRITE); memcpy(dst, src, width); break; default: @@ -904,11 +924,38 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, GLfloat *color; enum pipe_format srcFormat, texFormat; - /* make sure rendering has completed */ pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); st_validate_state(st); + if (srcx < 0) { + width -= -srcx; + dstx += -srcx; + srcx = 0; + } + + if (srcy < 0) { + height -= -srcy; + dsty += -srcy; + srcy = 0; + } + + if (dstx < 0) { + width -= -dstx; + srcx += -dstx; + dstx = 0; + } + + if (dsty < 0) { + height -= -dsty; + srcy += -dsty; + dsty = 0; + } + + if (width < 0 || height < 0) + return; + + if (type == GL_STENCIL) { /* can't use texturing to do stencil */ copy_stencil_pixels(ctx, srcx, srcy, width, height, dstx, dsty); @@ -950,15 +997,24 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, } } + if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { + srcy = ctx->DrawBuffer->Height - srcy - height; + + if (srcy < 0) { + height -= -srcy; + srcy = 0; + } + + if (height < 0) + return; + } + pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, texFormat, 0, - width, height, 1, 0, + width, height, 1, PIPE_TEXTURE_USAGE_SAMPLER); if (!pt) return; - if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { - srcy = ctx->DrawBuffer->Height - srcy - height; - } if (srcFormat == texFormat) { /* copy source framebuffer surface into mipmap/texture */ @@ -978,13 +1034,13 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, else { /* CPU-based fallback/conversion */ struct pipe_transfer *ptRead = - screen->get_tex_transfer(screen, rbRead->texture, 0, 0, 0, - PIPE_TRANSFER_READ, srcx, srcy, width, - height); + st_cond_flush_get_tex_transfer(st, rbRead->texture, 0, 0, 0, + PIPE_TRANSFER_READ, srcx, srcy, width, + height); struct pipe_transfer *ptTex = - screen->get_tex_transfer(screen, pt, 0, 0, 0, PIPE_TRANSFER_WRITE, - 0, 0, width, height); + st_cond_flush_get_tex_transfer(st, pt, 0, 0, 0, PIPE_TRANSFER_WRITE, + 0, 0, width, height); if (type == GL_COLOR) { /* alternate path using get/put_tile() */ |