示例#1
0
文件: xa_context.c 项目: nikai3d/mesa
int
xa_surface_dma(struct xa_context *ctx,
	       struct xa_surface *srf,
	       void *data,
	       unsigned int pitch,
	       int to_surface, struct xa_box *boxes, unsigned int num_boxes)
{
    struct pipe_transfer *transfer;
    void *map;
    int w, h, i;
    enum pipe_transfer_usage transfer_direction;
    struct pipe_context *pipe = ctx->pipe;

    transfer_direction = (to_surface ? PIPE_TRANSFER_WRITE :
			  PIPE_TRANSFER_READ);

    for (i = 0; i < num_boxes; ++i, ++boxes) {
	w = boxes->x2 - boxes->x1;
	h = boxes->y2 - boxes->y1;

	transfer = pipe_get_transfer(pipe, srf->tex, 0, 0,
				     transfer_direction, boxes->x1, boxes->y1,
				     w, h);
	if (!transfer)
	    return -XA_ERR_NORES;

	map = pipe_transfer_map(ctx->pipe, transfer);
	if (!map)
	    goto out_no_map;

	if (to_surface) {
	    util_copy_rect(map, srf->tex->format, transfer->stride,
			   0, 0, w, h, data, pitch, boxes->x1, boxes->y1);
	} else {
	    util_copy_rect(data, srf->tex->format, pitch,
			   boxes->x1, boxes->y1, w, h, map, transfer->stride, 0,
			   0);
	}
	pipe->transfer_unmap(pipe, transfer);
	pipe->transfer_destroy(pipe, transfer);
	if (to_surface)
	    pipe->flush(pipe, &ctx->last_fence);
    }
    return XA_ERR_NONE;
 out_no_map:
    pipe->transfer_destroy(pipe, transfer);
    return -XA_ERR_NORES;
}
示例#2
0
/**
 * Copy 3D box from one place to another.
 * Position and sizes are in pixels.
 */
void
util_copy_box(ubyte * dst,
              enum pipe_format format,
              unsigned dst_stride, unsigned dst_slice_stride,
              unsigned dst_x, unsigned dst_y, unsigned dst_z,
              unsigned width, unsigned height, unsigned depth,
              const ubyte * src,
              int src_stride, unsigned src_slice_stride,
              unsigned src_x, unsigned src_y, unsigned src_z)
{
   unsigned z;
   dst += dst_z * dst_slice_stride;
   src += src_z * src_slice_stride;
   for (z = 0; z < depth; ++z) {
      util_copy_rect(dst,
                     format,
                     dst_stride,
                     dst_x, dst_y,
                     width, height,
                     src,
                     src_stride,
                     src_x, src_y);

      dst += dst_slice_stride;
      src += src_slice_stride;
   }
}
示例#3
0
void
NineSurface9_CopyDefaultToMem( struct NineSurface9 *This,
                               struct NineSurface9 *From )
{
    struct pipe_context *pipe = This->pipe;
    struct pipe_resource *r_src = From->base.resource;
    struct pipe_transfer *transfer;
    struct pipe_box src_box;
    uint8_t *p_dst;
    const uint8_t *p_src;

    assert(This->base.pool == D3DPOOL_SYSTEMMEM &&
           From->base.pool == D3DPOOL_DEFAULT);

    assert(This->desc.Width == From->desc.Width);
    assert(This->desc.Height == From->desc.Height);

    u_box_origin_2d(This->desc.Width, This->desc.Height, &src_box);
    src_box.z = From->layer;

    p_src = pipe->transfer_map(pipe, r_src, From->level,
                               PIPE_TRANSFER_READ,
                               &src_box, &transfer);
    p_dst = NineSurface9_GetSystemMemPointer(This, 0, 0);

    assert (p_src && p_dst);

    util_copy_rect(p_dst, This->base.info.format,
                   This->stride, 0, 0,
                   This->desc.Width, This->desc.Height,
                   p_src,
                   transfer->stride, 0, 0);

    pipe->transfer_unmap(pipe, transfer);
}
示例#4
0
static Bool
ExaDownloadFromScreen(PixmapPtr pPix, int x,  int y, int w,  int h, char *dst,
		      int dst_pitch)
{
    ScreenPtr pScreen = pPix->drawable.pScreen;
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
    modesettingPtr ms = modesettingPTR(pScrn);
    struct exa_context *exa = ms->exa;
    struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPix);
    struct pipe_transfer *transfer;

    if (!priv || !priv->tex)
	return FALSE;

    transfer = pipe_get_transfer(exa->pipe, priv->tex, 0, 0,
                                 PIPE_TRANSFER_READ, x, y, w, h);
    if (!transfer)
	return FALSE;

    exa_debug_printf("------ ExaDownloadFromScreen(%d, %d, %d, %d, %d)\n",
                 x, y, w, h, dst_pitch);

    util_copy_rect((unsigned char*)dst, priv->tex->format, dst_pitch, 0, 0,
		   w, h, exa->pipe->transfer_map(exa->pipe, transfer),
		   transfer->stride, 0, 0);

    exa->pipe->transfer_unmap(exa->pipe, transfer);
    exa->pipe->transfer_destroy(exa->pipe, transfer);

    return TRUE;
}
示例#5
0
static Bool
ExaUploadToScreen(PixmapPtr pPix, int x, int y, int w, int h, char *src,
		  int src_pitch)
{
    ScreenPtr pScreen = pPix->drawable.pScreen;
    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
    modesettingPtr ms = modesettingPTR(pScrn);
    struct exa_context *exa = ms->exa;
    struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPix);
    struct pipe_transfer *transfer;
    void *map;

    if (!priv || !priv->tex)
	return FALSE;

    map = pipe_transfer_map(exa->pipe, priv->tex, 0, 0,
                            PIPE_TRANSFER_WRITE, x, y, w, h, &transfer);
    if (!map)
	return FALSE;

    exa_debug_printf("++++++ ExaUploadToScreen(%d, %d, %d, %d, %d)\n",
                 x, y, w, h, src_pitch);

    util_copy_rect(map,
		   priv->tex->format, transfer->stride, 0, 0, w, h,
		   (unsigned char*)src, src_pitch, 0, 0);

    exa->pipe->transfer_unmap(exa->pipe, transfer);

    return TRUE;
}
示例#6
0
/* One-shot transfer operation with data supplied in a user
 * pointer.  XXX: strides??
 */
void u_default_transfer_inline_write( struct pipe_context *pipe,
                                      struct pipe_resource *resource,
                                      unsigned level,
                                      unsigned usage,
                                      const struct pipe_box *box,
                                      const void *data,
                                      unsigned stride,
                                      unsigned layer_stride)
{
   struct pipe_transfer *transfer = NULL;
   uint8_t *map = NULL;

   assert(!(usage & PIPE_TRANSFER_READ));

   /* the write flag is implicit by the nature of transfer_inline_write */
   usage |= PIPE_TRANSFER_WRITE;

   /* transfer_inline_write implicitly discards the rewritten buffer range */
   if (box->x == 0 && box->width == resource->width0) {
      usage |= PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE;
   } else {
      usage |= PIPE_TRANSFER_DISCARD_RANGE;
   }

   map = pipe->transfer_map(pipe,
                            resource,
                            level,
                            usage,
                            box, &transfer);
   if (map == NULL)
      return;

   if (resource->target == PIPE_BUFFER) {
      assert(box->height == 1);
      assert(box->depth == 1);

      memcpy(map, data, box->width);
   }
   else {
      const uint8_t *src_data = data;
      unsigned i;

      for (i = 0; i < box->depth; i++) {
         util_copy_rect(map,
                        resource->format,
                        transfer->stride, /* bytes */
                        0, 0,
                        box->width,
                        box->height,
                        src_data,
                        stride,       /* bytes */
                        0, 0);
         map += transfer->layer_stride;
         src_data += layer_stride;
      }
   }

   pipe_transfer_unmap(pipe, transfer);
}
示例#7
0
文件: vid_dec.c 项目: Sheph/mesa
static void vid_dec_FillOutput(vid_dec_PrivateType *priv, struct pipe_video_buffer *buf,
                               OMX_BUFFERHEADERTYPE* output)
{
   omx_base_PortType *port = priv->ports[OMX_BASE_FILTER_OUTPUTPORT_INDEX];
   OMX_VIDEO_PORTDEFINITIONTYPE *def = &port->sPortParam.format.video;

   struct pipe_sampler_view **views;
   struct pipe_transfer *transfer;
   struct pipe_box box = { };
   uint8_t *src, *dst;

   views = buf->get_sampler_view_planes(buf);

   dst = output->pBuffer;

   box.width = def->nFrameWidth;
   box.height = def->nFrameHeight;
   box.depth = 1;

   src = priv->pipe->transfer_map(priv->pipe, views[0]->texture, 0,
                                  PIPE_TRANSFER_READ, &box, &transfer);
   util_copy_rect(dst, views[0]->texture->format, def->nStride, 0, 0,
                  box.width, box.height, src, transfer->stride, 0, 0);
   pipe_transfer_unmap(priv->pipe, transfer);

   dst = ((uint8_t*)output->pBuffer) + (def->nStride * box.height);

   box.width = def->nFrameWidth / 2;
   box.height = def->nFrameHeight / 2;
 
   src = priv->pipe->transfer_map(priv->pipe, views[1]->texture, 0,
                                  PIPE_TRANSFER_READ, &box, &transfer);
   util_copy_rect(dst, views[1]->texture->format, def->nStride, 0, 0,
                  box.width, box.height, src, transfer->stride, 0, 0);
   pipe_transfer_unmap(priv->pipe, transfer);
}
示例#8
0
static void
crtc_load_cursor_argb_ga3d(xf86CrtcPtr crtc, CARD32 * image)
{
    unsigned char *ptr;
    modesettingPtr ms = modesettingPTR(crtc->scrn);
    struct crtc_private *crtcp = crtc->driver_private;
    struct pipe_transfer *transfer;

    if (!crtcp->cursor_tex) {
	struct pipe_resource templat;
	struct winsys_handle whandle;

	memset(&templat, 0, sizeof(templat));
	templat.bind |= PIPE_BIND_RENDER_TARGET;
	templat.bind |= PIPE_BIND_SCANOUT;
	templat.target = PIPE_TEXTURE_2D;
	templat.last_level = 0;
	templat.depth0 = 1;
	templat.array_size = 1;
	templat.format = PIPE_FORMAT_B8G8R8A8_UNORM;
	templat.width0 = 64;
	templat.height0 = 64;

	memset(&whandle, 0, sizeof(whandle));
	whandle.type = DRM_API_HANDLE_TYPE_KMS;

	crtcp->cursor_tex = ms->screen->resource_create(ms->screen,
						       &templat);
	ms->screen->resource_get_handle(ms->screen, crtcp->cursor_tex, &whandle);

	crtcp->cursor_handle = whandle.handle;
    }

    transfer = pipe_get_transfer(ms->ctx, crtcp->cursor_tex,
                                 0, 0,
                                 PIPE_TRANSFER_WRITE,
                                 0, 0, 64, 64);
    ptr = ms->ctx->transfer_map(ms->ctx, transfer);
    util_copy_rect(ptr, crtcp->cursor_tex->format,
		   transfer->stride, 0, 0,
		   64, 64, (void*)image, 64 * 4, 0, 0);
    ms->ctx->transfer_unmap(ms->ctx, transfer);
    ms->ctx->transfer_destroy(ms->ctx, transfer);

    if (crtc->cursor_shown)
	drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id,
			 crtcp->cursor_handle, 64, 64);
}
示例#9
0
static void
upload_sampler(struct pipe_context *pipe, struct pipe_sampler_view *dst,
               const struct pipe_box *dst_box, const void *src, unsigned src_stride,
               unsigned src_x, unsigned src_y)
{
   struct pipe_transfer *transfer;
   void *map;

   map = pipe->transfer_map(pipe, dst->texture, 0, PIPE_TRANSFER_WRITE,
                            dst_box, &transfer);
   if (!map)
      return;

   util_copy_rect(map, dst->texture->format, transfer->stride, 0, 0,
                  dst_box->width, dst_box->height,
                  src, src_stride, src_x, src_y);

   pipe->transfer_unmap(pipe, transfer);
}
示例#10
0
/**
 * Upload data to a rectangular sub-region.  Lots of choices how to do this:
 *
 * - memcpy by span to current destination
 * - upload data as new buffer and blit
 *
 * Currently always memcpy.
 */
static void
st_surface_data(struct pipe_context *pipe,
		struct pipe_transfer *dst,
		unsigned dstx, unsigned dsty,
		const void *src, unsigned src_stride,
		unsigned srcx, unsigned srcy, unsigned width, unsigned height)
{
   void *map = pipe_transfer_map(pipe, dst);

   assert(dst->resource);
   util_copy_rect(map,
                  dst->resource->format,
                  dst->stride,
                  dstx, dsty, 
                  width, height, 
                  src, src_stride, 
                  srcx, srcy);

   pipe_transfer_unmap(pipe, dst);
}
示例#11
0
/**
 * Upload data to a rectangular sub-region.  Lots of choices how to do this:
 *
 * - memcpy by span to current destination
 * - upload data as new buffer and blit
 *
 * Currently always memcpy.
 */
static void
st_surface_data(struct pipe_context *pipe,
		struct pipe_transfer *dst,
		unsigned dstx, unsigned dsty,
		const void *src, unsigned src_stride,
		unsigned srcx, unsigned srcy, unsigned width, unsigned height)
{
   struct pipe_screen *screen = pipe->screen;
   void *map = screen->transfer_map(screen, dst);

   util_copy_rect(map,
                  &dst->block,
                  dst->stride,
                  dstx, dsty, 
                  width, height, 
                  src, src_stride, 
                  srcx, srcy);

   screen->transfer_unmap(screen, dst);
}
/**
 * Copy image data from a VdpOutputSurface to application memory in the
 * surface's native format.
 */
VdpStatus
vlVdpOutputSurfaceGetBitsNative(VdpOutputSurface surface,
                                VdpRect const *source_rect,
                                void *const *destination_data,
                                uint32_t const *destination_pitches)
{
   vlVdpOutputSurface *vlsurface;
   struct pipe_context *pipe;
   struct pipe_resource *res;
   struct pipe_box box;
   struct pipe_transfer *transfer;
   uint8_t *map;

   vlsurface = vlGetDataHTAB(surface);
   if (!vlsurface)
      return VDP_STATUS_INVALID_HANDLE;

   pipe = vlsurface->device->context;
   if (!pipe)
      return VDP_STATUS_INVALID_HANDLE;

   pipe_mutex_lock(vlsurface->device->mutex);
   vlVdpResolveDelayedRendering(vlsurface->device, NULL, NULL);

   res = vlsurface->sampler_view->texture;
   box = RectToPipeBox(source_rect, res);
   map = pipe->transfer_map(pipe, res, 0, PIPE_TRANSFER_READ, &box, &transfer);
   if (!map) {
      pipe_mutex_unlock(vlsurface->device->mutex);
      return VDP_STATUS_RESOURCES;
   }

   util_copy_rect(*destination_data, res->format, *destination_pitches, 0, 0,
                  box.width, box.height, map, transfer->stride, 0, 0);

   pipe_transfer_unmap(pipe, transfer);
   pipe_mutex_unlock(vlsurface->device->mutex);

   return VDP_STATUS_OK;
}
示例#13
0
static Bool
ExaUploadToScreen(PixmapPtr pPix, int x, int y, int w, int h, char *src,
		  int src_pitch)
{
    ScreenPtr pScreen = pPix->drawable.pScreen;
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
    modesettingPtr ms = modesettingPTR(pScrn);
    struct exa_context *exa = ms->exa;
    struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPix);
    struct pipe_transfer *transfer;

    if (!priv || !priv->tex)
	return FALSE;

    /* make sure that any pending operations are flushed to hardware */
    if (exa->pipe->is_texture_referenced(exa->pipe, priv->tex, 0, 0) &
	(PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE))
	xorg_exa_flush(exa, 0, NULL);

    transfer = exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
					   PIPE_TRANSFER_WRITE, x, y, w, h);
    if (!transfer)
	return FALSE;

#if DEBUG_PRINT
    debug_printf("++++++ ExaUploadToScreen(%d, %d, %d, %d, %d)\n",
                 x, y, w, h, src_pitch);
#endif

    util_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer),
		   priv->tex->format, transfer->stride, 0, 0, w, h,
		   (unsigned char*)src, src_pitch, 0, 0);

    exa->scrn->transfer_unmap(exa->scrn, transfer);
    exa->scrn->tex_transfer_destroy(transfer);

    return TRUE;
}
示例#14
0
文件: vid_dec.c 项目: chemecse/mesa
static void vid_dec_FillOutput(vid_dec_PrivateType *priv, struct pipe_video_buffer *buf,
                               OMX_BUFFERHEADERTYPE* output)
{
   omx_base_PortType *port = priv->ports[OMX_BASE_FILTER_OUTPUTPORT_INDEX];
   OMX_VIDEO_PORTDEFINITIONTYPE *def = &port->sPortParam.format.video;

   struct pipe_sampler_view **views;
   unsigned i, j;
   unsigned width, height;

   views = buf->get_sampler_view_planes(buf);

   for (i = 0; i < 2 /* NV12 */; i++) {
      if (!views[i]) continue;
      width = def->nFrameWidth;
      height = def->nFrameHeight;
      vl_video_buffer_adjust_size(&width, &height, i, buf->chroma_format, buf->interlaced);
      for (j = 0; j < views[i]->texture->array_size; ++j) {
         struct pipe_box box = {0, 0, j, width, height, 1};
         struct pipe_transfer *transfer;
         uint8_t *map, *dst;
         map = priv->pipe->transfer_map(priv->pipe, views[i]->texture, 0,
                  PIPE_TRANSFER_READ, &box, &transfer);
         if (!map)
            return;

         dst = ((uint8_t*)output->pBuffer + output->nOffset) + j * def->nStride +
               i * def->nFrameWidth * def->nFrameHeight;
         util_copy_rect(dst,
            views[i]->texture->format,
            def->nStride * views[i]->texture->array_size, 0, 0,
            box.width, box.height, map, transfer->stride, 0, 0);

         pipe_transfer_unmap(priv->pipe, transfer);
      }
   }
}
示例#15
0
文件: surface9.c 项目: alesegdia/mesa
HRESULT
NineSurface9_CopySurface( struct NineSurface9 *This,
                          struct NineSurface9 *From,
                          const POINT *pDestPoint,
                          const RECT *pSourceRect )
{
    struct pipe_context *pipe = This->pipe;
    struct pipe_resource *r_dst = This->base.resource;
    struct pipe_resource *r_src = From->base.resource;
    struct pipe_transfer *transfer;
    struct pipe_box src_box;
    struct pipe_box dst_box;
    uint8_t *p_dst;
    const uint8_t *p_src;

    DBG("This=%p From=%p pDestPoint=%p pSourceRect=%p\n",
        This, From, pDestPoint, pSourceRect);

    assert(This->base.pool != D3DPOOL_MANAGED &&
           From->base.pool != D3DPOOL_MANAGED);

    user_assert(This->desc.Format == From->desc.Format, D3DERR_INVALIDCALL);

    dst_box.x = pDestPoint ? pDestPoint->x : 0;
    dst_box.y = pDestPoint ? pDestPoint->y : 0;

    user_assert(dst_box.x >= 0 &&
                dst_box.y >= 0, D3DERR_INVALIDCALL);

    dst_box.z = This->layer;
    src_box.z = From->layer;

    dst_box.depth = 1;
    src_box.depth = 1;

    if (pSourceRect) {
        /* make sure it doesn't range outside the source surface */
        user_assert(pSourceRect->left >= 0 &&
                    pSourceRect->right <= From->desc.Width &&
                    pSourceRect->top >= 0 &&
                    pSourceRect->bottom <= From->desc.Height,
                    D3DERR_INVALIDCALL);
        if (rect_to_pipe_box_xy_only_clamp(&src_box, pSourceRect))
            return D3D_OK;
    } else {
        src_box.x = 0;
        src_box.y = 0;
        src_box.width = From->desc.Width;
        src_box.height = From->desc.Height;
    }

    /* limits */
    dst_box.width = This->desc.Width - dst_box.x;
    dst_box.height = This->desc.Height - dst_box.y;

    user_assert(src_box.width <= dst_box.width &&
                src_box.height <= dst_box.height, D3DERR_INVALIDCALL);

    dst_box.width = src_box.width;
    dst_box.height = src_box.height;

    /* check source block align for compressed textures */
    if (util_format_is_compressed(From->base.info.format) &&
        ((src_box.width != From->desc.Width) ||
         (src_box.height != From->desc.Height))) {
        const unsigned w = util_format_get_blockwidth(From->base.info.format);
        const unsigned h = util_format_get_blockheight(From->base.info.format);
        user_assert(!(src_box.width % w) &&
                    !(src_box.height % h),
                    D3DERR_INVALIDCALL);
    }

    /* check destination block align for compressed textures */
    if (util_format_is_compressed(This->base.info.format) &&
        ((dst_box.width != This->desc.Width) ||
         (dst_box.height != This->desc.Height) ||
         dst_box.x != 0 ||
         dst_box.y != 0)) {
        const unsigned w = util_format_get_blockwidth(This->base.info.format);
        const unsigned h = util_format_get_blockheight(This->base.info.format);
        user_assert(!(dst_box.x % w) && !(dst_box.width % w) &&
                    !(dst_box.y % h) && !(dst_box.height % h),
                    D3DERR_INVALIDCALL);
    }

    if (r_dst && r_src) {
        pipe->resource_copy_region(pipe,
                                   r_dst, This->level,
                                   dst_box.x, dst_box.y, dst_box.z,
                                   r_src, From->level,
                                   &src_box);
    } else
    if (r_dst) {
        p_src = NineSurface9_GetSystemMemPointer(From, src_box.x, src_box.y);

        pipe->transfer_inline_write(pipe, r_dst, This->level,
                                    0, /* WRITE|DISCARD are implicit */
                                    &dst_box, p_src, From->stride, 0);
    } else
    if (r_src) {
        p_dst = NineSurface9_GetSystemMemPointer(This, 0, 0);

        p_src = pipe->transfer_map(pipe, r_src, From->level,
                                   PIPE_TRANSFER_READ,
                                   &src_box, &transfer);
        if (!p_src)
            return D3DERR_DRIVERINTERNALERROR;

        util_copy_rect(p_dst, This->base.info.format,
                       This->stride, dst_box.x, dst_box.y,
                       dst_box.width, dst_box.height,
                       p_src,
                       transfer->stride, src_box.x, src_box.y);

        pipe->transfer_unmap(pipe, transfer);
    } else {
        p_dst = NineSurface9_GetSystemMemPointer(This, 0, 0);
        p_src = NineSurface9_GetSystemMemPointer(From, 0, 0);

        util_copy_rect(p_dst, This->base.info.format,
                       This->stride, dst_box.x, dst_box.y,
                       dst_box.width, dst_box.height,
                       p_src,
                       From->stride, src_box.x, src_box.y);
    }

    if (This->base.pool == D3DPOOL_DEFAULT)
        NineSurface9_MarkContainerDirty(This);
    if (!r_dst && This->base.resource)
        NineSurface9_AddDirtyRect(This, &dst_box);

    return D3D_OK;
}
示例#16
0
/**
 * Fallback function for pipe->surface_copy().
 * Note: (X,Y)=(0,0) is always the upper-left corner.
 * if do_flip, flip the image vertically on its way from src rect to dst rect.
 * XXX should probably put this in new u_surface.c file...
 */
void
util_surface_copy(struct pipe_context *pipe,
                  boolean do_flip,
                  struct pipe_surface *dst,
                  unsigned dst_x, unsigned dst_y,
                  struct pipe_surface *src,
                  unsigned src_x, unsigned src_y, 
                  unsigned w, unsigned h)
{
   struct pipe_screen *screen = pipe->screen;
   struct pipe_transfer *src_trans, *dst_trans;
   void *dst_map;
   const void *src_map;
   enum pipe_format src_format, dst_format;

   assert(src->texture && dst->texture);
   if (!src->texture || !dst->texture)
      return;

   src_format = src->texture->format;
   dst_format = dst->texture->format;

   src_trans = screen->get_tex_transfer(screen,
                                        src->texture,
                                        src->face,
                                        src->level,
                                        src->zslice,
                                        PIPE_TRANSFER_READ,
                                        src_x, src_y, w, h);

   dst_trans = screen->get_tex_transfer(screen,
                                        dst->texture,
                                        dst->face,
                                        dst->level,
                                        dst->zslice,
                                        PIPE_TRANSFER_WRITE,
                                        dst_x, dst_y, w, h);

   assert(util_format_get_blocksize(dst_format) == util_format_get_blocksize(src_format));
   assert(util_format_get_blockwidth(dst_format) == util_format_get_blockwidth(src_format));
   assert(util_format_get_blockheight(dst_format) == util_format_get_blockheight(src_format));

   src_map = pipe->screen->transfer_map(screen, src_trans);
   dst_map = pipe->screen->transfer_map(screen, dst_trans);

   assert(src_map);
   assert(dst_map);

   if (src_map && dst_map) {
      /* If do_flip, invert src_y position and pass negative src stride */
      util_copy_rect(dst_map,
                     dst_format,
                     dst_trans->stride,
                     0, 0,
                     w, h,
                     src_map,
                     do_flip ? -(int) src_trans->stride : src_trans->stride,
                     0,
                     do_flip ? h - 1 : 0);
   }

   pipe->screen->transfer_unmap(pipe->screen, src_trans);
   pipe->screen->transfer_unmap(pipe->screen, dst_trans);

   screen->tex_transfer_destroy(src_trans);
   screen->tex_transfer_destroy(dst_trans);
}
示例#17
0
文件: surface.c 项目: CSRedRat/mesa-1
/**
 * Copy image data from a VdpVideoSurface to application memory in a specified
 * YCbCr format.
 */
VdpStatus
vlVdpVideoSurfaceGetBitsYCbCr(VdpVideoSurface surface,
                              VdpYCbCrFormat destination_ycbcr_format,
                              void *const *destination_data,
                              uint32_t const *destination_pitches)
{
   vlVdpSurface *vlsurface;
   struct pipe_context *pipe;
   enum pipe_format format;
   struct pipe_sampler_view **sampler_views;
   unsigned i, j;

   vlsurface = vlGetDataHTAB(surface);
   if (!vlsurface)
      return VDP_STATUS_INVALID_HANDLE;

   pipe = vlsurface->device->context;
   if (!pipe)
      return VDP_STATUS_INVALID_HANDLE;

   format = FormatYCBCRToPipe(destination_ycbcr_format);
   if (format == PIPE_FORMAT_NONE)
       return VDP_STATUS_INVALID_Y_CB_CR_FORMAT;

   if (vlsurface->video_buffer == NULL || format != vlsurface->video_buffer->buffer_format)
      return VDP_STATUS_NO_IMPLEMENTATION; /* TODO We don't support conversion (yet) */

   pipe_mutex_lock(vlsurface->device->mutex);
   sampler_views = vlsurface->video_buffer->get_sampler_view_planes(vlsurface->video_buffer);
   if (!sampler_views) {
      pipe_mutex_unlock(vlsurface->device->mutex);
      return VDP_STATUS_RESOURCES;
   }

   for (i = 0; i < 3; ++i) {
      unsigned width, height;
      struct pipe_sampler_view *sv = sampler_views[i];
      if (!sv) continue;

      vlVdpVideoSurfaceSize(vlsurface, i, &width, &height);

      for (j = 0; j < sv->texture->array_size; ++j) {
         struct pipe_box box = {
            0, 0, j,
            width, height, 1
         };
         struct pipe_transfer *transfer;
         uint8_t *map;

         map = pipe->transfer_map(pipe, sv->texture, 0,
                                       PIPE_TRANSFER_READ, &box, &transfer);
         if (!map) {
            pipe_mutex_unlock(vlsurface->device->mutex);
            return VDP_STATUS_RESOURCES;
         }

         util_copy_rect(destination_data[i] + destination_pitches[i] * j, sv->texture->format,
                        destination_pitches[i] * sv->texture->array_size, 0, 0,
                        box.width, box.height, map, transfer->stride, 0, 0);

         pipe_transfer_unmap(pipe, transfer);
      }
   }
   pipe_mutex_unlock(vlsurface->device->mutex);

   return VDP_STATUS_OK;
}
示例#18
0
文件: surface.c 项目: Unr34ler/mesa
/**
 * Copy image data from a VdpVideoSurface to application memory in a specified
 * YCbCr format.
 */
VdpStatus
vlVdpVideoSurfaceGetBitsYCbCr(VdpVideoSurface surface,
                              VdpYCbCrFormat destination_ycbcr_format,
                              void *const *destination_data,
                              uint32_t const *destination_pitches)
{
   vlVdpSurface *vlsurface;
   struct pipe_context *pipe;
   enum pipe_format format, buffer_format;
   struct pipe_sampler_view **sampler_views;
   enum getbits_conversion conversion = CONVERSION_NONE;
   unsigned i, j;

   vlsurface = vlGetDataHTAB(surface);
   if (!vlsurface)
      return VDP_STATUS_INVALID_HANDLE;

   pipe = vlsurface->device->context;
   if (!pipe)
      return VDP_STATUS_INVALID_HANDLE;

   if (!destination_data || !destination_pitches)
       return VDP_STATUS_INVALID_POINTER;

   format = FormatYCBCRToPipe(destination_ycbcr_format);
   if (format == PIPE_FORMAT_NONE)
      return VDP_STATUS_INVALID_Y_CB_CR_FORMAT;

   if (vlsurface->video_buffer == NULL)
      return VDP_STATUS_INVALID_VALUE;

   buffer_format = vlsurface->video_buffer->buffer_format;
   if (format != buffer_format) {
      if (format == PIPE_FORMAT_YV12 && buffer_format == PIPE_FORMAT_NV12)
         conversion = CONVERSION_NV12_TO_YV12;
      else if (format == PIPE_FORMAT_NV12 && buffer_format == PIPE_FORMAT_YV12)
         conversion = CONVERSION_YV12_TO_NV12;
      else if ((format == PIPE_FORMAT_YUYV && buffer_format == PIPE_FORMAT_UYVY) ||
               (format == PIPE_FORMAT_UYVY && buffer_format == PIPE_FORMAT_YUYV))
         conversion = CONVERSION_SWAP_YUYV_UYVY;
      else
         return VDP_STATUS_NO_IMPLEMENTATION;
   }

   pipe_mutex_lock(vlsurface->device->mutex);
   sampler_views = vlsurface->video_buffer->get_sampler_view_planes(vlsurface->video_buffer);
   if (!sampler_views) {
      pipe_mutex_unlock(vlsurface->device->mutex);
      return VDP_STATUS_RESOURCES;
   }

   for (i = 0; i < 3; ++i) {
      unsigned width, height;
      struct pipe_sampler_view *sv = sampler_views[i];
      if (!sv) continue;

      vlVdpVideoSurfaceSize(vlsurface, i, &width, &height);

      for (j = 0; j < sv->texture->array_size; ++j) {
         struct pipe_box box = {
            0, 0, j,
            width, height, 1
         };
         struct pipe_transfer *transfer;
         uint8_t *map;

         map = pipe->transfer_map(pipe, sv->texture, 0,
                                       PIPE_TRANSFER_READ, &box, &transfer);
         if (!map) {
            pipe_mutex_unlock(vlsurface->device->mutex);
            return VDP_STATUS_RESOURCES;
         }

         if (conversion == CONVERSION_NV12_TO_YV12 && i == 1) {
            u_copy_nv12_to_yv12(destination_data, destination_pitches,
                                i, j, transfer->stride, sv->texture->array_size,
                                map, box.width, box.height);
         } else if (conversion == CONVERSION_YV12_TO_NV12 && i > 0) {
            u_copy_yv12_to_nv12(destination_data, destination_pitches,
                                i, j, transfer->stride, sv->texture->array_size,
                                map, box.width, box.height);
         } else if (conversion == CONVERSION_SWAP_YUYV_UYVY) {
            u_copy_swap422_packed(destination_data, destination_pitches,
                                   i, j, transfer->stride, sv->texture->array_size,
                                   map, box.width, box.height);
         } else {
            util_copy_rect(destination_data[i] + destination_pitches[i] * j, sv->texture->format,
                           destination_pitches[i] * sv->texture->array_size, 0, 0,
                           box.width, box.height, map, transfer->stride, 0, 0);
         }

         pipe_transfer_unmap(pipe, transfer);
      }
   }
   pipe_mutex_unlock(vlsurface->device->mutex);

   return VDP_STATUS_OK;
}
示例#19
0
static void
lp_resource_copy(struct pipe_context *pipe,
                 struct pipe_resource *dst, unsigned dst_level,
                 unsigned dstx, unsigned dsty, unsigned dstz,
                 struct pipe_resource *src, unsigned src_level,
                 const struct pipe_box *src_box)
{
   /* XXX this used to ignore srcz/dstz
    * assume it works the same for cube and 3d
    */
   struct llvmpipe_resource *src_tex = llvmpipe_resource(src);
   struct llvmpipe_resource *dst_tex = llvmpipe_resource(dst);
   const enum pipe_format format = src_tex->base.format;
   unsigned width = src_box->width;
   unsigned height = src_box->height;
   assert(src_box->depth == 1);

   /* Fallback for buffers. */
   if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) {
      util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz,
                                src, src_level, src_box);
      return;
   }

   llvmpipe_flush_resource(pipe,
                           dst, dst_level, dstz,
                           FALSE, /* read_only */
                           TRUE, /* cpu_access */
                           FALSE, /* do_not_block */
                           "blit dest");

   llvmpipe_flush_resource(pipe,
                           src, src_level, src_box->z,
                           TRUE, /* read_only */
                           TRUE, /* cpu_access */
                           FALSE, /* do_not_block */
                           "blit src");

   /*
   printf("surface copy from %u lvl %u to %u lvl %u: %u,%u,%u to %u,%u,%u %u x %u x %u\n",
          src_tex->id, src_level, dst_tex->id, dst_level, 
          src_box->x, src_box->y, src_box->z, dstx, dsty, dstz,
          src_box->width, src_box->height, src_box->depth);
   */

   /* set src tiles to linear layout */
   {
      unsigned tx, ty, tw, th;
      unsigned x, y;

      adjust_to_tile_bounds(src_box->x, src_box->y, width, height,
                            &tx, &ty, &tw, &th);

      for (y = 0; y < th; y += TILE_SIZE) {
         for (x = 0; x < tw; x += TILE_SIZE) {
            (void) llvmpipe_get_texture_tile_linear(src_tex,
                                                    src_box->z, src_level,
                                                    LP_TEX_USAGE_READ,
                                                    tx + x, ty + y);
         }
      }
   }

   /* set dst tiles to linear layout */
   {
      unsigned tx, ty, tw, th;
      unsigned x, y;
      enum lp_texture_usage usage;

      adjust_to_tile_bounds(dstx, dsty, width, height, &tx, &ty, &tw, &th);

      for (y = 0; y < th; y += TILE_SIZE) {
         boolean contained_y = ty + y >= dsty &&
                               ty + y + TILE_SIZE <= dsty + height ?
                               TRUE : FALSE;

         for (x = 0; x < tw; x += TILE_SIZE) {
            boolean contained_x = tx + x >= dstx &&
                                  tx + x + TILE_SIZE <= dstx + width ?
                                  TRUE : FALSE;

            /*
             * Set the usage mode to WRITE_ALL for the tiles which are
             * completely contained by the dest rectangle.
             */
            if (contained_y && contained_x)
               usage = LP_TEX_USAGE_WRITE_ALL;
            else
               usage = LP_TEX_USAGE_READ_WRITE;

            (void) llvmpipe_get_texture_tile_linear(dst_tex,
                                                    dstz, dst_level,
                                                    usage,
                                                    tx + x, ty + y);
         }
      }
   }

   /* copy */
   {
      const ubyte *src_linear_ptr
         = llvmpipe_get_texture_image_address(src_tex, src_box->z,
                                              src_level,
                                              LP_TEX_LAYOUT_LINEAR);
      ubyte *dst_linear_ptr
         = llvmpipe_get_texture_image_address(dst_tex, dstz,
                                              dst_level,
                                              LP_TEX_LAYOUT_LINEAR);

      if (dst_linear_ptr && src_linear_ptr) {
         util_copy_rect(dst_linear_ptr, format,
                        llvmpipe_resource_stride(&dst_tex->base, dst_level),
                        dstx, dsty,
                        width, height,
                        src_linear_ptr,
                        llvmpipe_resource_stride(&src_tex->base, src_level),
                        src_box->x, src_box->y);
      }
   }
}
示例#20
0
文件: u_format.c 项目: MaikuMori/mesa
void
util_format_translate(enum pipe_format dst_format,
                      void *dst, unsigned dst_stride,
                      unsigned dst_x, unsigned dst_y,
                      enum pipe_format src_format,
                      const void *src, unsigned src_stride,
                      unsigned src_x, unsigned src_y,
                      unsigned width, unsigned height)
{
   const struct util_format_description *dst_format_desc;
   const struct util_format_description *src_format_desc;
   uint8_t *dst_row;
   const uint8_t *src_row;
   unsigned x_step, y_step;
   unsigned dst_step;
   unsigned src_step;

   dst_format_desc = util_format_description(dst_format);
   src_format_desc = util_format_description(src_format);

   if (util_is_format_compatible(src_format_desc, dst_format_desc)) {
      /*
       * Trivial case.
       */

      util_copy_rect(dst, dst_format, dst_stride,  dst_x, dst_y,
                     width, height, src, (int)src_stride,
                     src_x, src_y);
      return;
   }

   assert(dst_x % dst_format_desc->block.width == 0);
   assert(dst_y % dst_format_desc->block.height == 0);
   assert(src_x % src_format_desc->block.width == 0);
   assert(src_y % src_format_desc->block.height == 0);

   dst_row = (uint8_t *)dst + dst_y*dst_stride + dst_x*(dst_format_desc->block.bits/8);
   src_row = (const uint8_t *)src + src_y*src_stride + src_x*(src_format_desc->block.bits/8);

   /*
    * This works because all pixel formats have pixel blocks with power of two
    * sizes.
    */

   y_step = MAX2(dst_format_desc->block.height, src_format_desc->block.height);
   x_step = MAX2(dst_format_desc->block.width, src_format_desc->block.width);
   assert(y_step % dst_format_desc->block.height == 0);
   assert(y_step % src_format_desc->block.height == 0);

   dst_step = y_step / dst_format_desc->block.height * dst_stride;
   src_step = y_step / src_format_desc->block.height * src_stride;

   /*
    * TODO: double formats will loose precision
    * TODO: Add a special case for formats that are mere swizzles of each other
    */

   if (src_format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS ||
       dst_format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) {
      float *tmp_z = NULL;
      uint8_t *tmp_s = NULL;

      assert(x_step == 1);
      assert(y_step == 1);

      if (src_format_desc->unpack_z_float &&
          dst_format_desc->pack_z_float) {
         tmp_z = MALLOC(width * sizeof *tmp_z);
      }

      if (src_format_desc->unpack_s_8uint &&
          dst_format_desc->pack_s_8uint) {
         tmp_s = MALLOC(width * sizeof *tmp_s);
      }

      while (height--) {
         if (tmp_z) {
            src_format_desc->unpack_z_float(tmp_z, 0, src_row, src_stride, width, 1);
            dst_format_desc->pack_z_float(dst_row, dst_stride, tmp_z, 0, width, 1);
         }

         if (tmp_s) {
            src_format_desc->unpack_s_8uint(tmp_s, 0, src_row, src_stride, width, 1);
            dst_format_desc->pack_s_8uint(dst_row, dst_stride, tmp_s, 0, width, 1);
         }

         dst_row += dst_step;
         src_row += src_step;
      }

      FREE(tmp_s);

      FREE(tmp_z);

      return;
   }

   if (util_format_fits_8unorm(src_format_desc) ||
       util_format_fits_8unorm(dst_format_desc)) {
      unsigned tmp_stride;
      uint8_t *tmp_row;

      tmp_stride = MAX2(width, x_step) * 4 * sizeof *tmp_row;
      tmp_row = MALLOC(y_step * tmp_stride);
      if (!tmp_row)
         return;

      while (height >= y_step) {
         src_format_desc->unpack_rgba_8unorm(tmp_row, tmp_stride, src_row, src_stride, width, y_step);
         dst_format_desc->pack_rgba_8unorm(dst_row, dst_stride, tmp_row, tmp_stride, width, y_step);

         dst_row += dst_step;
         src_row += src_step;
         height -= y_step;
      }

      if (height) {
         src_format_desc->unpack_rgba_8unorm(tmp_row, tmp_stride, src_row, src_stride, width, height);
         dst_format_desc->pack_rgba_8unorm(dst_row, dst_stride, tmp_row, tmp_stride, width, height);
      }

      FREE(tmp_row);
   }
   else {
      unsigned tmp_stride;
      float *tmp_row;

      tmp_stride = MAX2(width, x_step) * 4 * sizeof *tmp_row;
      tmp_row = MALLOC(y_step * tmp_stride);
      if (!tmp_row)
         return;

      while (height >= y_step) {
         src_format_desc->unpack_rgba_float(tmp_row, tmp_stride, src_row, src_stride, width, y_step);
         dst_format_desc->pack_rgba_float(dst_row, dst_stride, tmp_row, tmp_stride, width, y_step);

         dst_row += dst_step;
         src_row += src_step;
         height -= y_step;
      }

      if (height) {
         src_format_desc->unpack_rgba_float(tmp_row, tmp_stride, src_row, src_stride, width, height);
         dst_format_desc->pack_rgba_float(dst_row, dst_stride, tmp_row, tmp_stride, width, height);
      }

      FREE(tmp_row);
   }
}
示例#21
0
VAStatus
vlVaGetImage(VADriverContextP ctx, VASurfaceID surface, int x, int y,
             unsigned int width, unsigned int height, VAImageID image)
{
   vlVaDriver *drv;
   vlVaSurface *surf;
   vlVaBuffer *img_buf;
   VAImage *vaimage;
   struct pipe_sampler_view **views;
   enum pipe_format format;
   bool convert = false;
   void *data[3];
   unsigned pitches[3], i, j;

   if (!ctx)
      return VA_STATUS_ERROR_INVALID_CONTEXT;

   drv = VL_VA_DRIVER(ctx);

   pipe_mutex_lock(drv->mutex);
   surf = handle_table_get(drv->htab, surface);
   if (!surf || !surf->buffer) {
      pipe_mutex_unlock(drv->mutex);
      return VA_STATUS_ERROR_INVALID_SURFACE;
   }

   vaimage = handle_table_get(drv->htab, image);
   if (!vaimage) {
      pipe_mutex_unlock(drv->mutex);
      return VA_STATUS_ERROR_INVALID_IMAGE;
   }

   img_buf = handle_table_get(drv->htab, vaimage->buf);
   if (!img_buf) {
      pipe_mutex_unlock(drv->mutex);
      return VA_STATUS_ERROR_INVALID_BUFFER;
   }

   format = VaFourccToPipeFormat(vaimage->format.fourcc);
   if (format == PIPE_FORMAT_NONE) {
      pipe_mutex_unlock(drv->mutex);
      return VA_STATUS_ERROR_OPERATION_FAILED;
   }

   if (format != surf->buffer->buffer_format) {
      /* support NV12 to YV12 and IYUV conversion now only */
      if ((format == PIPE_FORMAT_YV12 &&
          surf->buffer->buffer_format == PIPE_FORMAT_NV12) ||
          (format == PIPE_FORMAT_IYUV &&
          surf->buffer->buffer_format == PIPE_FORMAT_NV12))
         convert = true;
      else {
         pipe_mutex_unlock(drv->mutex);
         return VA_STATUS_ERROR_OPERATION_FAILED;
      }
   }

   views = surf->buffer->get_sampler_view_planes(surf->buffer);
   if (!views) {
      pipe_mutex_unlock(drv->mutex);
      return VA_STATUS_ERROR_OPERATION_FAILED;
   }

   for (i = 0; i < vaimage->num_planes; i++) {
      data[i] = img_buf->data + vaimage->offsets[i];
      pitches[i] = vaimage->pitches[i];
   }
   if (vaimage->format.fourcc == VA_FOURCC('I','4','2','0')) {
      void *tmp_d;
      unsigned tmp_p;
      tmp_d  = data[1];
      data[1] = data[2];
      data[2] = tmp_d;
      tmp_p = pitches[1];
      pitches[1] = pitches[2];
      pitches[2] = tmp_p;
   }

   for (i = 0; i < vaimage->num_planes; i++) {
      unsigned width, height;
      if (!views[i]) continue;
      vlVaVideoSurfaceSize(surf, i, &width, &height);
      for (j = 0; j < views[i]->texture->array_size; ++j) {
         struct pipe_box box = {0, 0, j, width, height, 1};
         struct pipe_transfer *transfer;
         uint8_t *map;
         map = drv->pipe->transfer_map(drv->pipe, views[i]->texture, 0,
                  PIPE_TRANSFER_READ, &box, &transfer);
         if (!map) {
            pipe_mutex_unlock(drv->mutex);
            return VA_STATUS_ERROR_OPERATION_FAILED;
         }

         if (i == 1 && convert) {
            u_copy_nv12_to_yv12(data, pitches, i, j,
               transfer->stride, views[i]->texture->array_size,
               map, box.width, box.height);
         } else {
            util_copy_rect(data[i] + pitches[i] * j,
               views[i]->texture->format,
               pitches[i] * views[i]->texture->array_size, 0, 0,
               box.width, box.height, map, transfer->stride, 0, 0);
         }
         pipe_transfer_unmap(drv->pipe, transfer);
      }
   }
   pipe_mutex_unlock(drv->mutex);

   return VA_STATUS_SUCCESS;
}
示例#22
0
static void
lp_resource_copy(struct pipe_context *pipe,
                 struct pipe_resource *dst, struct pipe_subresource subdst,
                 unsigned dstx, unsigned dsty, unsigned dstz,
                 struct pipe_resource *src, struct pipe_subresource subsrc,
                 unsigned srcx, unsigned srcy, unsigned srcz,
                 unsigned width, unsigned height)
{
   /* XXX what about the dstz/srcz parameters - zslice wasn't used... */
   struct llvmpipe_resource *src_tex = llvmpipe_resource(src);
   struct llvmpipe_resource *dst_tex = llvmpipe_resource(dst);
   const enum pipe_format format = src_tex->base.format;

   llvmpipe_flush_resource(pipe,
                           dst, subdst.face, subdst.level,
                           0, /* flush_flags */
                           FALSE, /* read_only */
                           TRUE, /* cpu_access */
                           FALSE, /* do_not_block */
                           "blit dest");

   llvmpipe_flush_resource(pipe,
                           src, subsrc.face, subsrc.level,
                           0, /* flush_flags */
                           TRUE, /* read_only */
                           TRUE, /* cpu_access */
                           FALSE, /* do_not_block */
                           "blit src");

   /*
   printf("surface copy from %u to %u: %u,%u to %u,%u %u x %u\n",
          src_tex->id, dst_tex->id,
          srcx, srcy, dstx, dsty, width, height);
   */

   /* set src tiles to linear layout */
   {
      unsigned tx, ty, tw, th;
      unsigned x, y;

      adjust_to_tile_bounds(srcx, srcy, width, height, &tx, &ty, &tw, &th);

      for (y = 0; y < th; y += TILE_SIZE) {
         for (x = 0; x < tw; x += TILE_SIZE) {
            (void) llvmpipe_get_texture_tile_linear(src_tex,
                                                    subsrc.face, subsrc.level,
                                                    LP_TEX_USAGE_READ,
                                                    tx + x, ty + y);
         }
      }
   }

   /* set dst tiles to linear layout */
   {
      unsigned tx, ty, tw, th;
      unsigned x, y;
      enum lp_texture_usage usage;

      adjust_to_tile_bounds(dstx, dsty, width, height, &tx, &ty, &tw, &th);

      for (y = 0; y < th; y += TILE_SIZE) {
         boolean contained_y = ty + y >= dsty &&
                               ty + y + TILE_SIZE <= dsty + height ?
                               TRUE : FALSE;

         for (x = 0; x < tw; x += TILE_SIZE) {
            boolean contained_x = tx + x >= dstx &&
                                  tx + x + TILE_SIZE <= dstx + width ?
                                  TRUE : FALSE;

            /*
             * Set the usage mode to WRITE_ALL for the tiles which are
             * completely contained by the dest rectangle.
             */
            if (contained_y && contained_x)
               usage = LP_TEX_USAGE_WRITE_ALL;
            else
               usage = LP_TEX_USAGE_READ_WRITE;

            (void) llvmpipe_get_texture_tile_linear(dst_tex,
                                                    subdst.face, subdst.level,
                                                    usage,
                                                    tx + x, ty + y);
         }
      }
   }

   /* copy */
   {
      const ubyte *src_linear_ptr
         = llvmpipe_get_texture_image_address(src_tex, subsrc.face,
                                              subsrc.level,
                                              LP_TEX_LAYOUT_LINEAR);
      ubyte *dst_linear_ptr
         = llvmpipe_get_texture_image_address(dst_tex, subdst.face,
                                              subdst.level,
                                              LP_TEX_LAYOUT_LINEAR);

      if (dst_linear_ptr && src_linear_ptr) {
         util_copy_rect(dst_linear_ptr, format,
                        llvmpipe_resource_stride(&dst_tex->base, subdst.level),
                        dstx, dsty,
                        width, height,
                        src_linear_ptr,
                        llvmpipe_resource_stride(&src_tex->base, subsrc.level),
                        srcx, srcy);
      }
   }
}
示例#23
0
/**
 * Fallback function for pipe->resource_copy_region().
 * Note: (X,Y)=(0,0) is always the upper-left corner.
 */
void
util_resource_copy_region(struct pipe_context *pipe,
                          struct pipe_resource *dst,
                          unsigned dst_level,
                          unsigned dst_x, unsigned dst_y, unsigned dst_z,
                          struct pipe_resource *src,
                          unsigned src_level,
                          const struct pipe_box *src_box)
{
   struct pipe_transfer *src_trans, *dst_trans;
   uint8_t *dst_map;
   const uint8_t *src_map;
   enum pipe_format src_format, dst_format;
   struct pipe_box dst_box;
   int z;

   assert(src && dst);
   if (!src || !dst)
      return;

   assert((src->target == PIPE_BUFFER && dst->target == PIPE_BUFFER) ||
          (src->target != PIPE_BUFFER && dst->target != PIPE_BUFFER));

   src_format = src->format;
   dst_format = dst->format;

   assert(util_format_get_blocksize(dst_format) == util_format_get_blocksize(src_format));
   assert(util_format_get_blockwidth(dst_format) == util_format_get_blockwidth(src_format));
   assert(util_format_get_blockheight(dst_format) == util_format_get_blockheight(src_format));

   src_map = pipe->transfer_map(pipe,
                                src,
                                src_level,
                                PIPE_TRANSFER_READ,
                                src_box, &src_trans);
   assert(src_map);
   if (!src_map) {
      goto no_src_map;
   }

   dst_box.x = dst_x;
   dst_box.y = dst_y;
   dst_box.z = dst_z;
   dst_box.width  = src_box->width;
   dst_box.height = src_box->height;
   dst_box.depth  = src_box->depth;

   dst_map = pipe->transfer_map(pipe,
                                dst,
                                dst_level,
                                PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD_RANGE,
                                &dst_box, &dst_trans);
   assert(dst_map);
   if (!dst_map) {
      goto no_dst_map;
   }

   if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) {
      assert(src_box->height == 1);
      assert(src_box->depth == 1);
      memcpy(dst_map, src_map, src_box->width);
   } else {
      for (z = 0; z < src_box->depth; ++z) {
         util_copy_rect(dst_map,
                        dst_format,
                        dst_trans->stride,
                        0, 0,
                        src_box->width, src_box->height,
                        src_map,
                        src_trans->stride,
                        0, 0);

         dst_map += dst_trans->layer_stride;
         src_map += src_trans->layer_stride;
      }
   }

   pipe->transfer_unmap(pipe, dst_trans);
no_dst_map:
   pipe->transfer_unmap(pipe, src_trans);
no_src_map:
   ;
}
示例#24
0
/**
 * Fallback function for pipe->resource_copy_region().
 * Note: (X,Y)=(0,0) is always the upper-left corner.
 */
void
util_resource_copy_region(struct pipe_context *pipe,
                          struct pipe_resource *dst,
                          unsigned dst_level,
                          unsigned dst_x, unsigned dst_y, unsigned dst_z,
                          struct pipe_resource *src,
                          unsigned src_level,
                          const struct pipe_box *src_box)
{
   struct pipe_transfer *src_trans, *dst_trans;
   void *dst_map;
   const void *src_map;
   enum pipe_format src_format, dst_format;
   unsigned w = src_box->width;
   unsigned h = src_box->height;

   assert(src && dst);
   assert((src->target == PIPE_BUFFER && dst->target == PIPE_BUFFER) ||
          (src->target != PIPE_BUFFER && dst->target != PIPE_BUFFER));

   if (!src || !dst)
      return;

   src_format = src->format;
   dst_format = dst->format;

   src_trans = pipe_get_transfer(pipe,
                                 src,
                                 src_level,
                                 src_box->z,
                                 PIPE_TRANSFER_READ,
                                 src_box->x, src_box->y, w, h);

   dst_trans = pipe_get_transfer(pipe,
                                 dst,
                                 dst_level,
                                 dst_z,
                                 PIPE_TRANSFER_WRITE,
                                 dst_x, dst_y, w, h);

   assert(util_format_get_blocksize(dst_format) == util_format_get_blocksize(src_format));
   assert(util_format_get_blockwidth(dst_format) == util_format_get_blockwidth(src_format));
   assert(util_format_get_blockheight(dst_format) == util_format_get_blockheight(src_format));

   src_map = pipe->transfer_map(pipe, src_trans);
   dst_map = pipe->transfer_map(pipe, dst_trans);

   assert(src_map);
   assert(dst_map);

   if (src_map && dst_map) {
      if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) {
         memcpy(dst_map, src_map, w);
      } else {
         util_copy_rect(dst_map,
                        dst_format,
                        dst_trans->stride,
                        0, 0,
                        w, h,
                        src_map,
                        src_trans->stride,
                        0,
                        0);
      }
   }

   pipe->transfer_unmap(pipe, src_trans);
   pipe->transfer_unmap(pipe, dst_trans);

   pipe->transfer_destroy(pipe, src_trans);
   pipe->transfer_destroy(pipe, dst_trans);
}