Example #1
0
static void
intel_flush_front(struct gl_context *ctx)
{
   struct brw_context *brw = brw_context(ctx);
    __DRIcontext *driContext = brw->driContext;
    __DRIdrawable *driDrawable = driContext->driDrawablePriv;
    __DRIscreen *const screen = brw->intelScreen->driScrnPriv;

    if (brw->front_buffer_dirty && _mesa_is_winsys_fbo(ctx->DrawBuffer)) {
      if (screen->dri2.loader->flushFrontBuffer != NULL &&
          driDrawable &&
          driDrawable->loaderPrivate) {

         /* Resolve before flushing FAKE_FRONT_LEFT to FRONT_LEFT.
          *
          * This potentially resolves both front and back buffer. It
          * is unnecessary to resolve the back, but harms nothing except
          * performance. And no one cares about front-buffer render
          * performance.
          */
         intel_resolve_for_dri2_flush(brw, driDrawable);

         screen->dri2.loader->flushFrontBuffer(driDrawable,
                                               driDrawable->loaderPrivate);

	 /* We set the dirty bit in intel_prepare_render() if we're
	  * front buffer rendering once we get there.
	  */
	 brw->front_buffer_dirty = false;
      }
   }
}
Example #2
0
static void
intel_dri2_flush_with_flags(__DRIcontext *cPriv,
                            __DRIdrawable *dPriv,
                            unsigned flags,
                            enum __DRI2throttleReason reason)
{
   struct brw_context *brw = cPriv->driverPrivate;

   if (!brw)
      return;

   struct gl_context *ctx = &brw->ctx;

   FLUSH_VERTICES(ctx, 0);

   if (flags & __DRI2_FLUSH_DRAWABLE)
      intel_resolve_for_dri2_flush(brw, dPriv);

   if (reason == __DRI2_THROTTLE_SWAPBUFFER)
      brw->need_swap_throttle = true;
   if (reason == __DRI2_THROTTLE_FLUSHFRONT)
      brw->need_flush_throttle = true;

   intel_batchbuffer_flush(brw);

   if (INTEL_DEBUG & DEBUG_AUB) {
      aub_dump_bmp(ctx);
   }
}
Example #3
0
static void
intelDRI2Flush(__DRIdrawable *drawable)
{
   GET_CURRENT_CONTEXT(ctx);
   struct brw_context *brw = brw_context(ctx);
   if (brw == NULL)
      return;

   intel_resolve_for_dri2_flush(brw, drawable);
   brw->need_throttle = true;

   if (brw->batch.used)
      intel_batchbuffer_flush(brw);

   if (INTEL_DEBUG & DEBUG_AUB) {
      aub_dump_bmp(ctx);
   }
}
Example #4
0
static bool MUST_CHECK
brw_fence_insert_locked(struct brw_context *brw, struct brw_fence *fence)
{
   __DRIcontext *driContext = brw->driContext;
   __DRIdrawable *driDrawable = driContext->driDrawablePriv;

   /*
    * From KHR_fence_sync:
    *
    *   When the condition of the sync object is satisfied by the fence
    *   command, the sync is signaled by the associated client API context,
    *   causing any eglClientWaitSyncKHR commands (see below) blocking on
    *   <sync> to unblock. The only condition currently supported is
    *   EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR, which is satisfied by
    *   completion of the fence command corresponding to the sync object,
    *   and all preceding commands in the associated client API context's
    *   command stream. The sync object will not be signaled until all
    *   effects from these commands on the client API's internal and
    *   framebuffer state are fully realized. No other state is affected by
    *   execution of the fence command.
    *
    * Note the emphasis there on ensuring that the framebuffer is fully
    * realised before the fence is signaled. We cannot just flush the batch,
    * but must also resolve the drawable first. The importance of this is,
    * for example, in creating a fence for a frame to be passed to a
    * remote compositor. Without us flushing the drawable explicitly, the
    * resolve will be in a following batch (when the client finally calls
    * SwapBuffers, or triggers a resolve via some other path) and so the
    * compositor may read the incomplete framebuffer instead.
    */
   if (driDrawable)
      intel_resolve_for_dri2_flush(brw, driDrawable);
   brw_emit_mi_flush(brw);

   switch (fence->type) {
   case BRW_FENCE_TYPE_BO_WAIT:
      assert(!fence->batch_bo);
      assert(!fence->signalled);

      fence->batch_bo = brw->batch.bo;
      brw_bo_reference(fence->batch_bo);

      if (intel_batchbuffer_flush(brw) < 0) {
         brw_bo_unreference(fence->batch_bo);
         fence->batch_bo = NULL;
         return false;
      }
      break;
   case BRW_FENCE_TYPE_SYNC_FD:
      assert(!fence->signalled);

      if (fence->sync_fd == -1) {
         /* Create an out-fence that signals after all pending commands
          * complete.
          */
         if (intel_batchbuffer_flush_fence(brw, -1, &fence->sync_fd) < 0)
            return false;
         assert(fence->sync_fd != -1);
      } else {
         /* Wait on the in-fence before executing any subsequently submitted
          * commands.
          */
         if (intel_batchbuffer_flush(brw) < 0)
            return false;

         /* Emit a dummy batch just for the fence. */
         brw_emit_mi_flush(brw);
         if (intel_batchbuffer_flush_fence(brw, fence->sync_fd, NULL) < 0)
            return false;
      }
      break;
   }

   return true;
}