+void
+softpipe_flush_wrapped(struct pipe_context *pipe,
+ struct pipe_fence_handle **fence,
+ unsigned flags)
+{
+ softpipe_flush(pipe, SP_FLUSH_TEXTURE_CACHE, fence);
+}
+
+
+/**
+ * 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
+softpipe_flush_resource(struct pipe_context *pipe,
+ struct pipe_resource *texture,
+ unsigned level,
+ int layer,
+ unsigned flush_flags,
+ boolean read_only,
+ boolean cpu_access,
+ boolean do_not_block)
+{
+ unsigned referenced;
+
+ referenced = softpipe_is_resource_referenced(pipe, texture, level, layer);
+
+ if ((referenced & SP_REFERENCED_FOR_WRITE) ||
+ ((referenced & SP_REFERENCED_FOR_READ) && !read_only)) {
+
+ /*
+ * TODO: The semantics of these flush flags are too obtuse. They should
+ * disappear and the pipe driver should just ensure that all visible
+ * side-effects happen when they need to happen.
+ */
+ if (referenced & SP_REFERENCED_FOR_READ)
+ flush_flags |= SP_FLUSH_TEXTURE_CACHE;
+
+ if (cpu_access) {
+ /*
+ * Flush and wait.
+ */
+
+ struct pipe_fence_handle *fence = NULL;
+
+ if (do_not_block)
+ return FALSE;
+
+ softpipe_flush(pipe, flush_flags, &fence);
+
+ if (fence) {
+ /*
+ * This is for illustrative purposes only, as softpipe does not
+ * have fences.
+ */
+ pipe->screen->fence_finish(pipe->screen, fence,
+ PIPE_TIMEOUT_INFINITE);
+ pipe->screen->fence_reference(pipe->screen, &fence, NULL);
+ }
+ } else {
+ /*
+ * Just flush.
+ */
+
+ softpipe_flush(pipe, flush_flags, NULL);
+ }
+ }
+
+ return TRUE;
+}