xf86-video-intel: 4 commits - src/sna/gen3_render.c src/sna/kgem.h src/sna/sna_display.c src/sna/sna_dri.c
Chris Wilson
ickle at kemper.freedesktop.org
Fri Jul 8 02:01:00 PDT 2011
src/sna/gen3_render.c | 5 -
src/sna/kgem.h | 5 +
src/sna/sna_display.c | 6 +
src/sna/sna_dri.c | 179 ++++++++++++++++++++++++++++++++++++++------------
4 files changed, 151 insertions(+), 44 deletions(-)
New commits:
commit 1e2cae0ab339e477929e429f8ff31b11fcaf2cbf
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Jul 8 09:54:43 2011 +0100
sna/gen3: Restore disabling the use of stencil/fog in the invariant
One cleanup too far causing spurious results after rebooting. We also
need to ensure that the writemask is fully enabled (ie not disabled)
as well.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index 4b59f40..464e87b 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -1082,12 +1082,13 @@ static void gen3_emit_invariant(struct sna *sna)
CSB_TCB(6, 6) |
CSB_TCB(7, 7));
- OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | I1_LOAD_S(4) | 1);
- OUT_BATCH(0x00000000); /* Disable texture coordinate wrap-shortest */
+ OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | I1_LOAD_S(4) | I1_LOAD_S(5) | 1);
+ OUT_BATCH(0); /* Disable texture coordinate wrap-shortest */
OUT_BATCH((1 << S4_POINT_WIDTH_SHIFT) |
S4_LINE_WIDTH_ONE |
S4_CULLMODE_NONE |
S4_VFMT_XY);
+ OUT_BATCH(0); /* Disable fog/stencil. *Enable* write mask. */
OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT);
OUT_BATCH(_3DSTATE_DEPTH_SUBRECT_DISABLE);
commit ec3dd64e739c4c2bbd8141de5275fe8a90f24a57
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Jul 8 00:17:27 2011 +0100
sna/dri: Enable chaining of page-flips
Trade off extra frames of latency for extra frames of anti-jitter
buffering and loss of completion information; compiz users rejoice.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index c89a7d2..2a8a865 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -76,11 +76,14 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define NDEBUG 1
#endif
+#define NO_TRIPPLE_BUFFER 0
+
enum frame_event_type {
DRI2_SWAP,
DRI2_SWAP_THROTTLE,
DRI2_ASYNC_FLIP,
DRI2_FLIP,
+ DRI2_FLIP_THROTTLE,
DRI2_WAITMSC,
};
@@ -113,6 +116,8 @@ struct sna_dri_frame_event {
PixmapPtr old_front;
PixmapPtr next_front;
uint32_t old_fb;
+
+ struct sna_dri_frame_event *chain;
};
static inline struct sna_dri_frame_event *
@@ -833,10 +838,69 @@ done:
sna_dri_frame_event_info_free(info);
}
+static int
+sna_dri_flip(struct sna *sna, DrawablePtr draw, struct sna_dri_frame_event *info)
+{
+ struct sna_dri_private *front_priv = info->front->driverPrivate;
+ struct sna_dri_frame_event *pending;
+ ScreenPtr screen = draw->pScreen;
+ PixmapPtr pixmap;
+
+ if (NO_TRIPPLE_BUFFER)
+ return sna_dri_schedule_flip(sna, draw, info);
+
+ info->type = DRI2_FLIP_THROTTLE;
+
+ pending = sna->dri.flip_pending[info->pipe];
+ if (pending) {
+ if (pending->type != DRI2_FLIP_THROTTLE) {
+ /* We need to first wait (one vblank) for the
+ * async flips to complete beofore this client can
+ * take over.
+ */
+ info->type = DRI2_FLIP;
+ return sna_dri_schedule_flip(sna, draw, info);
+ }
+
+ DBG(("%s: chaining flip\n", __FUNCION__));
+ assert(pending->chain == NULL);
+ pending->chain = info;
+ return TRUE;
+ }
+
+ if (!sna_dri_schedule_flip(sna, draw, info))
+ return FALSE;
+
+ info->old_front =
+ sna_set_screen_pixmap(sna, get_pixmap(info->back));
+ sna->dri.flip_pending[info->pipe] = info;
+
+ if ((pixmap = screen->CreatePixmap(screen,
+ draw->width,
+ draw->height,
+ draw->depth,
+ SNA_CREATE_FB))) {
+ DBG(("%s: new back buffer\n", __FUNCTION__));
+ front_priv->pixmap->refcnt--;
+ front_priv->pixmap = pixmap;
+ front_priv->bo = sna_pixmap_set_dri(sna, pixmap);
+ info->front->name = kgem_bo_flink(&sna->kgem, front_priv->bo);
+ info->front->pitch = front_priv->bo->pitch;
+ }
+
+ sna_dri_exchange_buffers(draw, info->front, info->back);
+ DRI2SwapComplete(info->client, draw, 0, 0, 0,
+ DRI2_EXCHANGE_COMPLETE,
+ info->event_complete,
+ info->event_data);
+ return TRUE;
+}
+
static void sna_dri_flip_event(struct sna *sna,
struct sna_dri_frame_event *flip)
{
DrawablePtr drawable;
+ struct sna_dri_frame_event *chain;
int status;
DBG(("%s(frame=%d, tv=%d.%06d, type=%d)\n",
@@ -854,45 +918,76 @@ static void sna_dri_flip_event(struct sna *sna,
* into account. This usually means some defective kms pageflip completion,
* causing wrong (msc, ust) return values and possible visual corruption.
*/
- if (!flip->drawable_id)
- return;
-
- status = dixLookupDrawable(&drawable,
- flip->drawable_id,
- serverClient,
- M_ANY, DixWriteAccess);
- if (status != Success)
- return;
-
- if ((flip->fe_frame < flip->frame) &&
- (flip->frame - flip->fe_frame < 5)) {
- static int limit = 5;
-
- /* XXX we are currently hitting this path with older
- * kernels, so make it quieter.
- */
- if (limit) {
- xf86DrvMsg(sna->scrn->scrnIndex, X_WARNING,
- "%s: Pageflip completion has impossible msc %d < target_msc %d\n",
- __func__, flip->fe_frame, flip->frame);
- limit--;
+ if (flip->drawable_id) {
+ status = dixLookupDrawable(&drawable,
+ flip->drawable_id,
+ serverClient,
+ M_ANY, DixWriteAccess);
+ if (status == Success) {
+ if ((flip->fe_frame < flip->frame) &&
+ (flip->frame - flip->fe_frame < 5)) {
+ static int limit = 5;
+
+ /* XXX we are currently hitting this path with older
+ * kernels, so make it quieter.
+ */
+ if (limit) {
+ xf86DrvMsg(sna->scrn->scrnIndex, X_WARNING,
+ "%s: Pageflip completion has impossible msc %d < target_msc %d\n",
+ __func__, flip->fe_frame, flip->frame);
+ limit--;
+ }
+
+ /* All-0 values signal timestamping failure. */
+ flip->fe_frame = flip->fe_tv_sec = flip->fe_tv_usec = 0;
+ }
+
+ DBG(("%s: flip complete\n", __FUNCTION__));
+ DRI2SwapComplete(flip->client, drawable,
+ flip->fe_frame,
+ flip->fe_tv_sec,
+ flip->fe_tv_usec,
+ DRI2_FLIP_COMPLETE,
+ flip->client ? flip->event_complete : NULL,
+ flip->event_data);
}
-
- /* All-0 values signal timestamping failure. */
- flip->fe_frame = flip->fe_tv_sec = flip->fe_tv_usec = 0;
}
- DBG(("%s: flip complete\n", __FUNCTION__));
- DRI2SwapComplete(flip->client, drawable,
- flip->fe_frame,
- flip->fe_tv_sec,
- flip->fe_tv_usec,
- DRI2_FLIP_COMPLETE,
- flip->client ? flip->event_complete : NULL,
- flip->event_data);
+ sna_mode_delete_fb(flip->sna, flip->old_front, flip->old_fb);
+ sna_dri_frame_event_info_free(flip);
+ break;
+
+ case DRI2_FLIP_THROTTLE:
+ assert(sna->dri.flip_pending[flip->pipe] == flip);
+ sna->dri.flip_pending[flip->pipe] = NULL;
+
+ chain = flip->chain;
sna_mode_delete_fb(flip->sna, flip->old_front, flip->old_fb);
sna_dri_frame_event_info_free(flip);
+
+ if (chain) {
+ status = dixLookupDrawable(&drawable,
+ chain->drawable_id,
+ serverClient,
+ M_ANY, DixWriteAccess);
+ if (status == Success) {
+ if (!(can_flip(chain->sna, drawable,
+ chain->front, chain->back) &&
+ sna_dri_flip(chain->sna, drawable, chain))) {
+ sna_dri_copy(sna, drawable, NULL,
+ chain->front, chain->back, true);
+ DRI2SwapComplete(chain->client,
+ drawable,
+ 0, 0, 0,
+ DRI2_BLIT_COMPLETE,
+ chain->client ? chain->event_complete : NULL,
+ chain->event_data);
+ sna_dri_frame_event_info_free(chain);
+ }
+ } else
+ sna_dri_frame_event_info_free(chain);
+ }
break;
case DRI2_ASYNC_FLIP:
@@ -1052,12 +1147,8 @@ sna_dri_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
info->type = swap_type;
if (divisor == 0) {
DBG(("%s: performing immediate swap\n", __FUNCTION__));
- if (flip && sna_dri_schedule_flip(sna, draw, info)) {
- info->old_front =
- sna_set_screen_pixmap(sna, get_pixmap(back));
- sna_dri_exchange_buffers(draw, front, back);
+ if (flip && sna_dri_flip(sna, draw, info))
return TRUE;
- }
DBG(("%s: emitting immediate vsync'ed blit, throttling client\n",
__FUNCTION__));
@@ -1200,6 +1291,7 @@ sna_dri_async_swap(ClientPtr client, DrawablePtr draw,
DBG(("%s()\n", __FUNCTION__));
if (!can_flip(sna, draw, front, back)) {
+blit:
sna_dri_copy(sna, draw, NULL, front, back, false);
DRI2SwapComplete(client, draw, 0, 0, 0,
DRI2_BLIT_COMPLETE, func, data);
@@ -1259,6 +1351,11 @@ sna_dri_async_swap(ClientPtr client, DrawablePtr draw,
front->name = kgem_bo_flink(&sna->kgem, front_priv->bo);
front->pitch = front_priv->bo->pitch;
}
+ } else if (info->type != DRI2_ASYNC_FLIP) {
+ /* A normal vsync'ed client is finishing, wait for it
+ * to unpin the old framebuffer before taking* pver.
+ */
+ goto blit;
}
if (front_priv->pixmap == info->next_front &&
commit a32694b0f07e35c22dd83bcfb828196d5d86628e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Jul 7 23:11:39 2011 +0100
sna/dri: Remove redundant NULL check in reference
The buffer has already been dereferenced by this point...
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index b75c46e..c89a7d2 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -316,10 +316,8 @@ static void sna_dri_destroy_buffer(DrawablePtr drawable, DRI2Buffer2Ptr buffer)
static void sna_dri_reference_buffer(DRI2Buffer2Ptr buffer)
{
- if (buffer) {
- struct sna_dri_private *private = buffer->driverPrivate;
- private->refcnt++;
- }
+ struct sna_dri_private *private = buffer->driverPrivate;
+ private->refcnt++;
}
static void damage(DrawablePtr drawable, PixmapPtr pixmap, RegionPtr region)
commit d180c5f5f781f4fa7f747dd7bb8073a20771cd79
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed Jul 6 20:19:00 2011 +0100
sna: Take advantage of the needs_flush tracking on the front buffer
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index 6c1f656..2ad975a 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -181,8 +181,13 @@ static inline void kgem_bo_submit(struct kgem *kgem, struct kgem_bo *bo)
void __kgem_flush(struct kgem *kgem, struct kgem_bo *bo);
static inline void kgem_bo_flush(struct kgem *kgem, struct kgem_bo *bo)
{
+ if (!bo->needs_flush)
+ return;
+
kgem_bo_submit(kgem, bo);
__kgem_flush(kgem, bo);
+
+ bo->needs_flush = false;
}
static inline struct kgem_bo *kgem_bo_reference(struct kgem_bo *bo)
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 1586884..b3b3185 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -1787,6 +1787,12 @@ sna_do_pageflip(struct sna *sna,
sna->mode.fb_pixmap = pixmap->drawable.serialNumber;
bo->cpu_read = bo->cpu_write = false;
bo->gpu = true;
+
+ /* Although the kernel performs an implicit flush upon
+ * page-flipping, marking the bo as requiring a flush
+ * here ensures that the buffer goes into the active cache
+ * upon release.
+ */
bo->needs_flush = true;
} else {
drmModeRmFB(sna->kgem.fd, mode->fb_id);
More information about the xorg-commit
mailing list