xf86-video-intel: src/sna/kgem.c src/sna/kgem.h src/sna/sna_display.c
Chris Wilson
ickle at kemper.freedesktop.org
Fri Apr 12 03:40:26 PDT 2013
src/sna/kgem.c | 88 +++++++++++++++++++++++++++++++++++++-------------
src/sna/kgem.h | 5 ++
src/sna/sna_display.c | 23 +++++++------
3 files changed, 84 insertions(+), 32 deletions(-)
New commits:
commit 9dae6f9f1f169c228929185a8bd94e82afe92574
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Apr 12 11:01:08 2013 +0100
sna: Flush the scanout cache after resizing the display
And ensure that any new scanout allocations make the requested size.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 4b13cc0..a2bb688 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1603,6 +1603,17 @@ inline static void kgem_bo_remove_from_active(struct kgem *kgem,
assert(list_is_empty(&bo->vma));
}
+static void _kgem_bo_delete_buffer(struct kgem *kgem, struct kgem_bo *bo)
+{
+ struct kgem_buffer *io = (struct kgem_buffer *)bo->proxy;
+
+ DBG(("%s: size=%d, offset=%d, parent used=%d\n",
+ __FUNCTION__, bo->size.bytes, bo->delta, io->used));
+
+ if (ALIGN(bo->delta + bo->size.bytes, UPLOAD_ALIGNMENT) == io->used)
+ io->used = bo->delta;
+}
+
static void kgem_bo_clear_scanout(struct kgem *kgem, struct kgem_bo *bo)
{
assert(bo->scanout);
@@ -1627,15 +1638,31 @@ static void kgem_bo_clear_scanout(struct kgem *kgem, struct kgem_bo *bo)
bo->reusable = false;
}
-static void _kgem_bo_delete_buffer(struct kgem *kgem, struct kgem_bo *bo)
+static bool check_scanout_size(struct kgem *kgem,
+ struct kgem_bo *bo,
+ int width, int height)
{
- struct kgem_buffer *io = (struct kgem_buffer *)bo->proxy;
+ struct drm_mode_fb_cmd info;
- DBG(("%s: size=%d, offset=%d, parent used=%d\n",
- __FUNCTION__, bo->size.bytes, bo->delta, io->used));
+ assert(bo->scanout);
- if (ALIGN(bo->delta + bo->size.bytes, UPLOAD_ALIGNMENT) == io->used)
- io->used = bo->delta;
+ VG_CLEAR(info);
+ info.fb_id = bo->delta;
+
+ if (drmIoctl(kgem->fd, DRM_IOCTL_MODE_GETFB, &info))
+ return false;
+
+ gem_close(kgem->fd, info.handle);
+
+ if (width != info.width || height != info.height) {
+ DBG(("%s: not using scanout %d (%dx%d), want (%dx%d)\n",
+ __FUNCTION__,
+ info.fb_id, info.width, info.height,
+ width, height))
+ return false;
+ }
+
+ return true;
}
static void kgem_bo_move_to_scanout(struct kgem *kgem, struct kgem_bo *bo)
@@ -2771,6 +2798,31 @@ void kgem_purge_cache(struct kgem *kgem)
kgem->need_purge = false;
}
+void kgem_clean_scanout_cache(struct kgem *kgem)
+{
+ while (!list_is_empty(&kgem->scanout)) {
+ struct kgem_bo *bo;
+
+ bo = list_first_entry(&kgem->scanout, struct kgem_bo, list);
+ if (__kgem_busy(kgem, bo->handle))
+ break;
+
+ list_del(&bo->list);
+ kgem_bo_clear_scanout(kgem, bo);
+ __kgem_bo_destroy(kgem, bo);
+ }
+}
+
+void kgem_clean_large_cache(struct kgem *kgem)
+{
+ while (!list_is_empty(&kgem->large_inactive)) {
+ kgem_bo_free(kgem,
+ list_first_entry(&kgem->large_inactive,
+ struct kgem_bo, list));
+
+ }
+}
+
bool kgem_expire_cache(struct kgem *kgem)
{
time_t now, expire;
@@ -2793,22 +2845,8 @@ bool kgem_expire_cache(struct kgem *kgem)
free(rq);
}
- while (!list_is_empty(&kgem->large_inactive)) {
- kgem_bo_free(kgem,
- list_first_entry(&kgem->large_inactive,
- struct kgem_bo, list));
-
- }
-
- while (!list_is_empty(&kgem->scanout)) {
- bo = list_first_entry(&kgem->scanout, struct kgem_bo, list);
- if (__kgem_busy(kgem, bo->handle))
- break;
-
- list_del(&bo->list);
- kgem_bo_clear_scanout(kgem, bo);
- __kgem_bo_destroy(kgem, bo);
- }
+ kgem_clean_large_cache(kgem);
+ kgem_clean_scanout_cache(kgem);
expire = 0;
list_for_each_entry(bo, &kgem->snoop, list) {
@@ -2962,6 +3000,9 @@ void kgem_cleanup_cache(struct kgem *kgem)
struct kgem_bo, list));
}
+ kgem_clean_large_cache(kgem);
+ kgem_clean_scanout_cache(kgem);
+
while (!list_is_empty(&kgem->snoop))
kgem_bo_free(kgem,
list_last_entry(&kgem->snoop,
@@ -3576,6 +3617,9 @@ struct kgem_bo *kgem_create_2d(struct kgem *kgem,
if (size > num_pages(bo) || num_pages(bo) > 2*size)
continue;
+ if (!check_scanout_size(kgem, bo, width, height))
+ continue;
+
if (bo->tiling != tiling ||
(tiling != I915_TILING_NONE && bo->pitch != pitch)) {
if (!gem_set_tiling(kgem->fd, bo->handle,
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index e486292..3086f17 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -194,10 +194,10 @@ struct kgem {
void (*retire)(struct kgem *kgem);
void (*expire)(struct kgem *kgem);
+ uint16_t reloc__self[256];
uint32_t batch[64*1024-8] page_aligned;
struct drm_i915_gem_exec_object2 exec[256] page_aligned;
struct drm_i915_gem_relocation_entry reloc[4096] page_aligned;
- uint16_t reloc__self[256];
#ifdef DEBUG_MEMORY
struct {
@@ -682,6 +682,9 @@ bool kgem_expire_cache(struct kgem *kgem);
void kgem_purge_cache(struct kgem *kgem);
void kgem_cleanup_cache(struct kgem *kgem);
+void kgem_clean_scanout_cache(struct kgem *kgem);
+void kgem_clean_large_cache(struct kgem *kgem);
+
#if HAS_DEBUG_FULL
void __kgem_batch_debug(struct kgem *kgem, uint32_t nbatch);
#else
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 0d32086..ba9bf79 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -103,6 +103,14 @@ static inline struct sna_crtc *to_sna_crtc(xf86CrtcPtr crtc)
return crtc->driver_private;
}
+static bool sna_mode_has_pending_events(struct sna *sna)
+{
+ struct pollfd pfd;
+ pfd.fd = sna->kgem.fd;
+ pfd.events = POLLIN;
+ return poll(&pfd, 1, 0) == 1;
+}
+
#define BACKLIGHT_CLASS "/sys/class/backlight"
/* Enough for 10 digits of backlight + '\n' + '\0' */
@@ -2601,6 +2609,11 @@ sna_mode_resize(ScrnInfoPtr scrn, int width, int height)
screen->DestroyPixmap(old_front);
+ while (sna_mode_has_pending_events(sna))
+ sna_mode_wakeup(sna);
+
+ kgem_clean_scanout_cache(&sna->kgem);
+
return TRUE;
}
@@ -2743,14 +2756,6 @@ bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna)
return true;
}
-static Bool sna_mode_has_pending_events(struct sna *sna)
-{
- struct pollfd pfd;
- pfd.fd = sna->kgem.fd;
- pfd.events = POLLIN;
- return poll(&pfd, 1, 0) == 1;
-}
-
void
sna_mode_close(struct sna *sna)
{
@@ -2761,7 +2766,7 @@ sna_mode_close(struct sna *sna)
* check that the fd is readable before attempting to read the next
* event from drm.
*/
- if (sna_mode_has_pending_events(sna))
+ while (sna_mode_has_pending_events(sna))
sna_mode_wakeup(sna);
for (i = 0; i < xf86_config->num_crtc; i++)
More information about the xorg-commit
mailing list