diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index 82344ba74cf..3df744fada8 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -389,12 +389,12 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, slab_create_child(&r300->pool_transfers, &r300screen->pool_transfers); - r300->ctx = rws->ctx_create(rws, RADEON_CTX_PRIORITY_MEDIUM); + r300->ctx = rws->ctx_create(rws, RADEON_CTX_PRIORITY_MEDIUM, false); if (!r300->ctx) goto fail; - if (!rws->cs_create(&r300->cs, r300->ctx, AMD_IP_GFX, r300_flush_callback, r300, false)) + if (!rws->cs_create(&r300->cs, r300->ctx, AMD_IP_GFX, r300_flush_callback, r300)) goto fail; if (!r300screen->caps.has_tcl) { diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index aff820a0485..cb884e5353b 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -206,7 +206,7 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, } ws->cs_create(&rctx->b.gfx.cs, rctx->b.ctx, AMD_IP_GFX, - r600_context_gfx_flush, rctx, false); + r600_context_gfx_flush, rctx); rctx->b.gfx.flush = r600_context_gfx_flush; u_suballocator_init(&rctx->allocator_fetch_shader, &rctx->b.b, 64 * 1024, diff --git a/src/gallium/drivers/r600/r600_pipe_common.c b/src/gallium/drivers/r600/r600_pipe_common.c index f1f33827720..bc48f71d237 100644 --- a/src/gallium/drivers/r600/r600_pipe_common.c +++ b/src/gallium/drivers/r600/r600_pipe_common.c @@ -632,13 +632,13 @@ bool r600_common_context_init(struct r600_common_context *rctx, if (!rctx->b.const_uploader) return false; - rctx->ctx = rctx->ws->ctx_create(rctx->ws, RADEON_CTX_PRIORITY_MEDIUM); + rctx->ctx = rctx->ws->ctx_create(rctx->ws, RADEON_CTX_PRIORITY_MEDIUM, false); if (!rctx->ctx) return false; if (rscreen->info.ip[AMD_IP_SDMA].num_queues && !(rscreen->debug_flags & DBG_NO_ASYNC_DMA)) { rctx->ws->cs_create(&rctx->dma.cs, rctx->ctx, AMD_IP_SDMA, - r600_flush_dma_ring, rctx, false); + r600_flush_dma_ring, rctx); rctx->dma.flush = r600_flush_dma_ring; } diff --git a/src/gallium/drivers/r600/radeon_uvd.c b/src/gallium/drivers/r600/radeon_uvd.c index 2fdb8b92784..569fe42a6a9 100644 --- a/src/gallium/drivers/r600/radeon_uvd.c +++ b/src/gallium/drivers/r600/radeon_uvd.c @@ -1100,7 +1100,7 @@ struct pipe_video_codec *ruvd_create_decoder(struct pipe_context *context, dec->screen = context->screen; dec->ws = ws; - if (!ws->cs_create(&dec->cs, rctx->ctx, AMD_IP_UVD, NULL, NULL, false)) { + if (!ws->cs_create(&dec->cs, rctx->ctx, AMD_IP_UVD, NULL, NULL)) { RVID_ERR("Can't get command submission context.\n"); goto error; } diff --git a/src/gallium/drivers/r600/radeon_vce.c b/src/gallium/drivers/r600/radeon_vce.c index 8fb630b61df..836ad310435 100644 --- a/src/gallium/drivers/r600/radeon_vce.c +++ b/src/gallium/drivers/r600/radeon_vce.c @@ -432,7 +432,7 @@ struct pipe_video_codec *rvce_create_encoder(struct pipe_context *context, enc->screen = context->screen; enc->ws = ws; - if (!ws->cs_create(&enc->cs, rctx->ctx, AMD_IP_VCE, rvce_cs_flush, enc, false)) { + if (!ws->cs_create(&enc->cs, rctx->ctx, AMD_IP_VCE, rvce_cs_flush, enc)) { RVID_ERR("Can't get command submission context.\n"); goto error; } diff --git a/src/gallium/drivers/radeonsi/radeon_uvd.c b/src/gallium/drivers/radeonsi/radeon_uvd.c index 1ddba57319e..dea67bf6466 100644 --- a/src/gallium/drivers/radeonsi/radeon_uvd.c +++ b/src/gallium/drivers/radeonsi/radeon_uvd.c @@ -1258,7 +1258,7 @@ struct pipe_video_codec *si_common_uvd_create_decoder(struct pipe_context *conte dec->screen = context->screen; dec->ws = ws; - if (!ws->cs_create(&dec->cs, sctx->ctx, AMD_IP_UVD, NULL, NULL, false)) { + if (!ws->cs_create(&dec->cs, sctx->ctx, AMD_IP_UVD, NULL, NULL)) { RVID_ERR("Can't get command submission context.\n"); goto error; } diff --git a/src/gallium/drivers/radeonsi/radeon_uvd_enc.c b/src/gallium/drivers/radeonsi/radeon_uvd_enc.c index a88f0e22c19..1e38eb8aef8 100644 --- a/src/gallium/drivers/radeonsi/radeon_uvd_enc.c +++ b/src/gallium/drivers/radeonsi/radeon_uvd_enc.c @@ -276,7 +276,7 @@ struct pipe_video_codec *radeon_uvd_create_encoder(struct pipe_context *context, enc->screen = context->screen; enc->ws = ws; - if (!ws->cs_create(&enc->cs, sctx->ctx, AMD_IP_UVD_ENC, radeon_uvd_enc_cs_flush, enc, false)) { + if (!ws->cs_create(&enc->cs, sctx->ctx, AMD_IP_UVD_ENC, radeon_uvd_enc_cs_flush, enc)) { RVID_ERR("Can't get command submission context.\n"); goto error; } diff --git a/src/gallium/drivers/radeonsi/radeon_vce.c b/src/gallium/drivers/radeonsi/radeon_vce.c index 784e227480d..0d46e4040e9 100644 --- a/src/gallium/drivers/radeonsi/radeon_vce.c +++ b/src/gallium/drivers/radeonsi/radeon_vce.c @@ -411,7 +411,7 @@ struct pipe_video_codec *si_vce_create_encoder(struct pipe_context *context, enc->screen = context->screen; enc->ws = ws; - if (!ws->cs_create(&enc->cs, sctx->ctx, AMD_IP_VCE, rvce_cs_flush, enc, false)) { + if (!ws->cs_create(&enc->cs, sctx->ctx, AMD_IP_VCE, rvce_cs_flush, enc)) { RVID_ERR("Can't get command submission context.\n"); goto error; } diff --git a/src/gallium/drivers/radeonsi/radeon_vcn_dec.c b/src/gallium/drivers/radeonsi/radeon_vcn_dec.c index 05718404a23..8974db14eed 100644 --- a/src/gallium/drivers/radeonsi/radeon_vcn_dec.c +++ b/src/gallium/drivers/radeonsi/radeon_vcn_dec.c @@ -3072,7 +3072,7 @@ struct pipe_video_codec *radeon_create_decoder(struct pipe_context *context, dec->sq.ib_total_size_in_dw = NULL; dec->sq.ib_checksum = NULL; - if (!ws->cs_create(&dec->cs, sctx->ctx, ring, NULL, NULL, false)) { + if (!ws->cs_create(&dec->cs, sctx->ctx, ring, NULL, NULL)) { RVID_ERR("Can't get command submission context.\n"); goto error; } @@ -3093,10 +3093,11 @@ struct pipe_video_codec *radeon_create_decoder(struct pipe_context *context, goto err; for (i = 0; i < dec->njctx; i++) { /* Initialize the context handle and the command stream. */ - dec->jctx[i] = dec->ws->ctx_create(dec->ws, RADEON_CTX_PRIORITY_MEDIUM); + dec->jctx[i] = dec->ws->ctx_create(dec->ws, RADEON_CTX_PRIORITY_MEDIUM, + sctx->context_flags & PIPE_CONTEXT_LOSE_CONTEXT_ON_RESET); if (!sctx->ctx) goto error; - if (!dec->ws->cs_create(&dec->jcs[i], dec->jctx[i], ring, NULL, NULL, false)) { + if (!dec->ws->cs_create(&dec->jcs[i], dec->jctx[i], ring, NULL, NULL)) { RVID_ERR("Can't get additional command submission context for mJPEG.\n"); goto error; } diff --git a/src/gallium/drivers/radeonsi/radeon_vcn_enc.c b/src/gallium/drivers/radeonsi/radeon_vcn_enc.c index 24d25130655..2e2448aa959 100644 --- a/src/gallium/drivers/radeonsi/radeon_vcn_enc.c +++ b/src/gallium/drivers/radeonsi/radeon_vcn_enc.c @@ -1017,7 +1017,7 @@ struct pipe_video_codec *radeon_create_encoder(struct pipe_context *context, if (!ws->cs_create(&enc->cs, (sctx->vcn_has_ctx) ? ((struct si_context *)enc->ectx)->ctx : sctx->ctx, - AMD_IP_VCN_ENC, radeon_enc_cs_flush, enc, false)) { + AMD_IP_VCN_ENC, radeon_enc_cs_flush, enc)) { RVID_ERR("Can't get command submission context.\n"); goto error; } diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c index c95cdc6a032..dcfdad9c30b 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.c +++ b/src/gallium/drivers/radeonsi/si_pipe.c @@ -524,8 +524,10 @@ static struct pipe_context *si_create_context(struct pipe_screen *screen, unsign priority = RADEON_CTX_PRIORITY_MEDIUM; } + bool allow_context_lost = flags & PIPE_CONTEXT_LOSE_CONTEXT_ON_RESET; + /* Initialize the context handle and the command stream. */ - sctx->ctx = sctx->ws->ctx_create(sctx->ws, priority); + sctx->ctx = sctx->ws->ctx_create(sctx->ws, priority, allow_context_lost); if (!sctx->ctx && priority != RADEON_CTX_PRIORITY_MEDIUM) { /* Context priority should be treated as a hint. If context creation * fails with the requested priority, for example because the caller @@ -533,7 +535,7 @@ static struct pipe_context *si_create_context(struct pipe_screen *screen, unsign * fallback to normal priority. */ priority = RADEON_CTX_PRIORITY_MEDIUM; - sctx->ctx = sctx->ws->ctx_create(sctx->ws, priority); + sctx->ctx = sctx->ws->ctx_create(sctx->ws, priority, allow_context_lost); } if (!sctx->ctx) { fprintf(stderr, "radeonsi: can't create radeon_winsys_ctx\n"); @@ -541,8 +543,7 @@ static struct pipe_context *si_create_context(struct pipe_screen *screen, unsign } ws->cs_create(&sctx->gfx_cs, sctx->ctx, sctx->has_graphics ? AMD_IP_GFX : AMD_IP_COMPUTE, - (void *)si_flush_gfx_cs, sctx, - flags & PIPE_CONTEXT_LOSE_CONTEXT_ON_RESET); + (void *)si_flush_gfx_cs, sctx); /* Initialize private allocators. */ u_suballocator_init(&sctx->allocator_zeroed_memory, &sctx->b, 128 * 1024, 0, @@ -1056,7 +1057,7 @@ static void si_test_gds_memory_management(struct si_context *sctx, unsigned allo struct pb_buffer *gds_bo[ARRAY_SIZE(cs)]; for (unsigned i = 0; i < ARRAY_SIZE(cs); i++) { - ws->cs_create(&cs[i], sctx->ctx, AMD_IP_COMPUTE, NULL, NULL, false); + ws->cs_create(&cs[i], sctx->ctx, AMD_IP_COMPUTE, NULL, NULL); gds_bo[i] = ws->buffer_create(ws, alloc_size, alignment, domain, 0); assert(gds_bo[i]); } diff --git a/src/gallium/drivers/radeonsi/si_sdma_copy_image.c b/src/gallium/drivers/radeonsi/si_sdma_copy_image.c index a3ca555821c..e5d4506c9f0 100644 --- a/src/gallium/drivers/radeonsi/si_sdma_copy_image.c +++ b/src/gallium/drivers/radeonsi/si_sdma_copy_image.c @@ -370,8 +370,7 @@ bool si_sdma_copy_image(struct si_context *sctx, struct si_texture *dst, struct return false; sctx->sdma_cs = CALLOC_STRUCT(radeon_cmdbuf); - if (ws->cs_create(sctx->sdma_cs, sctx->ctx, AMD_IP_SDMA, - NULL, NULL, true)) + if (ws->cs_create(sctx->sdma_cs, sctx->ctx, AMD_IP_SDMA, NULL, NULL)) return false; } diff --git a/src/gallium/drivers/radeonsi/si_sqtt.c b/src/gallium/drivers/radeonsi/si_sqtt.c index 04c59554448..a9524a91f49 100644 --- a/src/gallium/drivers/radeonsi/si_sqtt.c +++ b/src/gallium/drivers/radeonsi/si_sqtt.c @@ -513,7 +513,7 @@ static void si_sqtt_init_cs(struct si_context *sctx) { /* Thread trace start CS (only handles AMD_IP_GFX). */ sctx->sqtt->start_cs[AMD_IP_GFX] = CALLOC_STRUCT(radeon_cmdbuf); if (!ws->cs_create(sctx->sqtt->start_cs[AMD_IP_GFX], sctx->ctx, AMD_IP_GFX, - NULL, NULL, 0)) { + NULL, NULL)) { free(sctx->sqtt->start_cs[AMD_IP_GFX]); sctx->sqtt->start_cs[AMD_IP_GFX] = NULL; return; @@ -524,7 +524,7 @@ static void si_sqtt_init_cs(struct si_context *sctx) { /* Thread trace stop CS. */ sctx->sqtt->stop_cs[AMD_IP_GFX] = CALLOC_STRUCT(radeon_cmdbuf); if (!ws->cs_create(sctx->sqtt->stop_cs[AMD_IP_GFX], sctx->ctx, AMD_IP_GFX, - NULL, NULL, 0)) { + NULL, NULL)) { free(sctx->sqtt->start_cs[AMD_IP_GFX]); sctx->sqtt->start_cs[AMD_IP_GFX] = NULL; free(sctx->sqtt->stop_cs[AMD_IP_GFX]); diff --git a/src/gallium/include/winsys/radeon_winsys.h b/src/gallium/include/winsys/radeon_winsys.h index d6551e2ae8c..c34c0225df7 100644 --- a/src/gallium/include/winsys/radeon_winsys.h +++ b/src/gallium/include/winsys/radeon_winsys.h @@ -493,9 +493,14 @@ struct radeon_winsys { /** * Create a command submission context. * Various command streams can be submitted to the same context. + * + * \param allow_context_lost If true, lost contexts skip command submission and report + * the reset status. + * If false, losing the context results in undefined behavior. */ struct radeon_winsys_ctx *(*ctx_create)(struct radeon_winsys *ws, - enum radeon_ctx_priority priority); + enum radeon_ctx_priority priority, + bool allow_context_lost); /** * Destroy a context. @@ -524,7 +529,7 @@ struct radeon_winsys { struct radeon_winsys_ctx *ctx, enum amd_ip_type amd_ip_type, void (*flush)(void *ctx, unsigned flags, struct pipe_fence_handle **fence), - void *flush_ctx, bool allow_context_lost); + void *flush_ctx); /** * Set up and enable mid command buffer preemption for the command stream. diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c index afc8f1d7433..082d8d2b9bd 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c @@ -271,7 +271,8 @@ radeon_to_amdgpu_priority(enum radeon_ctx_priority radeon_priority) } static struct radeon_winsys_ctx *amdgpu_ctx_create(struct radeon_winsys *ws, - enum radeon_ctx_priority priority) + enum radeon_ctx_priority priority, + bool allow_context_lost) { struct amdgpu_ctx *ctx = CALLOC_STRUCT(amdgpu_ctx); int r; @@ -285,6 +286,7 @@ static struct radeon_winsys_ctx *amdgpu_ctx_create(struct radeon_winsys *ws, ctx->ws = amdgpu_winsys(ws); ctx->refcount = 1; ctx->initial_num_total_rejected_cs = ctx->ws->num_total_rejected_cs; + ctx->allow_context_lost = allow_context_lost; r = amdgpu_cs_ctx_create2(ctx->ws->dev, amdgpu_priority, &ctx->ctx); if (r) { @@ -1045,8 +1047,7 @@ amdgpu_cs_create(struct radeon_cmdbuf *rcs, enum amd_ip_type ip_type, void (*flush)(void *ctx, unsigned flags, struct pipe_fence_handle **fence), - void *flush_ctx, - bool allow_context_lost) + void *flush_ctx) { struct amdgpu_ctx *ctx = (struct amdgpu_ctx*)rwctx; struct amdgpu_cs *cs; @@ -1063,7 +1064,6 @@ amdgpu_cs_create(struct radeon_cmdbuf *rcs, cs->flush_cs = flush; cs->flush_data = flush_ctx; cs->ip_type = ip_type; - cs->allow_context_lost = allow_context_lost; cs->noop = ctx->ws->noop_cs; cs->has_chaining = ctx->ws->info.gfx_level >= GFX7 && (ip_type == AMD_IP_GFX || ip_type == AMD_IP_COMPUTE); @@ -1737,7 +1737,7 @@ static void amdgpu_cs_submit_ib(void *job, void *gdata, int thread_index) cleanup: if (unlikely(r)) { - if (!acs->allow_context_lost) { + if (!acs->ctx->allow_context_lost) { /* Non-robust contexts are allowed to terminate the process. The only alternative is * to skip command submission, which would look like a freeze because nothing is drawn, * which is not a useful state to be in under any circumstances. diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.h b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.h index 3bb21f3fded..8babf491cef 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.h +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.h @@ -24,6 +24,12 @@ struct amdgpu_ctx { amdgpu_bo_handle user_fence_bo; uint64_t *user_fence_cpu_address_base; int refcount; + + /* If true, report lost contexts and skip command submission. + * If false, terminate the process. + */ + bool allow_context_lost; + unsigned initial_num_total_rejected_cs; bool rejected_any_cs; }; @@ -138,7 +144,6 @@ struct amdgpu_cs { /* Flush CS. */ void (*flush_cs)(void *ctx, unsigned flags, struct pipe_fence_handle **fence); void *flush_data; - bool allow_context_lost; bool noop; bool has_chaining; diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c index 1622a9e0b83..d972611c6c5 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c @@ -51,7 +51,8 @@ static void radeon_fence_reference(struct pipe_fence_handle **dst, struct pipe_fence_handle *src); static struct radeon_winsys_ctx *radeon_drm_ctx_create(struct radeon_winsys *ws, - enum radeon_ctx_priority priority) + enum radeon_ctx_priority priority, + bool allow_context_lost) { struct radeon_ctx *ctx = CALLOC_STRUCT(radeon_ctx); if (!ctx) @@ -160,8 +161,7 @@ radeon_drm_cs_create(struct radeon_cmdbuf *rcs, enum amd_ip_type ip_type, void (*flush)(void *ctx, unsigned flags, struct pipe_fence_handle **fence), - void *flush_ctx, - bool allow_context_lost) + void *flush_ctx) { struct radeon_drm_winsys *ws = ((struct radeon_ctx*)ctx)->ws; struct radeon_drm_cs *cs;