diff options
Diffstat (limited to 'src/mesa/state_tracker/st_cb_drawpixels.c')
-rw-r--r-- | src/mesa/state_tracker/st_cb_drawpixels.c | 100 |
1 files changed, 76 insertions, 24 deletions
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 821ea67ce4..ebb1d1142a 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -309,6 +309,8 @@ _mesa_base_format(GLenum format) switch (format) { case GL_DEPTH_COMPONENT: return GL_DEPTH_COMPONENT; + case GL_DEPTH_STENCIL: + return GL_DEPTH_STENCIL; case GL_STENCIL_INDEX: return GL_STENCIL_INDEX; default: @@ -617,7 +619,7 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, static void draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, - GLsizei width, GLsizei height, GLenum type, + GLsizei width, GLsizei height, GLenum format, GLenum type, const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels) { @@ -634,12 +636,20 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, strb = st_renderbuffer(ctx->DrawBuffer-> Attachment[BUFFER_STENCIL].Renderbuffer); + + if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { + y = ctx->DrawBuffer->Height - y - height; + } + pt = screen->get_tex_transfer(screen, strb->texture, 0, 0, 0, PIPE_TRANSFER_WRITE, x, y, width, height); stmap = screen->transfer_map(screen, pt); + pixels = _mesa_map_drawpix_pbo(ctx, unpack, pixels); + assert(pixels); + /* if width > MAX_WIDTH, have to process image in chunks */ skipPixels = 0; while (skipPixels < width) { @@ -647,42 +657,74 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, const GLint spanWidth = MIN2(width - skipPixels, MAX_WIDTH); GLint row; for (row = 0; row < height; row++) { - GLint spanY = row; - GLubyte values[MAX_WIDTH]; + GLubyte sValues[MAX_WIDTH]; + GLuint zValues[MAX_WIDTH]; GLenum destType = GL_UNSIGNED_BYTE; const GLvoid *source = _mesa_image_address2d(unpack, pixels, width, height, - GL_COLOR_INDEX, type, + format, type, row, skipPixels); - _mesa_unpack_stencil_span(ctx, spanWidth, destType, values, + _mesa_unpack_stencil_span(ctx, spanWidth, destType, sValues, type, source, unpack, ctx->_ImageTransferState); + + if (format == GL_DEPTH_STENCIL) { + _mesa_unpack_depth_span(ctx, spanWidth, GL_UNSIGNED_INT, zValues, + (1 << 24) - 1, type, source, unpack); + } + if (zoom) { - /* - _swrast_write_zoomed_stencil_span(ctx, 0, 0, spanWidth, - spanX, spanY, values); - */ + _mesa_problem(ctx, "Gallium glDrawPixels(GL_STENCIL) with " + "zoom not complete"); } - else { + + { + GLint spanY; + if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { - spanY = height - spanY - 1; + spanY = height - row - 1; + } + else { + spanY = row; } + /* now pack the stencil (and Z) values in the dest format */ switch (pt->format) { case PIPE_FORMAT_S8_UNORM: { ubyte *dest = stmap + spanY * pt->stride + spanX; - memcpy(dest, values, spanWidth); + memcpy(dest, sValues, spanWidth); } break; case PIPE_FORMAT_S8Z24_UNORM: - { + if (format == GL_DEPTH_STENCIL) { uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4); GLint k; for (k = 0; k < spanWidth; k++) { - uint p = dest[k]; - p = (p & 0xffffff) | (values[k] << 24); - dest[k] = p; + dest[k] = zValues[k] | (sValues[k] << 24); + } + } + else { + uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4); + GLint k; + for (k = 0; k < spanWidth; k++) { + dest[k] = (dest[k] & 0xffffff) | (sValues[k] << 24); + } + } + break; + case PIPE_FORMAT_Z24S8_UNORM: + if (format == GL_DEPTH_STENCIL) { + uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4); + GLint k; + for (k = 0; k < spanWidth; k++) { + dest[k] = zValues[k] | (sValues[k] << 24); + } + } + else { + uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4); + GLint k; + for (k = 0; k < spanWidth; k++) { + dest[k] = (dest[k] & 0xffffff00) | (sValues[k] & 0xff); } } break; @@ -694,6 +736,8 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, skipPixels += spanWidth; } + _mesa_unmap_drawpix_pbo(ctx, unpack); + /* unmap the stencil buffer */ screen->transfer_unmap(screen, pt); screen->tex_transfer_destroy(pt); @@ -715,8 +759,10 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLuint bufferFormat; const GLfloat *color; - if (format == GL_STENCIL_INDEX) { - draw_stencil_pixels(ctx, x, y, width, height, type, unpack, pixels); + if (format == GL_STENCIL_INDEX || + format == GL_DEPTH_STENCIL) { + draw_stencil_pixels(ctx, x, y, width, height, format, type, + unpack, pixels); return; } @@ -731,11 +777,6 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, stvp = st_make_passthrough_vertex_shader(ctx->st, GL_TRUE); color = ctx->Current.RasterColor; } - else if (format == GL_STENCIL_INDEX) { - ps = st->state.framebuffer.zsbuf; - /* XXX special case - can't use texture map */ - color = NULL; - } else { ps = st->state.framebuffer.cbufs[0]; stfp = combined_drawpix_fragment_program(ctx); @@ -781,7 +822,8 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, } /* this will do stencil pixel transfer ops */ - st_read_stencil_pixels(ctx, srcx, srcy, width, height, GL_UNSIGNED_BYTE, + st_read_stencil_pixels(ctx, srcx, srcy, width, height, + GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, &ctx->DefaultPacking, buffer); ptDraw = screen->get_tex_transfer(screen, rbDraw->texture, 0, 0, 0, @@ -821,6 +863,16 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, } } break; + case PIPE_FORMAT_Z24S8_UNORM: + { + uint *dst4 = (uint *) dst; + int j; + for (j = 0; j < width; j++) { + *dst4 = (*dst4 & 0xffffff00) | (src[j] & 0xff); + dst4++; + } + } + break; case PIPE_FORMAT_S8_UNORM: memcpy(dst, src, width); break; |