+void
+llvmpipe_finish( struct pipe_context *pipe,
+ const char *reason )
+{
+ struct pipe_fence_handle *fence = NULL;
+ llvmpipe_flush(pipe, &fence, reason);
+ if (fence) {
+ pipe->screen->fence_finish(pipe->screen, fence, PIPE_TIMEOUT_INFINITE);
+ pipe->screen->fence_reference(pipe->screen, &fence, NULL);
+ }
+}
+
+/**
+ * Flush context if necessary.
+ *
+ * Returns FALSE if it would have block, but do_not_block was set, TRUE
+ * otherwise.
+ *
+ * TODO: move this logic to an auxiliary library?
+ */
+boolean
+llvmpipe_flush_resource(struct pipe_context *pipe,
+ struct pipe_resource *resource,
+ unsigned level,
+ int layer,
+ boolean read_only,
+ boolean cpu_access,
+ boolean do_not_block,
+ const char *reason)
+{
+ unsigned referenced;
+
+ referenced = llvmpipe_is_resource_referenced(pipe, resource, level, layer);
+
+ if ((referenced & LP_REFERENCED_FOR_WRITE) ||
+ ((referenced & LP_REFERENCED_FOR_READ) && !read_only)) {
+
+ if (cpu_access) {
+ /*
+ * Flush and wait.
+ */
+ if (do_not_block)
+ return FALSE;
+
+ llvmpipe_finish(pipe, reason);
+ } else {
+ /*
+ * Just flush.
+ */
+
+ llvmpipe_flush(pipe, NULL, reason);
+ }
+ }
+
+ return TRUE;
+}