ソースを参照

intel: Use the new DRI2 flush invalidate entrypoint to signal frame done.

Previously for frame throttling we would wait on the first batch after
a swap before emitting another swap, because we had no hook after a
swap was emitted.  This meant that if an app managed to squeeze
everything it for a frame had into one batch, it would lock-step with
the GPU.  With the swapbuffers changes, we now have the entrypoint we
want.

This takes the WoW intro screen from 25% GPU idle and visibly jerky to
4-5% GPU idle and rather smooth.  Other apps such as OpenArena have
run into this problem as well.
tags/7.8-rc1
Eric Anholt 15年前
コミット
7d4e674b21
2個のファイルの変更21行の追加20行の削除
  1. 0
    20
      src/mesa/drivers/dri/intel/intel_context.c
  2. 21
    0
      src/mesa/drivers/dri/intel/intel_screen.c

+ 0
- 20
src/mesa/drivers/dri/intel/intel_context.c ファイルの表示

@@ -506,27 +506,7 @@ intelFlush(GLcontext * ctx)
static void
intel_glFlush(GLcontext *ctx)
{
struct intel_context *intel = intel_context(ctx);

intel_flush(ctx, GL_TRUE);

/* We're using glFlush as an indicator that a frame is done, which is
* what DRI2 does before calling SwapBuffers (and means we should catch
* people doing front-buffer rendering, as well)..
*
* Wait for the swapbuffers before the one we just emitted, so we don't
* get too many swaps outstanding for apps that are GPU-heavy but not
* CPU-heavy.
*
* Unfortunately, we don't have a handle to the batch containing the swap,
* and getting our hands on that doesn't seem worth it, so we just us the
* first batch we emitted after the last swap.
*/
if (intel->first_post_swapbuffers_batch != NULL) {
drm_intel_bo_wait_rendering(intel->first_post_swapbuffers_batch);
drm_intel_bo_unreference(intel->first_post_swapbuffers_batch);
intel->first_post_swapbuffers_batch = NULL;
}
}

void

+ 21
- 0
src/mesa/drivers/dri/intel/intel_screen.c ファイルの表示

@@ -128,8 +128,29 @@ intelDRI2Flush(__DRIdrawable *drawable)
static void
intelDRI2FlushInvalidate(__DRIdrawable *drawable)
{
struct intel_context *intel = drawable->driContextPriv->driverPrivate;

intelDRI2Flush(drawable);
drawable->validBuffers = GL_FALSE;

/* We're using FlushInvalidate as an indicator that a frame is
* done. It's only called immediately after SwapBuffers, so it
* won't affect front-buffer rendering or applications explicitly
* managing swap regions using MESA_copy_buffer.
*
* Wait for the swapbuffers before the one we just emitted, so we don't
* get too many swaps outstanding for apps that are GPU-heavy but not
* CPU-heavy.
*
* Unfortunately, we don't have a handle to the batch containing the swap,
* and getting our hands on that doesn't seem worth it, so we just use the
* first batch we emitted after the last swap.
*/
if (intel->first_post_swapbuffers_batch != NULL) {
drm_intel_bo_wait_rendering(intel->first_post_swapbuffers_batch);
drm_intel_bo_unreference(intel->first_post_swapbuffers_batch);
intel->first_post_swapbuffers_batch = NULL;
}
}

static const struct __DRI2flushExtensionRec intelFlushExtension = {

読み込み中…
キャンセル
保存