diff options
| author | Michel Dänzer <daenzer@vmware.com> | 2009-08-13 18:46:53 +0200 | 
|---|---|---|
| committer | Michel Dänzer <daenzer@vmware.com> | 2009-08-13 18:46:53 +0200 | 
| commit | 7ef8c79a8c69d62eecbd4301b0e15d44d0797072 (patch) | |
| tree | 411c1bd50220cf6f5f07e79ba9de3df14e400aeb /src/gallium/state_trackers | |
| parent | f2fcd5822a0b308e8b9410061996377c0b4a0a91 (diff) | |
st/xorg: Fix DRI2 CopyRegion hook.
Use GC CopyArea op for proper translation and clipping, and throttle full
buffer swaps / frontbuffer flushes.
Diffstat (limited to 'src/gallium/state_trackers')
| -rw-r--r-- | src/gallium/state_trackers/xorg/xorg_dri2.c | 72 | 
1 files changed, 43 insertions, 29 deletions
| diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c index 301e5214e3..3fbab4dc51 100644 --- a/src/gallium/state_trackers/xorg/xorg_dri2.c +++ b/src/gallium/state_trackers/xorg/xorg_dri2.c @@ -45,6 +45,7 @@ typedef struct {      PixmapPtr pPixmap;      struct pipe_texture *tex;      struct pipe_buffer *buf; +    struct pipe_fence_handle *fence;  } *BufferPrivatePtr;  static DRI2BufferPtr @@ -97,17 +98,11 @@ driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count)  	    tex = ms->screen->texture_create(ms->screen, &template);  	    depth = tex;  	} else { -	    struct pipe_texture template; -	    memset(&template, 0, sizeof(template)); -	    template.target = PIPE_TEXTURE_2D; -	    template.format = PIPE_FORMAT_A8R8G8B8_UNORM; -	    pf_get_block(template.format, &template.block); -	    template.width[0] = pDraw->width; -	    template.height[0] = pDraw->height; -	    template.depth[0] = 1; -	    template.last_level = 0; -	    template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; -	    tex = ms->screen->texture_create(ms->screen, &template); +	    pPixmap = (*pScreen->CreatePixmap)(pScreen, pDraw->width, +					       pDraw->height, +					       pDraw->depth, +					       0); +	    tex = xorg_exa_get_texture(pPixmap);  	}  	if (!tex) @@ -148,11 +143,12 @@ driDestroyBuffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count)      for (i = 0; i < count; i++) {  	private = buffers[i].driverPrivate; -	if (private->pPixmap) -	    (*pScreen->DestroyPixmap)(private->pPixmap); -  	pipe_texture_reference(&private->tex, NULL);  	pipe_buffer_reference(&private->buf, NULL); +        ms->screen->fence_reference(ms->screen, &private->fence, NULL); + +	if (private->pPixmap) +	    (*pScreen->DestroyPixmap)(private->pPixmap);      }      if (buffers) { @@ -170,24 +166,42 @@ driCopyRegion(DrawablePtr pDraw, RegionPtr pRegion,      modesettingPtr ms = modesettingPTR(pScrn);      BufferPrivatePtr dst_priv = pDestBuffer->driverPrivate;      BufferPrivatePtr src_priv = pSrcBuffer->driverPrivate; +    PixmapPtr src_pixmap; +    PixmapPtr dst_pixmap; +    GCPtr gc; +    RegionPtr copy_clip; -    struct pipe_surface *dst_surf = -	ms->screen->get_tex_surface(ms->screen, dst_priv->tex, 0, 0, 0, -				    PIPE_BUFFER_USAGE_GPU_WRITE); -    struct pipe_surface *src_surf = -	ms->screen->get_tex_surface(ms->screen, src_priv->tex, 0, 0, 0, -				    PIPE_BUFFER_USAGE_GPU_READ); +    src_pixmap = src_priv->pPixmap; +    dst_pixmap = dst_priv->pPixmap; +    if (pSrcBuffer->attachment == DRI2BufferFrontLeft) +	src_pixmap = (PixmapPtr)pDraw; +    if (pDestBuffer->attachment == DRI2BufferFrontLeft) +	dst_pixmap = (PixmapPtr)pDraw; +    gc = GetScratchGC(pDraw->depth, pScreen); +    copy_clip = REGION_CREATE(pScreen, NULL, 0); +    REGION_COPY(pScreen, copy_clip, pRegion); +    (*gc->funcs->ChangeClip) (gc, CT_REGION, copy_clip, 0); +    ValidateGC(&dst_pixmap->drawable, gc); -#if 1 -    ms->ctx->surface_copy(ms->ctx, dst_surf, 0, 0, src_surf, -			  0, 0, pDraw->width, pDraw->height); -#else -    util_surface_copy(ms->ctx, false, dst_surf, 0, 0, src_surf, -		      0, 0, pDraw->width, pDraw->height); -#endif +    /* If this is a full buffer swap, throttle on the previous one */ +    if (dst_priv->fence && REGION_NUM_RECTS(pRegion) == 1) { +	BoxPtr extents = REGION_EXTENTS(pScreen, pRegion); + +	if (extents->x1 == 0 && extents->y1 == 0 && +	    extents->x2 == pDraw->width && extents->y2 == pDraw->height) { +	    ms->screen->fence_finish(ms->screen, dst_priv->fence, 0); +	    ms->screen->fence_reference(ms->screen, &dst_priv->fence, NULL); +	} +    } + +    (*gc->ops->CopyArea)(&src_pixmap->drawable, &dst_pixmap->drawable, gc, +			 0, 0, pDraw->width, pDraw->height, 0, 0); + +    FreeScratchGC(gc); -    pipe_surface_reference(&dst_surf, NULL); -    pipe_surface_reference(&src_surf, NULL); +    ms->ctx->flush(ms->ctx, PIPE_FLUSH_SWAPBUFFERS, +		   pDestBuffer->attachment == DRI2BufferFrontLeft ? +		   &dst_priv->fence : NULL);  }  Bool | 
