diff --git a/src/gallium/drivers/crocus/crocus_context.c b/src/gallium/drivers/crocus/crocus_context.c index d0758dc1a2a..44d947de84a 100644 --- a/src/gallium/drivers/crocus/crocus_context.c +++ b/src/gallium/drivers/crocus/crocus_context.c @@ -319,7 +319,15 @@ crocus_create_context(struct pipe_screen *pscreen, void *priv, unsigned flags) if (ice->batch_count > 1) screen->vtbl.init_compute_context(&ice->batches[CROCUS_BATCH_COMPUTE]); - return ctx; + if (!(flags & PIPE_CONTEXT_PREFER_THREADED)) + return ctx; + + return threaded_context_create(ctx, &screen->transfer_pool, + crocus_replace_buffer_storage, + NULL, /* TODO: asynchronous flushes? */ + NULL, + false, + &ice->thrctx); } bool diff --git a/src/gallium/drivers/crocus/crocus_context.h b/src/gallium/drivers/crocus/crocus_context.h index 9aab10655a7..15b41079ce1 100644 --- a/src/gallium/drivers/crocus/crocus_context.h +++ b/src/gallium/drivers/crocus/crocus_context.h @@ -442,6 +442,7 @@ struct crocus_shader_state { */ struct crocus_context { struct pipe_context ctx; + struct threaded_context *thrctx; /** A debug callback for KHR_debug output. */ struct pipe_debug_callback dbg; diff --git a/src/gallium/drivers/crocus/crocus_fence.c b/src/gallium/drivers/crocus/crocus_fence.c index fdff24b2dd4..2e3ad4ba6c6 100644 --- a/src/gallium/drivers/crocus/crocus_fence.c +++ b/src/gallium/drivers/crocus/crocus_fence.c @@ -319,6 +319,7 @@ static bool crocus_fence_finish(struct pipe_screen *p_screen, struct pipe_context *ctx, struct pipe_fence_handle *fence, uint64_t timeout) { + ctx = threaded_context_unwrap_sync(ctx); struct crocus_context *ice = (struct crocus_context *)ctx; struct crocus_screen *screen = (struct crocus_screen *)p_screen; diff --git a/src/gallium/drivers/crocus/crocus_resource.c b/src/gallium/drivers/crocus/crocus_resource.c index 7a7735b4aba..e81356b1111 100644 --- a/src/gallium/drivers/crocus/crocus_resource.c +++ b/src/gallium/drivers/crocus/crocus_resource.c @@ -1086,6 +1086,35 @@ resource_is_busy(struct crocus_context *ice, return busy; } +void +crocus_replace_buffer_storage(struct pipe_context *ctx, + struct pipe_resource *p_dst, + struct pipe_resource *p_src, + unsigned num_rebinds, + uint32_t rebind_mask, + uint32_t delete_buffer_id) +{ + struct crocus_screen *screen = (void *) ctx->screen; + struct crocus_context *ice = (void *) ctx; + struct crocus_resource *dst = (void *) p_dst; + struct crocus_resource *src = (void *) p_src; + + assert(memcmp(&dst->surf, &src->surf, sizeof(dst->surf)) == 0); + + struct crocus_bo *old_bo = dst->bo; + + /* Swap out the backing storage */ + crocus_bo_reference(src->bo); + dst->bo = src->bo; + + /* Rebind the buffer, replacing any state referring to the old BO's + * address, and marking state dirty so it's reemitted. + */ + screen->vtbl.rebind_buffer(ice, dst); + + crocus_bo_unreference(old_bo); +} + static void crocus_invalidate_resource(struct pipe_context *ctx, struct pipe_resource *resource) diff --git a/src/gallium/drivers/crocus/crocus_resource.h b/src/gallium/drivers/crocus/crocus_resource.h index 6a165820207..a6a819deaf1 100644 --- a/src/gallium/drivers/crocus/crocus_resource.h +++ b/src/gallium/drivers/crocus/crocus_resource.h @@ -348,6 +348,14 @@ bool crocus_resource_set_clear_color(struct crocus_context *ice, union isl_color_value crocus_resource_get_clear_color(const struct crocus_resource *res); +void +crocus_replace_buffer_storage(struct pipe_context *ctx, + struct pipe_resource *p_dst, + struct pipe_resource *p_src, + unsigned num_rebinds, + uint32_t rebind_mask, + uint32_t delete_buffer_id); + void crocus_init_screen_resource_functions(struct pipe_screen *pscreen); void crocus_dirty_for_history(struct crocus_context *ice,