+ sbuf->dma.flags.unsynchronized = TRUE;
+ }
+ } else {
+ /*
+ * Synchronizing, so flush any pending primitives, finish writing any
+ * pending DMA command, and ensure the next DMA will be done in order.
+ */
+
+ svga_hwtnl_flush_buffer(svga, resource);
+
+ if (sbuf->dma.pending) {
+ svga_buffer_upload_flush(svga, sbuf);
+
+ if (svga_buffer_has_hw_storage(sbuf)) {
+ /*
+ * We have a pending DMA upload from a hardware buffer, therefore
+ * we need to ensure that the host finishes processing that DMA
+ * command before the state tracker can start overwriting the
+ * hardware buffer.
+ *
+ * XXX: This could be avoided by tying the hardware buffer to
+ * the transfer (just as done with textures), which would allow
+ * overlapping DMAs commands to be queued on the same context
+ * buffer. However, due to the likelihood of software vertex
+ * processing, it is more convenient to hold on to the hardware
+ * buffer, allowing to quickly access the contents from the CPU
+ * without having to do a DMA download from the host.
+ */
+
+ if (usage & PIPE_TRANSFER_DONTBLOCK) {
+ /*
+ * Flushing the command buffer here will most likely cause
+ * the map of the hwbuf below to block, so preemptively
+ * return NULL here if DONTBLOCK is set to prevent unnecessary
+ * command buffer flushes.
+ */
+
+ FREE(transfer);
+ goto done;
+ }
+
+ svga_context_flush(svga, NULL);
+ }
+ }
+
+ sbuf->dma.flags.unsynchronized = FALSE;
+ }
+ }
+
+ if (!sbuf->swbuf && !svga_buffer_has_hw_storage(sbuf)) {
+ if (svga_buffer_create_hw_storage(ss, sbuf, sbuf->bind_flags) != PIPE_OK) {