summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2009-08-07 11:56:40 +0200
committerMichel Dänzer <daenzer@vmware.com>2009-08-07 11:56:40 +0200
commit4cebafae81c1738a1c330d52a2c5248869f06411 (patch)
tree1f0d421672a4b96ed638f820aa3a74df37fdfbdf
parent9243791322e36b9231e6a3f04024ad66325385e3 (diff)
Add KMS EXA UploadToScreen hook.
Fixups by Michel Dänzer: Doesn't seem to be a win in terms of raw numbers, but should allow more pipelining and avoiding BO memory waste for small glyph pixmaps.
-rw-r--r--src/radeon_exa_funcs.c65
1 files changed, 63 insertions, 2 deletions
diff --git a/src/radeon_exa_funcs.c b/src/radeon_exa_funcs.c
index 145f13d..30d299f 100644
--- a/src/radeon_exa_funcs.c
+++ b/src/radeon_exa_funcs.c
@@ -447,7 +447,67 @@ RADEONBlitChunk(ScrnInfoPtr pScrn, struct radeon_bo *src_bo,
FINISH_ACCEL();
}
-#if defined(ACCEL_CP) && defined(XF86DRM_MODE)
+#if defined(XF86DRM_MODE)
+static Bool
+RADEONUploadToScreenCS(PixmapPtr pDst, int x, int y, int w, int h,
+ char *src, int src_pitch)
+{
+ RINFO_FROM_SCREEN(pDst->drawable.pScreen);
+ struct radeon_exa_pixmap_priv *driver_priv;
+ struct radeon_bo *scratch;
+ unsigned size;
+ uint32_t datatype = 0;
+ uint32_t dst_pitch_offset;
+ unsigned bpp = pDst->drawable.bitsPerPixel;
+ uint32_t scratch_pitch = (w * bpp / 8 + 63) & ~63;
+ Bool r;
+ int i;
+
+ if (bpp < 8)
+ return FALSE;
+
+ driver_priv = exaGetPixmapDriverPrivate(pDst);
+
+ size = scratch_pitch * h;
+ scratch = radeon_bo_open(info->bufmgr, 0, size, 0, RADEON_GEM_DOMAIN_GTT, 0);
+ if (scratch == NULL) {
+ return FALSE;
+ }
+ radeon_cs_space_reset_bos(info->cs);
+ radeon_add_pixmap(info->cs, pDst, 0, RADEON_GEM_DOMAIN_VRAM);
+ radeon_cs_space_add_persistent_bo(info->cs, scratch, RADEON_GEM_DOMAIN_GTT, 0);
+ r = radeon_cs_space_check(info->cs);
+ if (r) {
+ r = FALSE;
+ goto out;
+ }
+
+ r = radeon_bo_map(scratch, 0);
+ if (r) {
+ r = FALSE;
+ goto out;
+ }
+ r = TRUE;
+ size = w * bpp / 8;
+ for (i = 0; i < h; i++) {
+ memcpy(scratch->ptr + i * scratch_pitch, src, size);
+ src += src_pitch;
+ }
+ radeon_bo_unmap(scratch);
+
+ RADEONGetDatatypeBpp(pDst->drawable.bitsPerPixel, &datatype);
+ RADEONGetPixmapOffsetPitch(pDst, &dst_pitch_offset);
+ ACCEL_PREAMBLE();
+ RADEON_SWITCH_TO_2D();
+ RADEONBlitChunk(pScrn, scratch, driver_priv->bo, datatype, scratch_pitch << 16,
+ dst_pitch_offset, 0, 0, x, y, w, h,
+ RADEON_GEM_DOMAIN_GTT, RADEON_GEM_DOMAIN_VRAM);
+
+out:
+ radeon_bo_unref(scratch);
+ return r;
+}
+
static Bool
RADEONDownloadFromScreenCS(PixmapPtr pSrc, int x, int y, int w,
int h, char *dst, int dst_pitch)
@@ -460,7 +520,7 @@ RADEONDownloadFromScreenCS(PixmapPtr pSrc, int x, int y, int w,
uint32_t src_pitch_offset;
unsigned bpp = pSrc->drawable.bitsPerPixel;
uint32_t scratch_pitch = (w * bpp / 8 + 63) & ~63;
- int r;
+ Bool r;
driver_priv = exaGetPixmapDriverPrivate(pSrc);
/* if we have more refs than just the BO then flush */
@@ -652,6 +712,7 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen)
}
# if defined(XF86DRM_MODE)
else {
+ info->accel_state->exa->UploadToScreen = &RADEONUploadToScreenCS;
info->accel_state->exa->DownloadFromScreen = &RADEONDownloadFromScreenCS;
}
# endif