Beispiel #1
0
static GLboolean
_mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS)
{
   GLint img, row;
   const GLint srcRowStride
      = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
      / sizeof(uint64_t);

   assert(dstFormat == MESA_FORMAT_Z32_FLOAT_S8X24_UINT);
   assert(srcFormat == GL_DEPTH_STENCIL ||
          srcFormat == GL_DEPTH_COMPONENT ||
          srcFormat == GL_STENCIL_INDEX);
   assert(srcFormat != GL_DEPTH_STENCIL ||
          srcType == GL_UNSIGNED_INT_24_8 ||
          srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);

   /* In case we only upload depth we need to preserve the stencil */
   for (img = 0; img < srcDepth; img++) {
      uint64_t *dstRow = (uint64_t *) dstSlices[img];
      const uint64_t *src
         = (const uint64_t *) _mesa_image_address(dims, srcPacking, srcAddr,
               srcWidth, srcHeight,
               srcFormat, srcType,
               img, 0, 0);
      for (row = 0; row < srcHeight; row++) {
         /* The unpack functions with:
          *    dstType = GL_FLOAT_32_UNSIGNED_INT_24_8_REV
          * only write their own dword, so the other dword (stencil
          * or depth) is preserved. */
         if (srcFormat != GL_STENCIL_INDEX)
            _mesa_unpack_depth_span(ctx, srcWidth,
                                    GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */
                                    dstRow, /* dst addr */
                                    ~0U, srcType, src, srcPacking);

         if (srcFormat != GL_DEPTH_COMPONENT)
            _mesa_unpack_stencil_span(ctx, srcWidth,
                                      GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */
                                      dstRow, /* dst addr */
                                      srcType, src, srcPacking,
                                      ctx->_ImageTransferState);

         src += srcRowStride;
         dstRow += dstRowStride / sizeof(uint64_t);
      }
   }
   return GL_TRUE;
}
Beispiel #2
0
/**
 * Store simple 8-bit/value stencil texture data.
 */
static GLboolean
_mesa_texstore_s8(TEXSTORE_PARAMS)
{
   assert(dstFormat == MESA_FORMAT_S_UINT8);
   assert(srcFormat == GL_STENCIL_INDEX);

   {
      const GLint srcRowStride
	 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
      GLint img, row;
      GLubyte *stencil = malloc(srcWidth * sizeof(GLubyte));

      if (!stencil)
         return GL_FALSE;

      for (img = 0; img < srcDepth; img++) {
         GLubyte *dstRow = dstSlices[img];
         const GLubyte *src
            = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
                                                   srcWidth, srcHeight,
                                                   srcFormat, srcType,
                                                   img, 0, 0);
         for (row = 0; row < srcHeight; row++) {
            GLint i;

            /* get the 8-bit stencil values */
            _mesa_unpack_stencil_span(ctx, srcWidth,
                                      GL_UNSIGNED_BYTE, /* dst type */
                                      stencil, /* dst addr */
                                      srcType, src, srcPacking,
                                      ctx->_ImageTransferState);
            /* merge stencil values into depth values */
            for (i = 0; i < srcWidth; i++)
               dstRow[i] = stencil[i];

            src += srcRowStride;
            dstRow += dstRowStride / sizeof(GLubyte);
         }
      }

      free(stencil);
   }

   return GL_TRUE;
}
Beispiel #3
0
/*
 * Draw stencil image.
 */
static void
draw_stencil_pixels( struct gl_context *ctx, GLint x, GLint y,
                     GLsizei width, GLsizei height,
                     GLenum type,
                     const struct gl_pixelstore_attrib *unpack,
                     const GLvoid *pixels )
{
   const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
   const GLenum destType = GL_UNSIGNED_BYTE;
   GLint row;
   GLubyte *values;

   values = malloc(width * sizeof(GLubyte));
   if (!values) {
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
      return;
   }

   for (row = 0; row < height; row++) {
      const GLvoid *source = _mesa_image_address2d(unpack, pixels,
                                                   width, height,
                                                   GL_STENCIL_INDEX, type,
                                                   row, 0);
      _mesa_unpack_stencil_span(ctx, width, destType, values,
                                type, source, unpack,
                                ctx->_ImageTransferState);
      if (zoom) {
         _swrast_write_zoomed_stencil_span(ctx, x, y, width,
                                           x, y, values);
      }
      else {
         _swrast_write_stencil_span(ctx, width, x, y, values);
      }

      y++;
   }

   free(values);
}
Beispiel #4
0
/*
 * Draw stencil image.
 */
static void
draw_stencil_pixels( GLcontext *ctx, GLint x, GLint y,
                     GLsizei width, GLsizei height,
                     GLenum type,
                     const struct gl_pixelstore_attrib *unpack,
                     const GLvoid *pixels )
{
   const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
   GLint skipPixels;

   /* if width > MAX_WIDTH, have to process image in chunks */
   skipPixels = 0;
   while (skipPixels < width) {
      const GLint spanX = x + skipPixels;
      const GLint spanWidth = MIN2(width - skipPixels, MAX_WIDTH);
      GLint row;
      for (row = 0; row < height; row++) {
         const GLint spanY = y + row;
         GLstencil values[MAX_WIDTH];
         GLenum destType = (sizeof(GLstencil) == sizeof(GLubyte))
                         ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT;
         const GLvoid *source = _mesa_image_address2d(unpack, pixels,
                                                      width, height,
                                                      GL_COLOR_INDEX, type,
                                                      row, skipPixels);
         _mesa_unpack_stencil_span(ctx, spanWidth, destType, values,
                                   type, source, unpack,
                                   ctx->_ImageTransferState);
         if (zoom) {
            _swrast_write_zoomed_stencil_span(ctx, x, y, spanWidth,
                                              spanX, spanY, values);
         }
         else {
            _swrast_write_stencil_span(ctx, spanWidth, spanX, spanY, values);
         }
      }
      skipPixels += spanWidth;
   }
}
Beispiel #5
0
/**
 * Software fallback to do glDrawPixels(GL_STENCIL_INDEX) when we
 * can't use a fragment shader to write stencil values.
 */
static void
draw_stencil_pixels(struct gl_context *ctx, GLint x, GLint y,
                    GLsizei width, GLsizei height, GLenum format, GLenum type,
                    const struct gl_pixelstore_attrib *unpack,
                    const GLvoid *pixels)
{
   struct st_context *st = st_context(ctx);
   struct pipe_context *pipe = st->pipe;
   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;
   struct gl_pixelstore_attrib clippedUnpack = *unpack;

   if (!zoom) {
      if (!_mesa_clip_drawpixels(ctx, &x, &y, &width, &height,
                                 &clippedUnpack)) {
         /* totally clipped */
         return;
      }
   }

   strb = st_renderbuffer(ctx->DrawBuffer->
                          Attachment[BUFFER_STENCIL].Renderbuffer);

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

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

   pt = pipe_get_transfer(pipe, strb->texture,
                          strb->rtt_level, strb->rtt_face + strb->rtt_slice,
                          usage, x, y,
                          width, height);

   stmap = pipe_transfer_map(pipe, pt);

   pixels = _mesa_map_pbo_source(ctx, &clippedUnpack, pixels);
   assert(pixels);

   /* if width > MAX_WIDTH, have to process image in chunks */
   skipPixels = 0;
   while (skipPixels < width) {
      const GLint spanX = skipPixels;
      const GLint spanWidth = MIN2(width - skipPixels, MAX_WIDTH);
      GLint row;
      for (row = 0; row < height; row++) {
         GLubyte sValues[MAX_WIDTH];
         GLuint zValues[MAX_WIDTH];
         GLenum destType = GL_UNSIGNED_BYTE;
         const GLvoid *source = _mesa_image_address2d(&clippedUnpack, pixels,
                                                      width, height,
                                                      format, type,
                                                      row, skipPixels);
         _mesa_unpack_stencil_span(ctx, spanWidth, destType, sValues,
                                   type, source, &clippedUnpack,
                                   ctx->_ImageTransferState);

         if (format == GL_DEPTH_STENCIL) {
            _mesa_unpack_depth_span(ctx, spanWidth, GL_UNSIGNED_INT, zValues,
                                    (1 << 24) - 1, type, source,
                                    &clippedUnpack);
         }

         if (zoom) {
            _mesa_problem(ctx, "Gallium glDrawPixels(GL_STENCIL) with "
                          "zoom not complete");
         }

         {
            GLint spanY;

            if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
               spanY = height - row - 1;
            }
            else {
               spanY = row;
            }

            /* now pack the stencil (and Z) values in the dest format */
            switch (pt->resource->format) {
            case PIPE_FORMAT_S8_USCALED:
               {
                  ubyte *dest = stmap + spanY * pt->stride + spanX;
                  assert(usage == PIPE_TRANSFER_WRITE);
                  memcpy(dest, sValues, spanWidth);
               }
               break;
            case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
               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);
                  }
               }
               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);
                  }
               }
               break;
            case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
               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] << 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);
                  }
               }
               break;
            default:
               assert(0);
            }
         }
      }
      skipPixels += spanWidth;
   }

   _mesa_unmap_pbo_source(ctx, &clippedUnpack);

   /* unmap the stencil buffer */
   pipe_transfer_unmap(pipe, pt);
   pipe->transfer_destroy(pipe, pt);
}
Beispiel #6
0
/**
 * Store a combined depth/stencil texture image.
 */
static GLboolean
_mesa_texstore_s8_z24(TEXSTORE_PARAMS)
{
   const GLuint depthScale = 0xffffff;
   const GLint srcRowStride
      = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
   GLint img, row;
   GLuint *depth;
   GLubyte *stencil;

   assert(dstFormat == MESA_FORMAT_Z24_UNORM_S8_UINT);
   assert(srcFormat == GL_DEPTH_STENCIL_EXT ||
          srcFormat == GL_DEPTH_COMPONENT ||
          srcFormat == GL_STENCIL_INDEX);
   assert(srcFormat != GL_DEPTH_STENCIL_EXT ||
          srcType == GL_UNSIGNED_INT_24_8_EXT ||
          srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);

   depth = malloc(srcWidth * sizeof(GLuint));
   stencil = malloc(srcWidth * sizeof(GLubyte));

   if (!depth || !stencil) {
      free(depth);
      free(stencil);
      return GL_FALSE;
   }

   for (img = 0; img < srcDepth; img++) {
      GLuint *dstRow = (GLuint *) dstSlices[img];
      const GLubyte *src
	 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
						srcWidth, srcHeight,
						srcFormat, srcType,
						img, 0, 0);
      for (row = 0; row < srcHeight; row++) {
	 GLint i;
	 GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE;
	 
	 if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */
	    keepstencil = GL_TRUE;
	 }
         else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */
	    keepdepth = GL_TRUE;
	 }

	 if (keepdepth == GL_FALSE)
	    /* the 24 depth bits will be in the low position: */
	    _mesa_unpack_depth_span(ctx, srcWidth,
				    GL_UNSIGNED_INT, /* dst type */
				    keepstencil ? depth : dstRow, /* dst addr */
				    depthScale,
				    srcType, src, srcPacking);	 

	 if (keepstencil == GL_FALSE)
	    /* get the 8-bit stencil values */
	    _mesa_unpack_stencil_span(ctx, srcWidth,
				      GL_UNSIGNED_BYTE, /* dst type */
				      stencil, /* dst addr */
				      srcType, src, srcPacking,
				      ctx->_ImageTransferState);

	 /* merge stencil values into depth values */
	 for (i = 0; i < srcWidth; i++) {
	    if (keepstencil)
	       dstRow[i] = depth[i] | (dstRow[i] & 0xFF000000);
	    else
	       dstRow[i] = (dstRow[i] & 0xFFFFFF) | (stencil[i] << 24);

	 }
	 src += srcRowStride;
	 dstRow += dstRowStride / sizeof(GLuint);
      }
   }

   free(depth);
   free(stencil);

   return GL_TRUE;
}