示例#1
0
/**
 * Software fallback for glCopyPixels(GL_STENCIL).
 */
static void
copy_stencil_pixels(struct gl_context *ctx, GLint srcx, GLint srcy,
                    GLsizei width, GLsizei height,
                    GLint dstx, GLint dsty)
{
   struct st_renderbuffer *rbDraw;
   struct pipe_context *pipe = st_context(ctx)->pipe;
   enum pipe_transfer_usage usage;
   struct pipe_transfer *ptDraw;
   ubyte *drawMap;
   ubyte *buffer;
   int i;

   buffer = malloc(width * height * sizeof(ubyte));
   if (!buffer) {
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels(stencil)");
      return;
   }

   /* Get the dest renderbuffer.  If there's a wrapper, use the
    * underlying renderbuffer.
    */
   rbDraw = st_renderbuffer(ctx->DrawBuffer->_StencilBuffer);
   if (rbDraw->Base.Wrapped)
      rbDraw = st_renderbuffer(rbDraw->Base.Wrapped);

   /* this will do stencil pixel transfer ops */
   st_read_stencil_pixels(ctx, srcx, srcy, width, height,
                          GL_STENCIL_INDEX, GL_UNSIGNED_BYTE,
                          &ctx->DefaultPacking, buffer);

   if (0) {
      /* debug code: dump stencil values */
      GLint row, col;
      for (row = 0; row < height; row++) {
         printf("%3d: ", row);
         for (col = 0; col < width; col++) {
            printf("%02x ", buffer[col + row * width]);
         }
         printf("\n");
      }
   }

   if (util_format_get_component_bits(rbDraw->format,
                                     UTIL_FORMAT_COLORSPACE_ZS, 0) != 0)
      usage = PIPE_TRANSFER_READ_WRITE;
   else
      usage = PIPE_TRANSFER_WRITE;

   if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
      dsty = rbDraw->Base.Height - dsty - height;
   }

   ptDraw = pipe_get_transfer(pipe,
                              rbDraw->texture,
                              rbDraw->rtt_level,
                              rbDraw->rtt_face + rbDraw->rtt_slice,
                              usage, dstx, dsty,
                              width, height);

   assert(util_format_get_blockwidth(ptDraw->resource->format) == 1);
   assert(util_format_get_blockheight(ptDraw->resource->format) == 1);

   /* map the stencil buffer */
   drawMap = pipe_transfer_map(pipe, ptDraw);

   /* draw */
   /* XXX PixelZoom not handled yet */
   for (i = 0; i < height; i++) {
      ubyte *dst;
      const ubyte *src;
      int y;

      y = i;

      if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
         y = height - y - 1;
      }

      dst = drawMap + y * ptDraw->stride;
      src = buffer + i * width;

      switch (ptDraw->resource->format) {
      case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
         {
            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++;
            }
         }
         break;
      case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
         {
            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++;
            }
         }
         break;
      case PIPE_FORMAT_S8_USCALED:
         assert(usage == PIPE_TRANSFER_WRITE);
         memcpy(dst, src, width);
         break;
      default:
         assert(0);
      }
   }

   free(buffer);

   /* unmap the stencil buffer */
   pipe_transfer_unmap(pipe, ptDraw);
   pipe->transfer_destroy(pipe, ptDraw);
}
示例#2
0
static void
copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
                    GLsizei width, GLsizei height,
                    GLint dstx, GLint dsty)
{
   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;
   int i;

   buffer = _mesa_malloc(width * height * sizeof(ubyte));
   if (!buffer) {
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels(stencil)");
      return;
   }

   /* this will do stencil pixel transfer ops */
   st_read_stencil_pixels(ctx, srcx, srcy, width, height,
                          GL_STENCIL_INDEX, GL_UNSIGNED_BYTE,
                          &ctx->DefaultPacking, buffer);

   if(pf_get_component_bits( rbDraw->format, PIPE_FORMAT_COMP_Z ) != 0)
      usage = PIPE_TRANSFER_READ_WRITE;
   else
      usage = PIPE_TRANSFER_WRITE;
   
   if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
      dsty = rbDraw->Base.Height - dsty - height;
   }

   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);
   
   /* map the stencil buffer */
   drawMap = screen->transfer_map(screen, ptDraw);

   /* draw */
   /* XXX PixelZoom not handled yet */
   for (i = 0; i < height; i++) {
      ubyte *dst;
      const ubyte *src;
      int y;

      y = i;

      if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
         y = height - y - 1;
      }

      dst = drawMap + y * ptDraw->stride;
      src = buffer + i * width;

      switch (ptDraw->format) {
      case PIPE_FORMAT_S8Z24_UNORM:
         {
            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++;
            }
         }
         break;
      case PIPE_FORMAT_Z24S8_UNORM:
         {
            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++;
            }
         }
         break;
      case PIPE_FORMAT_S8_UNORM:
         assert(usage == PIPE_TRANSFER_WRITE);
         memcpy(dst, src, width);
         break;
      default:
         assert(0);
      }
   }

   _mesa_free(buffer);

   /* unmap the stencil buffer */
   screen->transfer_unmap(screen, ptDraw);
   screen->tex_transfer_destroy(ptDraw);
}