+void r600_preflush_suspend_features(struct r600_common_context *ctx)
+{
+ /* suspend queries */
+ if (ctx->num_cs_dw_nontimer_queries_suspend) {
+ /* Since non-timer queries are suspended during blits,
+ * we have to guard against double-suspends. */
+ r600_suspend_nontimer_queries(ctx);
+ ctx->nontimer_queries_suspended_by_flush = true;
+ }
+ if (!LIST_IS_EMPTY(&ctx->active_timer_queries))
+ r600_suspend_timer_queries(ctx);
+
+ ctx->streamout.suspended = false;
+ if (ctx->streamout.begin_emitted) {
+ r600_emit_streamout_end(ctx);
+ ctx->streamout.suspended = true;
+ }
+}
+
+void r600_postflush_resume_features(struct r600_common_context *ctx)
+{
+ if (ctx->streamout.suspended) {
+ ctx->streamout.append_bitmask = ctx->streamout.enabled_mask;
+ r600_streamout_buffers_dirty(ctx);
+ }
+
+ /* resume queries */
+ if (!LIST_IS_EMPTY(&ctx->active_timer_queries))
+ r600_resume_timer_queries(ctx);
+ if (ctx->nontimer_queries_suspended_by_flush) {
+ ctx->nontimer_queries_suspended_by_flush = false;
+ r600_resume_nontimer_queries(ctx);
+ }
+}
+
+static void r600_flush_from_st(struct pipe_context *ctx,
+ struct pipe_fence_handle **fence,
+ unsigned flags)
+{
+ struct pipe_screen *screen = ctx->screen;
+ struct r600_common_context *rctx = (struct r600_common_context *)ctx;
+ unsigned rflags = 0;
+ struct pipe_fence_handle *gfx_fence = NULL;
+ struct pipe_fence_handle *sdma_fence = NULL;
+
+ if (flags & PIPE_FLUSH_END_OF_FRAME)
+ rflags |= RADEON_FLUSH_END_OF_FRAME;
+
+ if (rctx->dma.cs) {
+ rctx->dma.flush(rctx, rflags, fence ? &sdma_fence : NULL);
+ }
+ rctx->gfx.flush(rctx, rflags, fence ? &gfx_fence : NULL);
+
+ /* Both engines can signal out of order, so we need to keep both fences. */
+ if (gfx_fence || sdma_fence) {
+ struct r600_multi_fence *multi_fence =
+ CALLOC_STRUCT(r600_multi_fence);
+ if (!multi_fence)
+ return;
+
+ multi_fence->reference.count = 1;
+ multi_fence->gfx = gfx_fence;
+ multi_fence->sdma = sdma_fence;
+
+ screen->fence_reference(screen, fence, NULL);
+ *fence = (struct pipe_fence_handle*)multi_fence;
+ }
+}
+
+static void r600_flush_dma_ring(void *ctx, unsigned flags,
+ struct pipe_fence_handle **fence)
+{
+ struct r600_common_context *rctx = (struct r600_common_context *)ctx;
+ struct radeon_winsys_cs *cs = rctx->dma.cs;
+
+ if (cs->cdw)
+ rctx->ws->cs_flush(cs, flags, &rctx->last_sdma_fence, 0);
+ if (fence)
+ rctx->ws->fence_reference(fence, rctx->last_sdma_fence);
+}
+
+static enum pipe_reset_status r600_get_reset_status(struct pipe_context *ctx)
+{
+ struct r600_common_context *rctx = (struct r600_common_context *)ctx;
+ unsigned latest = rctx->ws->query_value(rctx->ws,
+ RADEON_GPU_RESET_COUNTER);
+
+ if (rctx->gpu_reset_counter == latest)
+ return PIPE_NO_RESET;
+
+ rctx->gpu_reset_counter = latest;
+ return PIPE_UNKNOWN_CONTEXT_RESET;
+}
+
+static void r600_set_debug_callback(struct pipe_context *ctx,
+ const struct pipe_debug_callback *cb)
+{
+ struct r600_common_context *rctx = (struct r600_common_context *)ctx;
+
+ if (cb)
+ rctx->debug = *cb;
+ else
+ memset(&rctx->debug, 0, sizeof(rctx->debug));
+}
+