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; } } }
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); } }
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); } }
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; }