xf86-video-intel: 4 commits - src/common.h src/i830_batchbuffer.c src/i830_batchbuffer.h src/i830.h src/i830_uxa.c src/i915_render.c
Chris Wilson
ickle at kemper.freedesktop.org
Thu Jun 17 06:41:41 PDT 2010
src/common.h | 1
src/i830.h | 20 ++-
src/i830_batchbuffer.c | 51 +-------
src/i830_batchbuffer.h | 12 -
src/i830_uxa.c | 312 +++++++++++++++++++++++++------------------------
src/i915_render.c | 9 +
6 files changed, 199 insertions(+), 206 deletions(-)
New commits:
commit be55066c6481b4c5e2cd39ef1c0f3be88cae0c93
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Jun 17 14:23:21 2010 +0100
i830: Remove domain tracking from pixmaps.
The 4 integers can be reduced to a single boolean value, so do so.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/i830.h b/src/i830.h
index a5fee3d..64acda3 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -168,14 +168,10 @@ struct intel_pixmap {
struct list flush, batch, in_flight;
- int8_t busy;
- uint8_t tiling;
uint16_t stride;
-
- uint16_t flush_write_domain;
- uint16_t flush_read_domains;
- uint16_t batch_write_domain;
- uint16_t batch_read_domains;
+ uint8_t tiling;
+ int8_t busy :2;
+ int8_t batch_write :1;
};
#if HAS_DEVPRIVATEKEYREC
@@ -207,7 +203,7 @@ static inline void i830_set_pixmap_intel(PixmapPtr pixmap, struct intel_pixmap *
static inline Bool i830_uxa_pixmap_is_dirty(PixmapPtr pixmap)
{
- return i830_get_pixmap_intel(pixmap)->flush_write_domain != 0;
+ return !list_is_empty(&i830_get_pixmap_intel(pixmap)->flush);
}
static inline Bool i830_pixmap_tiled(PixmapPtr pixmap)
diff --git a/src/i830_batchbuffer.c b/src/i830_batchbuffer.c
index 46c9d4f..6da20d7 100644
--- a/src/i830_batchbuffer.c
+++ b/src/i830_batchbuffer.c
@@ -109,27 +109,11 @@ void intel_batch_teardown(ScrnInfoPtr scrn)
intel->vertex_bo = NULL;
}
- while (!list_is_empty(&intel->batch_pixmaps)) {
- struct intel_pixmap *entry;
-
- entry = list_first_entry(&intel->batch_pixmaps,
- struct intel_pixmap,
- batch);
-
- entry->batch_read_domains = entry->batch_write_domain = 0;
- list_del(&entry->batch);
- }
-
- while (!list_is_empty(&intel->flush_pixmaps)) {
- struct intel_pixmap *entry;
-
- entry = list_first_entry(&intel->flush_pixmaps,
- struct intel_pixmap,
- flush);
+ while (!list_is_empty(&intel->batch_pixmaps))
+ list_del(intel->batch_pixmaps.next);
- entry->flush_read_domains = entry->flush_write_domain = 0;
- list_del(&entry->flush);
- }
+ while (!list_is_empty(&intel->flush_pixmaps))
+ list_del(intel->flush_pixmaps.next);
while (!list_is_empty(&intel->in_flight)) {
struct intel_pixmap *entry;
@@ -148,16 +132,8 @@ void intel_batch_do_flush(ScrnInfoPtr scrn)
{
intel_screen_private *intel = intel_get_screen_private(scrn);
- while (!list_is_empty(&intel->flush_pixmaps)) {
- struct intel_pixmap *entry;
-
- entry = list_first_entry(&intel->flush_pixmaps,
- struct intel_pixmap,
- flush);
-
- entry->flush_read_domains = entry->flush_write_domain = 0;
- list_del(&entry->flush);
- }
+ while (!list_is_empty(&intel->flush_pixmaps))
+ list_del(intel->flush_pixmaps.next);
intel->need_mi_flush = FALSE;
}
@@ -239,8 +215,8 @@ void intel_batch_submit(ScrnInfoPtr scrn)
struct intel_pixmap,
batch);
- entry->batch_read_domains = entry->batch_write_domain = 0;
entry->busy = -1;
+ entry->batch_write = 0;
list_del(&entry->batch);
}
@@ -249,16 +225,8 @@ void intel_batch_submit(ScrnInfoPtr scrn)
* the work.
*/
intel->need_mi_flush = !list_is_empty(&intel->flush_pixmaps);
- while (!list_is_empty(&intel->flush_pixmaps)) {
- struct intel_pixmap *entry;
-
- entry = list_first_entry(&intel->flush_pixmaps,
- struct intel_pixmap,
- flush);
-
- entry->flush_read_domains = entry->flush_write_domain = 0;
- list_del(&entry->flush);
- }
+ while (!list_is_empty(&intel->flush_pixmaps))
+ list_del(intel->flush_pixmaps.next);
while (!list_is_empty(&intel->in_flight)) {
struct intel_pixmap *entry;
diff --git a/src/i830_batchbuffer.h b/src/i830_batchbuffer.h
index 93f786a..5375d2c 100644
--- a/src/i830_batchbuffer.h
+++ b/src/i830_batchbuffer.h
@@ -123,19 +123,13 @@ intel_batch_mark_pixmap_domains(intel_screen_private *intel,
{
assert (read_domains);
assert (write_domain == 0 || write_domain == read_domains);
- assert (write_domain == 0 ||
- priv->flush_write_domain == 0 ||
- priv->flush_write_domain == write_domain);
-
- priv->flush_read_domains |= read_domains;
- priv->batch_read_domains |= read_domains;
- priv->flush_write_domain |= write_domain;
- priv->batch_write_domain |= write_domain;
+
if (list_is_empty(&priv->batch))
list_add(&priv->batch, &intel->batch_pixmaps);
if (list_is_empty(&priv->flush))
list_add(&priv->flush, &intel->flush_pixmaps);
+ priv->batch_write |= write_domain != 0;
priv->busy = 1;
}
diff --git a/src/i830_uxa.c b/src/i830_uxa.c
index 8d67665..7946f91 100644
--- a/src/i830_uxa.c
+++ b/src/i830_uxa.c
@@ -676,7 +676,7 @@ static Bool i830_uxa_prepare_access(PixmapPtr pixmap, uxa_access_t access)
int ret;
if (!list_is_empty(&priv->batch) &&
- (access == UXA_ACCESS_RW || priv->batch_write_domain))
+ (access == UXA_ACCESS_RW || priv->batch_write))
intel_batch_submit(scrn);
if (bo->size > intel->max_gtt_map_size) {
commit c187da9a24e98cbdf86f0f0dfbdcd9025c8a4c76
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed Jun 16 13:16:28 2010 +0100
i830: GetImage acceleration.
The presumption is that we wish to keep the target hot, so
copy to a new bo and move that to the CPU in preference to
causing ping-pong of the original.
Also the gpu is much faster at detiling.
Before (PineView):
400000 trep @ 0.1128 msec ( 8860.0/sec): GetImage 10x10 square
18000 trep @ 1.3839 msec ( 723.0/sec): GetImage 100x100 square
800 trep @ 30.0987 msec ( 33.2/sec): GetImage 500x500 square
After: (PineView)
180000 trep @ 0.1478 msec ( 6770.0/sec): GetImage 10x10 square
60000 trep @ 0.4545 msec ( 2200.0/sec): GetImage 100x100 square
4000 trep @ 8.0739 msec ( 124.0/sec): GetImage 500x500 square
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/common.h b/src/common.h
index 883aaa8..30f1c78 100644
--- a/src/common.h
+++ b/src/common.h
@@ -421,6 +421,7 @@ intel_host_bridge (void);
enum {
INTEL_CREATE_PIXMAP_TILING_X = 0x10000000,
INTEL_CREATE_PIXMAP_TILING_Y,
+ INTEL_CREATE_PIXMAP_TILING_NONE,
};
#endif /* _INTEL_COMMON_H_ */
diff --git a/src/i830_uxa.c b/src/i830_uxa.c
index b69d45e..8d67665 100644
--- a/src/i830_uxa.c
+++ b/src/i830_uxa.c
@@ -831,6 +831,94 @@ static Bool i830_uxa_put_image(PixmapPtr pixmap,
}
}
+static Bool i830_uxa_pixmap_get_image(PixmapPtr pixmap,
+ int x, int y, int w, int h,
+ char *dst, int dst_pitch)
+{
+ struct intel_pixmap *priv = i830_get_pixmap_intel(pixmap);
+ int stride = i830_pixmap_pitch(pixmap);
+
+ if (dst_pitch == stride && w == pixmap->drawable.width) {
+ return drm_intel_bo_get_subdata(priv->bo, y * stride, stride * h, dst) == 0;
+ } else {
+ char *src;
+ int cpp;
+
+ if (drm_intel_bo_map(priv->bo, FALSE))
+ return FALSE;
+
+ cpp = pixmap->drawable.bitsPerPixel/8;
+ src = (char *) priv->bo->virtual + y * stride + x * cpp;
+ w *= cpp;
+ do {
+ memcpy(dst, src, w);
+ src += stride;
+ dst += dst_pitch;
+ } while (--h);
+
+ drm_intel_bo_unmap(priv->bo);
+
+ return TRUE;
+ }
+}
+
+static Bool i830_uxa_get_image(PixmapPtr pixmap,
+ int x, int y,
+ int w, int h,
+ char *dst, int dst_pitch)
+{
+ struct intel_pixmap *priv;
+ PixmapPtr scratch = NULL;
+ Bool ret;
+
+ /* The presumption is that we wish to keep the target hot, so
+ * copy to a new bo and move that to the CPU in preference to
+ * causing ping-pong of the original.
+ *
+ * Also the gpu is much faster at detiling.
+ */
+
+ priv = i830_get_pixmap_intel(pixmap);
+ if (intel_pixmap_is_busy(priv) || priv->tiling != I915_TILING_NONE) {
+ ScreenPtr screen = pixmap->drawable.pScreen;
+ GCPtr gc;
+
+ /* Copy to a linear buffer and pull. */
+ scratch = screen->CreatePixmap(screen, w, h,
+ pixmap->drawable.depth,
+ INTEL_CREATE_PIXMAP_TILING_NONE);
+ if (!scratch)
+ return FALSE;
+
+ gc = GetScratchGC(pixmap->drawable.depth, screen);
+ if (!gc) {
+ screen->DestroyPixmap(scratch);
+ return FALSE;
+ }
+
+ ValidateGC(&pixmap->drawable, gc);
+
+ gc->ops->CopyArea(&pixmap->drawable,
+ &scratch->drawable,
+ gc, x, y, w, h, 0, 0);
+
+ FreeScratchGC(gc);
+
+ intel_batch_submit(xf86Screens[screen->myNum]);
+
+ x = y = 0;
+ pixmap = scratch;
+ }
+
+ ret = i830_uxa_pixmap_get_image(pixmap, x, y, w, h, dst, dst_pitch);
+
+ if (scratch)
+ scratch->drawable.pScreen->DestroyPixmap(scratch);
+
+ return ret;
+
+}
+
void i830_uxa_block_handler(ScreenPtr screen)
{
ScrnInfoPtr scrn = xf86Screens[screen->myNum];
@@ -884,7 +972,7 @@ i830_uxa_create_pixmap(ScreenPtr screen, int w, int h, int depth,
tiling = I915_TILING_X;
if (usage == INTEL_CREATE_PIXMAP_TILING_Y)
tiling = I915_TILING_Y;
- if (usage == UXA_CREATE_PIXMAP_FOR_MAP)
+ if (usage == UXA_CREATE_PIXMAP_FOR_MAP || usage == INTEL_CREATE_PIXMAP_TILING_NONE)
tiling = I915_TILING_NONE;
if (tiling != I915_TILING_NONE) {
@@ -1069,6 +1157,7 @@ Bool i830_uxa_init(ScreenPtr screen)
/* PutImage */
intel->uxa_driver->put_image = i830_uxa_put_image;
+ intel->uxa_driver->get_image = i830_uxa_get_image;
intel->uxa_driver->prepare_access = i830_uxa_prepare_access;
intel->uxa_driver->finish_access = i830_uxa_finish_access;
commit 0e0101758438debf98f989d815989b45e78cf5f6
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Jun 15 12:48:57 2010 +0100
i830: Tidy i830_uxa_put_image()
Use a single code path to upload the image data after selecting the
right bo, and take advantage of pwrite() when possible.
Fixes:
Bug 28569 - [i965] IGN's flash-based video player crashes X
https://bugs.freedesktop.org/show_bug.cgi?id=28569
Bug 28573 - [i965] Fullscreen flash and windowed SDL games fail to
update the screen
https://bugs.freedesktop.org/show_bug.cgi?id=28573
Reported-and-tested-by: Brian Rogers <brian at xyzw.org>
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/i830.h b/src/i830.h
index 02220ea..a5fee3d 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -165,12 +165,17 @@ list_is_empty(struct list *head)
struct intel_pixmap {
dri_bo *bo;
- uint32_t tiling, stride;
- uint32_t flush_write_domain;
- uint32_t flush_read_domains;
- uint32_t batch_write_domain;
- uint32_t batch_read_domains;
+
struct list flush, batch, in_flight;
+
+ int8_t busy;
+ uint8_t tiling;
+ uint16_t stride;
+
+ uint16_t flush_write_domain;
+ uint16_t flush_read_domains;
+ uint16_t batch_write_domain;
+ uint16_t batch_read_domains;
};
#if HAS_DEVPRIVATEKEYREC
@@ -188,6 +193,13 @@ static inline struct intel_pixmap *i830_get_pixmap_intel(PixmapPtr pixmap)
#endif
}
+static inline Bool intel_pixmap_is_busy(struct intel_pixmap *priv)
+{
+ if (priv->busy == -1)
+ priv->busy = drm_intel_bo_busy(priv->bo);
+ return priv->busy;
+}
+
static inline void i830_set_pixmap_intel(PixmapPtr pixmap, struct intel_pixmap *intel)
{
dixSetPrivate(&pixmap->devPrivates, &uxa_pixmap_index, intel);
diff --git a/src/i830_batchbuffer.c b/src/i830_batchbuffer.c
index ada5809..46c9d4f 100644
--- a/src/i830_batchbuffer.c
+++ b/src/i830_batchbuffer.c
@@ -240,6 +240,7 @@ void intel_batch_submit(ScrnInfoPtr scrn)
batch);
entry->batch_read_domains = entry->batch_write_domain = 0;
+ entry->busy = -1;
list_del(&entry->batch);
}
diff --git a/src/i830_batchbuffer.h b/src/i830_batchbuffer.h
index 7508a9c..93f786a 100644
--- a/src/i830_batchbuffer.h
+++ b/src/i830_batchbuffer.h
@@ -135,6 +135,8 @@ intel_batch_mark_pixmap_domains(intel_screen_private *intel,
list_add(&priv->batch, &intel->batch_pixmaps);
if (list_is_empty(&priv->flush))
list_add(&priv->flush, &intel->flush_pixmaps);
+
+ priv->busy = 1;
}
static inline void
diff --git a/src/i830_uxa.c b/src/i830_uxa.c
index bf364f8..b69d45e 100644
--- a/src/i830_uxa.c
+++ b/src/i830_uxa.c
@@ -629,6 +629,7 @@ void i830_set_pixmap_bo(PixmapPtr pixmap, dri_bo * bo)
}
if (bo != NULL) {
+ uint32_t tiling;
uint32_t swizzle_mode;
int ret;
@@ -646,12 +647,15 @@ void i830_set_pixmap_bo(PixmapPtr pixmap, dri_bo * bo)
priv->stride = i830_pixmap_pitch(pixmap);
ret = drm_intel_bo_get_tiling(bo,
- &priv->tiling,
+ &tiling,
&swizzle_mode);
if (ret != 0) {
FatalError("Couldn't get tiling on bo %p: %s\n",
bo, strerror(-ret));
}
+
+ priv->tiling = tiling;
+ priv->busy = -1;
} else {
if (priv != NULL) {
free(priv);
@@ -696,6 +700,7 @@ static Bool i830_uxa_prepare_access(PixmapPtr pixmap, uxa_access_t access)
}
pixmap->devPrivate.ptr = bo->virtual;
+ priv->busy = 0;
return TRUE;
}
@@ -718,78 +723,33 @@ static void i830_uxa_finish_access(PixmapPtr pixmap)
pixmap->devPrivate.ptr = NULL;
}
-static Bool i830_bo_put_image(PixmapPtr pixmap, dri_bo *bo, char *src, int src_pitch, int w, int h)
+static Bool i830_uxa_pixmap_put_image(PixmapPtr pixmap,
+ char *src, int src_pitch,
+ int x, int y, int w, int h)
{
+ struct intel_pixmap *priv = i830_get_pixmap_intel(pixmap);
int stride = i830_pixmap_pitch(pixmap);
-
- if (src_pitch == stride) {
- memcpy (bo->virtual, src, stride * h);
- } else {
- char *dst = bo->virtual;
- int row_length = w * pixmap->drawable.bitsPerPixel/8;
+ int ret = FALSE;
+
+ if (src_pitch == stride && w == pixmap->drawable.width && priv->tiling == I915_TILING_NONE) {
+ ret = drm_intel_bo_subdata(priv->bo, y * stride, stride * h, src) == 0;
+ } else if (drm_intel_gem_bo_map_gtt(priv->bo) == 0) {
+ char *dst = priv->bo->virtual;
+ int cpp = pixmap->drawable.bitsPerPixel/8;
+ int row_length = w * cpp;
int num_rows = h;
- while (num_rows--) {
+ if (row_length == src_pitch && src_pitch == stride)
+ num_rows = 1, row_length *= h;
+ dst += y * stride + x * cpp;
+ do {
memcpy (dst, src, row_length);
src += src_pitch;
dst += stride;
- }
- }
-
- return TRUE;
-}
-
-static Bool
-i830_uxa_pixmap_swap_bo_with_image(PixmapPtr pixmap,
- char *src, int src_pitch)
-{
- ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum];
- intel_screen_private *intel = intel_get_screen_private(scrn);
- struct intel_pixmap *priv;
- dri_bo *bo;
- uint32_t tiling = I915_TILING_X;
- int stride;
- int w = pixmap->drawable.width;
- int h = pixmap->drawable.height;
- Bool ret;
-
- priv = i830_get_pixmap_intel(pixmap);
-
- if (priv->batch_read_domains || drm_intel_bo_busy(priv->bo)) {
- unsigned int size;
-
- size = i830_uxa_pixmap_compute_size (pixmap, w, h,
- &tiling, &stride);
- if (size > intel->max_gtt_map_size)
- return FALSE;
-
- bo = drm_intel_bo_alloc(intel->bufmgr, "pixmap", size, 0);
- if (bo == NULL)
- return FALSE;
-
- if (tiling != I915_TILING_NONE)
- drm_intel_bo_set_tiling(bo, &tiling, stride);
-
- pixmap->drawable.pScreen->ModifyPixmapHeader(pixmap,
- w, h,
- 0, 0,
- stride, NULL);
- i830_set_pixmap_bo(pixmap, bo);
- dri_bo_unreference(bo);
- } else {
- bo = priv->bo;
- stride = i830_pixmap_pitch(pixmap);
- }
-
- if (drm_intel_gem_bo_map_gtt(bo)) {
- xf86DrvMsg(scrn->scrnIndex, X_WARNING,
- "%s: bo map failed\n", __FUNCTION__);
- return FALSE;
+ } while (--num_rows);
+ drm_intel_gem_bo_unmap_gtt(priv->bo);
+ ret = TRUE;
}
- ret = i830_bo_put_image(pixmap, bo, src, src_pitch, w, h);
-
- drm_intel_gem_bo_unmap_gtt(bo);
-
return ret;
}
@@ -798,114 +758,77 @@ static Bool i830_uxa_put_image(PixmapPtr pixmap,
int w, int h,
char *src, int src_pitch)
{
- ScreenPtr screen = pixmap->drawable.pScreen;
- ScrnInfoPtr scrn = xf86Screens[screen->myNum];
- PixmapPtr scratch;
struct intel_pixmap *priv;
- GCPtr gc;
- Bool ret;
-
- if (x == 0 && y == 0 &&
- w == pixmap->drawable.width &&
- h == pixmap->drawable.height)
- {
- /* Replace GPU hot bo with new CPU data. */
- return i830_uxa_pixmap_swap_bo_with_image(pixmap,
- src, src_pitch);
- }
priv = i830_get_pixmap_intel(pixmap);
- if (priv->batch_read_domains ||
- drm_intel_bo_busy(priv->bo)) {
- dri_bo *bo;
-
- /* Partial replacement, copy incoming image to a bo and blit. */
- scratch = (*screen->CreatePixmap)(screen, w, h,
- pixmap->drawable.depth,
- UXA_CREATE_PIXMAP_FOR_MAP);
- if (!scratch)
- return FALSE;
-
- bo = i830_get_pixmap_bo(scratch);
- if (drm_intel_gem_bo_map_gtt(bo)) {
- (*screen->DestroyPixmap) (scratch);
- xf86DrvMsg(scrn->scrnIndex, X_WARNING,
- "%s: bo map failed\n", __FUNCTION__);
- return FALSE;
- }
-
- ret = i830_bo_put_image(scratch, bo, src, src_pitch, w, h);
-
- drm_intel_gem_bo_unmap_gtt(bo);
-
- if (ret) {
- gc = GetScratchGC(pixmap->drawable.depth, screen);
- if (gc) {
- ValidateGC(&pixmap->drawable, gc);
-
- (*gc->ops->CopyArea)(&scratch->drawable,
- &pixmap->drawable,
- gc, 0, 0, w, h, x, y);
-
- FreeScratchGC(gc);
- } else
- ret = FALSE;
- }
-
- (*screen->DestroyPixmap)(scratch);
+ if (!intel_pixmap_is_busy(priv)) {
+ /* bo is not busy so can be replaced without a stall, upload in-place. */
+ return i830_uxa_pixmap_put_image(pixmap, src, src_pitch, x, y, w, h);
} else {
- int dst_pitch;
+ ScreenPtr screen = pixmap->drawable.pScreen;
- /* bo is not busy so can be mapped without a stall, upload in-place. */
- if (drm_intel_gem_bo_map_gtt(priv->bo)) {
- xf86DrvMsg(scrn->scrnIndex, X_WARNING,
- "%s: bo map failed\n", __FUNCTION__);
- return FALSE;
+ if (x == 0 && y == 0 &&
+ w == pixmap->drawable.width &&
+ h == pixmap->drawable.height)
+ {
+ intel_screen_private *intel = intel_get_screen_private(xf86Screens[screen->myNum]);
+ uint32_t tiling = priv->tiling;
+ int size, stride;
+ dri_bo *bo;
+
+ /* Replace busy bo. */
+ size = i830_uxa_pixmap_compute_size (pixmap, w, h,
+ &tiling, &stride);
+ if (size > intel->max_gtt_map_size)
+ return FALSE;
+
+ bo = drm_intel_bo_alloc(intel->bufmgr, "pixmap", size, 0);
+ if (bo == NULL)
+ return FALSE;
+
+ if (tiling != I915_TILING_NONE)
+ drm_intel_bo_set_tiling(bo, &tiling, stride);
+
+ screen->ModifyPixmapHeader(pixmap,
+ w, h,
+ 0, 0,
+ stride, NULL);
+ i830_set_pixmap_bo(pixmap, bo);
+ dri_bo_unreference(bo);
+
+ return i830_uxa_pixmap_put_image(pixmap, src, src_pitch, 0, 0, w, h);
}
-
- ret = TRUE;
-
- /* Older version of pixman did not allow blt for <= 8bpp
- * images, so if the blt fails fallback to using the fb.
- */
- dst_pitch = i830_pixmap_pitch (pixmap);
- if (! pixman_blt((uint32_t *)src,
- priv->bo->virtual,
- src_pitch / sizeof(uint32_t),
- dst_pitch / sizeof(uint32_t),
- pixmap->drawable.bitsPerPixel,
- pixmap->drawable.bitsPerPixel,
- 0, 0,
- x, y,
- w, h))
+ else
{
- ret = FALSE;
-
- scratch = GetScratchPixmapHeader(screen,
- w, h,
- pixmap->drawable.depth,
- pixmap->drawable.bitsPerPixel,
- src_pitch,
- (pointer) src);
- if (scratch) {
- gc = GetScratchGC(pixmap->drawable.depth, screen);
+ PixmapPtr scratch;
+ Bool ret;
+
+ /* Upload to a linear buffer and queue a blit. */
+ scratch = (*screen->CreatePixmap)(screen, w, h,
+ pixmap->drawable.depth,
+ UXA_CREATE_PIXMAP_FOR_MAP);
+ if (!scratch)
+ return FALSE;
+
+ ret = i830_uxa_pixmap_put_image(scratch, src, src_pitch, 0, 0, w, h);
+ if (ret) {
+ GCPtr gc = GetScratchGC(pixmap->drawable.depth, screen);
if (gc) {
ValidateGC(&pixmap->drawable, gc);
- pixmap->devPrivate.ptr = priv->bo->virtual;
- ret = !! fbCopyArea(&scratch->drawable, &pixmap->drawable, gc,
- 0, 0,
- w, h,
- x, y);
+
+ (*gc->ops->CopyArea)(&scratch->drawable,
+ &pixmap->drawable,
+ gc, 0, 0, w, h, x, y);
+
FreeScratchGC(gc);
- }
- FreeScratchPixmapHeader(scratch);
+ } else
+ ret = FALSE;
}
- }
- drm_intel_gem_bo_unmap_gtt(priv->bo);
+ (*screen->DestroyPixmap)(scratch);
+ return ret;
+ }
}
-
- return ret;
}
void i830_uxa_block_handler(ScreenPtr screen)
@@ -1024,25 +947,26 @@ i830_uxa_create_pixmap(ScreenPtr screen, int w, int h, int depth,
return NullPixmap;
}
- if (usage == UXA_CREATE_PIXMAP_FOR_MAP)
+ if (usage == UXA_CREATE_PIXMAP_FOR_MAP) {
+ priv->busy = 0;
priv->bo = drm_intel_bo_alloc(intel->bufmgr,
"pixmap", size, 0);
- else
+ } else {
+ priv->busy = -1;
priv->bo = drm_intel_bo_alloc_for_render(intel->bufmgr,
"pixmap",
size, 0);
+ }
if (!priv->bo) {
free(priv);
fbDestroyPixmap(pixmap);
return NullPixmap;
}
+ if (tiling != I915_TILING_NONE)
+ drm_intel_bo_set_tiling(priv->bo, &tiling, stride);
priv->stride = stride;
priv->tiling = tiling;
- if (priv->tiling != I915_TILING_NONE)
- drm_intel_bo_set_tiling(priv->bo,
- &priv->tiling,
- stride);
screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, stride, NULL);
@@ -1072,6 +996,7 @@ void i830_uxa_create_screen_resources(ScreenPtr screen)
if (bo != NULL) {
PixmapPtr pixmap = screen->GetScreenPixmap(screen);
i830_set_pixmap_bo(pixmap, bo);
+ i830_get_pixmap_intel(pixmap)->busy = 1;
}
}
commit 2ff7a2fc9d939554502e9adec89cae5597a9e82c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Jun 17 13:56:30 2010 +0100
i915: Force the emission of BUF_INFO on every composite_setup
We should be able to eliminate these as the drawable remains unchanged.
However, the implicit flush of BUF_INFO fixes the rendering in KDE.
Alternatively, we need an MI_FLUSH | INHIBIT_RENDER_CACHE_FLUSH between
composites. (Note that it is not stale cache data causing the rendering
corruption and that a pipelined flush is not sufficient either.) Also,
having tried varies points at which to flush, the only place where the
flush is effective seems to be between composite operations - that is a
flush after 2D is not sufficient.
Reported-by: Vasily Khoruzhick <anarsoul at gmail.com>
Reported-by: Clemens Eisserer <linuxhippy at gmail.com>
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/i915_render.c b/src/i915_render.c
index b2bc7a7..782c259 100644
--- a/src/i915_render.c
+++ b/src/i915_render.c
@@ -1032,10 +1032,15 @@ static void i915_emit_composite_setup(ScrnInfoPtr scrn)
OUT_BATCH (intel->render_mask_solid);
}
- /* BUF_INFO is an implicit flush, so avoid if the target has not changed */
- if (dest != intel->render_current_dest) {
+ /* BUF_INFO is an implicit flush, so avoid if the target has not changed.
+ * XXX However for reasons unfathomed, correct rendering in KDE requires
+ * at least a MI_FLUSH | INHIBIT_RENDER_CACHE_FLUSH here.
+ */
+ if (1 || dest != intel->render_current_dest) {
uint32_t tiling_bits;
+ intel_batch_do_flush(scrn);
+
if (i830_pixmap_tiled(dest)) {
tiling_bits = BUF_3D_TILED_SURFACE;
if (i830_get_pixmap_intel(dest)->tiling
More information about the xorg-commit
mailing list