コード例 #1
0
ファイル: s_zoom.c プロジェクト: GYGit/reactos
/**
 * Zoom/write 32-bit Z values.
 * No per-fragment operations are applied.
 */
void
_swrast_write_zoomed_z_span(struct gl_context *ctx, GLint imgX, GLint imgY,
                            GLint width, GLint spanX, GLint spanY,
                            const GLuint *zVals)
{
   struct gl_renderbuffer *rb =
      ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
   GLuint zoomedVals[MAX_WIDTH];
   GLint x0, x1, y0, y1, y;
   GLint i, zoomedWidth;

   if (!compute_zoomed_bounds(ctx, imgX, imgY, spanX, spanY, width,
                              &x0, &x1, &y0, &y1)) {
      return;  /* totally clipped */
   }

   zoomedWidth = x1 - x0;
   ASSERT(zoomedWidth > 0);
   ASSERT(zoomedWidth <= MAX_WIDTH);

   /* zoom the span horizontally */
   for (i = 0; i < zoomedWidth; i++) {
      GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - spanX;
      ASSERT(j >= 0);
      ASSERT(j < width);
      zoomedVals[i] = zVals[j];
   }

   /* write the zoomed spans */
   for (y = y0; y < y1; y++) {
      GLubyte *dst = _swrast_pixel_address(rb, x0, y);
      _mesa_pack_uint_z_row(rb->Format, zoomedWidth, zoomedVals, dst);
   }
}
コード例 #2
0
ファイル: s_blit.c プロジェクト: venkatarajasekhar/Qt
/**
 * Blit color, depth or stencil with GL_NEAREST filtering.
 */
static void
blit_nearest(struct gl_context *ctx,
             GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
             GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
             GLbitfield buffer)
{
   struct gl_renderbuffer *readRb, *drawRb;

   const GLint srcWidth = ABS(srcX1 - srcX0);
   const GLint dstWidth = ABS(dstX1 - dstX0);
   const GLint srcHeight = ABS(srcY1 - srcY0);
   const GLint dstHeight = ABS(dstY1 - dstY0);

   const GLint srcXpos = MIN2(srcX0, srcX1);
   const GLint srcYpos = MIN2(srcY0, srcY1);
   const GLint dstXpos = MIN2(dstX0, dstX1);
   const GLint dstYpos = MIN2(dstY0, dstY1);

   const GLboolean invertX = (srcX1 < srcX0) ^ (dstX1 < dstX0);
   const GLboolean invertY = (srcY1 < srcY0) ^ (dstY1 < dstY0);
   enum mode {
      DIRECT,
      UNPACK_RGBA_FLOAT,
      UNPACK_Z_FLOAT,
      UNPACK_Z_INT,
      UNPACK_S,
   } mode;
   GLubyte *srcMap, *dstMap;
   GLint srcRowStride, dstRowStride;
   GLint dstRow;

   GLint pixelSize;
   GLvoid *srcBuffer, *dstBuffer;
   GLint prevY = -1;

   typedef void (*resample_func)(GLint srcWidth, GLint dstWidth,
                                 const GLvoid *srcBuffer, GLvoid *dstBuffer,
                                 GLboolean flip);
   resample_func resampleRow;

   switch (buffer) {
   case GL_COLOR_BUFFER_BIT:
      readRb = ctx->ReadBuffer->_ColorReadBuffer;
      drawRb = ctx->DrawBuffer->_ColorDrawBuffers[0];

      if (readRb->Format == drawRb->Format) {
	 mode = DIRECT;
	 pixelSize = _mesa_get_format_bytes(readRb->Format);
      } else {
	 mode = UNPACK_RGBA_FLOAT;
	 pixelSize = 16;
      }

      break;
   case GL_DEPTH_BUFFER_BIT:
      readRb = ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
      drawRb = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;

      /* Note that for depth/stencil, the formats of src/dst must match.  By
       * using the core helpers for pack/unpack, we avoid needing to handle
       * masking for things like DEPTH copies of Z24S8.
       */
      if (readRb->Format == MESA_FORMAT_Z32_FLOAT ||
	  readRb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) {
	 mode = UNPACK_Z_FLOAT;
      } else {
	 mode = UNPACK_Z_INT;
      }
      pixelSize = 4;
      break;
   case GL_STENCIL_BUFFER_BIT:
      readRb = ctx->ReadBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
      drawRb = ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
      mode = UNPACK_S;
      pixelSize = 1;
      break;
   default:
      _mesa_problem(ctx, "unexpected buffer in blit_nearest()");
      return;
   }

   /* choose row resampler */
   switch (pixelSize) {
   case 1:
      resampleRow = resample_row_1;
      break;
   case 2:
      resampleRow = resample_row_2;
      break;
   case 4:
      resampleRow = resample_row_4;
      break;
   case 8:
      resampleRow = resample_row_8;
      break;
   case 16:
      resampleRow = resample_row_16;
      break;
   default:
      _mesa_problem(ctx, "unexpected pixel size (%d) in blit_nearest",
                    pixelSize);
      return;
   }

   if (readRb == drawRb) {
      /* map whole buffer for read/write */
      /* XXX we could be clever and just map the union region of the
       * source and dest rects.
       */
      GLubyte *map;
      GLint rowStride;
      GLint formatSize = _mesa_get_format_bytes(readRb->Format);

      ctx->Driver.MapRenderbuffer(ctx, readRb, 0, 0,
                                  readRb->Width, readRb->Height,
                                  GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
                                  &map, &rowStride);
      if (!map) {
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer");
         return;
      }

      srcMap = map + srcYpos * rowStride + srcXpos * formatSize;
      dstMap = map + dstYpos * rowStride + dstXpos * formatSize;

      /* this handles overlapping copies */
      if (srcY0 < dstY0) {
         /* copy in reverse (top->down) order */
         srcMap += rowStride * (readRb->Height - 1);
         dstMap += rowStride * (readRb->Height - 1);
         srcRowStride = -rowStride;
         dstRowStride = -rowStride;
      }
      else {
         /* copy in normal (bottom->up) order */
         srcRowStride = rowStride;
         dstRowStride = rowStride;
      }
   }
   else {
      /* different src/dst buffers */
      ctx->Driver.MapRenderbuffer(ctx, readRb,
				  srcXpos, srcYpos,
                                  srcWidth, srcHeight,
                                  GL_MAP_READ_BIT, &srcMap, &srcRowStride);
      if (!srcMap) {
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer");
         return;
      }
      ctx->Driver.MapRenderbuffer(ctx, drawRb,
				  dstXpos, dstYpos,
                                  dstWidth, dstHeight,
                                  GL_MAP_WRITE_BIT, &dstMap, &dstRowStride);
      if (!dstMap) {
         ctx->Driver.UnmapRenderbuffer(ctx, readRb);
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer");
         return;
      }
   }

   /* allocate the src/dst row buffers */
   srcBuffer = malloc(pixelSize * srcWidth);
   if (!srcBuffer) {
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT");
      return;
   }
   dstBuffer = malloc(pixelSize * dstWidth);
   if (!dstBuffer) {
      free(srcBuffer);
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT");
      return;
   }

   for (dstRow = 0; dstRow < dstHeight; dstRow++) {
      GLint srcRow = (dstRow * srcHeight) / dstHeight;
      GLubyte *dstRowStart = dstMap + dstRowStride * dstRow;

      ASSERT(srcRow >= 0);
      ASSERT(srcRow < srcHeight);

      if (invertY) {
         srcRow = srcHeight - 1 - srcRow;
      }

      /* get pixel row from source and resample to match dest width */
      if (prevY != srcRow) {
	 GLubyte *srcRowStart = srcMap + srcRowStride * srcRow;

	 switch (mode) {
	 case DIRECT:
	    memcpy(srcBuffer, srcRowStart, pixelSize * srcWidth);
	    break;
	 case UNPACK_RGBA_FLOAT:
	    _mesa_unpack_rgba_row(readRb->Format, srcWidth, srcRowStart,
				  srcBuffer);
	    break;
	 case UNPACK_Z_FLOAT:
	    _mesa_unpack_float_z_row(readRb->Format, srcWidth, srcRowStart,
				     srcBuffer);
	    break;
	 case UNPACK_Z_INT:
	    _mesa_unpack_uint_z_row(readRb->Format, srcWidth, srcRowStart,
				    srcBuffer);
	    break;
	 case UNPACK_S:
	    _mesa_unpack_ubyte_stencil_row(readRb->Format, srcWidth,
					   srcRowStart, srcBuffer);
	    break;
	 }

         (*resampleRow)(srcWidth, dstWidth, srcBuffer, dstBuffer, invertX);
         prevY = srcRow;
      }

      /* store pixel row in destination */
      switch (mode) {
      case DIRECT:
	 memcpy(dstRowStart, dstBuffer, pixelSize * srcWidth);
	 break;
      case UNPACK_RGBA_FLOAT:
	 _mesa_pack_float_rgba_row(drawRb->Format, dstWidth, dstBuffer,
				   dstRowStart);
	 break;
      case UNPACK_Z_FLOAT:
	 _mesa_pack_float_z_row(drawRb->Format, dstWidth, dstBuffer,
				dstRowStart);
	 break;
      case UNPACK_Z_INT:
	 _mesa_pack_uint_z_row(drawRb->Format, dstWidth, dstBuffer,
			       dstRowStart);
	 break;
      case UNPACK_S:
	 _mesa_pack_ubyte_stencil_row(drawRb->Format, dstWidth, dstBuffer,
				      dstRowStart);
	 break;
      }
   }

   free(srcBuffer);
   free(dstBuffer);

   ctx->Driver.UnmapRenderbuffer(ctx, readRb);
   if (drawRb != readRb) {
      ctx->Driver.UnmapRenderbuffer(ctx, drawRb);
   }
}