[PATCH 02/13] glamor: Add glamor_program based copy acceleration
Eric Anholt
eric at anholt.net
Tue May 6 10:41:53 PDT 2014
Looks like my reply last night didn't go through...
Keith Packard <keithp at keithp.com> writes:
> Paints with textures, using a temporary buffer for overlapping copies
>
> Performs CPU to GPU transfers for pixmaps in memory. Accelerates copy
> plane when both objects are in the GPU. Includes copy_window
> acceleration too.
>
> v2: Use NV_texture_barrier for non-overlapping copies within the same
> drawable
>
> v3: Switch to glamor_make_current
>
> v4: Do overlap check on the bounding box of the region rather than
> on individual boxes
>
> Signed-off-by: Keith Packard <keithp at keithp.com>
>
> fixup copy
>
> Signed-off-by: Keith Packard <keithp at keithp.com>
There's some mess in the commit message from a squash.
The code looks good now and I'd like to just get some comments touched up.
However, regardless of what you decide to do with my comment suggestions,
Reviewed-by: Eric Anholt <eric at anholt.net>
> +/*
> + * Copy from GPU to GPU by using the source
> + * as a texture and painting that into the destination
> + */
Extended comment:
/**
* Implements CopyPlane and CopyArea from the GPU to the GPU by using
* the source as a texture and painting that into the destination.
*
* This requires that source and dest are different textures, or that
* (if the copy area doesn't overlap), GL_NV_texture_barrier is used
* to ensure that the caches are flushed at the right times.
*/
> +static Bool
> +glamor_copy_fbo_fbo_draw(DrawablePtr src,
> + DrawablePtr dst,
> + GCPtr gc,
> + BoxPtr box,
> + int nbox,
> + int dx,
> + int dy,
> + Bool reverse,
> + Bool upsidedown,
> + Pixel bitplane,
> + void *closure)
> +/*
> + * Copy from GPU to GPU, but create
> + * a temporary pixmap in the middle to
> + * correctly handle overlapping copies
> + * in systems lacking glCopyPixels
> + */
/**
* Copies from the GPU to the GPU using a temporary pixmap in between,
* to correctly handle overlapping copies.
*/
(you're not using copypixels at all any more)
> +static Bool
> +glamor_copy_fbo_fbo_temp(DrawablePtr src,
> + DrawablePtr dst,
> + GCPtr gc,
> + BoxPtr box,
> + int nbox,
> + int dx,
> + int dy,
> + Bool reverse,
> + Bool upsidedown,
> + Pixel bitplane,
> + void *closure)
> +/*
> + * Check and see if this copy operation overlaps within
> + * the same pixmap
> + */
/**
* Returns TRUE if the copy has to be implemented with
* glamor_copy_fbo_fbo_temp() instead of glamor_copy_fbo_fbo().
*
* If the src and dst are in the same pixmap, then glamor_copy_fbo_fbo()'s
* sampling would give undefined results (since the same texture would be
* bound as an FBO destination and as a texture source). However, if we
* have GL_NV_texture_barrier, we can take advantage of the exception it
* added:
*
* "- If a texel has been written, then in order to safely read the result
* a texel fetch must be in a subsequent Draw separated by the command
*
* void TextureBarrierNV(void);
*
* TextureBarrierNV() will guarantee that writes have completed and caches
* have been invalidated before subsequent Draws are executed."
*/
> +static Bool
> +glamor_copy_needs_temp(DrawablePtr src,
> + DrawablePtr dst,
> + BoxPtr box,
> + int nbox,
> + int dx,
> + int dy)
> +{
> + PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
> + PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
> + ScreenPtr screen = dst->pScreen;
> + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
> + int n;
> + int dst_off_x, dst_off_y;
> + int src_off_x, src_off_y;
> + BoxRec bounds;
> +
> + if (src_pixmap != dst_pixmap)
> + return FALSE;
> +
> + if (nbox == 0)
> + return FALSE;
> +
> + if (!glamor_priv->has_nv_texture_barrier)
> + return TRUE;
> +
> + glamor_get_drawable_deltas(src, src_pixmap, &src_off_x, &src_off_y);
> + glamor_get_drawable_deltas(dst, dst_pixmap, &dst_off_x, &dst_off_y);
> +
> + bounds = box[0];
> + for (n = 1; n < nbox; n++) {
> + bounds.x1 = min(bounds.x1, box[n].x1);
> + bounds.y1 = min(bounds.y1, box[n].y1);
> +
> + bounds.x2 = max(bounds.x2, box[n].x2);
> + bounds.y2 = max(bounds.y2, box[n].y2);
> + }
> +
> + /* Check to see if the pixmap-relative boxes overlap in both X and Y,
> + * in which case we can't rely on NV_texture_barrier and must
> + * make a temporary copy
> + *
> + * dst.x1 < src.x2 &&
> + * src.x1 < dst.x2 &&
> + *
> + * dst.y1 < src.y2 &&
> + * src.y1 < dst.y2
> + */
> + if (bounds.x1 + dst_off_x < bounds.x2 + dx + src_off_x &&
> + bounds.x1 + dx + src_off_x < bounds.x2 + dst_off_x &&
> +
> + bounds.y1 + dst_off_y < bounds.y2 + dy + src_off_y &&
> + bounds.y1 + dy + src_off_y < bounds.y2 + dst_off_y) {
> + return TRUE;
> + }
> +
> + glTextureBarrierNV();
> +
> + return FALSE;
> +}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 818 bytes
Desc: not available
URL: <http://lists.x.org/archives/xorg-devel/attachments/20140506/82827541/attachment.sig>
More information about the xorg-devel
mailing list