From b3f7f40b13d540314da5807ff82826c0c8ea764e Mon Sep 17 00:00:00 2001 From: Mary Guillemard Date: Thu, 11 Jun 2026 15:38:53 +0200 Subject: [PATCH] nvk/nvkmd: Do not merge bind operations across VA mappings We were allowing a possible merge of operation across VA mappings. This is not a valid usage and will cause a ENOSPC to be returned by the kernel side. This fixes Forza Horizon 6 device lost when trying to enter in-game or benchmark mode with VK_EXT_descriptor_heap MR. Signed-off-by: Mary Guillemard Fixes: 053b7f0f30c ("nvk/nvkmd: Implement nvkmd_ctx for nouveau") Reviewed-by: Mel Henning Part-of: --- src/nouveau/vulkan/nvkmd/nouveau/nvkmd_nouveau_ctx.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/nouveau/vulkan/nvkmd/nouveau/nvkmd_nouveau_ctx.c b/src/nouveau/vulkan/nvkmd/nouveau/nvkmd_nouveau_ctx.c index f94e80e80e1..e62a576e9e0 100644 --- a/src/nouveau/vulkan/nvkmd/nouveau/nvkmd_nouveau_ctx.c +++ b/src/nouveau/vulkan/nvkmd/nouveau/nvkmd_nouveau_ctx.c @@ -379,6 +379,7 @@ nvkmd_nouveau_bind_ctx_bind(struct nvkmd_ctx *_ctx, { struct nvkmd_nouveau_bind_ctx *ctx = nvkmd_nouveau_bind_ctx(_ctx); + struct nvkmd_va *prev_va = NULL; for (uint32_t i = 0; i < bind_count; i++) { STATIC_ASSERT(NVKMD_BIND_OP_BIND == DRM_NOUVEAU_VM_BIND_OP_MAP); STATIC_ASSERT(NVKMD_BIND_OP_UNBIND == DRM_NOUVEAU_VM_BIND_OP_UNMAP); @@ -399,8 +400,10 @@ nvkmd_nouveau_bind_ctx_bind(struct nvkmd_ctx *_ctx, struct drm_nouveau_vm_bind_op *prev_op = &ctx->req_ops[ctx->req.op_count - 1]; - /* Try to coalesce bind ops together if we can */ - if (op.op == prev_op->op && + /* Try to coalesce bind ops together if we can (We can only merge + * operations if they are part of the same VA mapping) */ + if (binds[i].va == prev_va && + op.op == prev_op->op && op.flags == prev_op->flags && op.handle == prev_op->handle && op.addr == prev_op->addr + prev_op->range && @@ -417,6 +420,7 @@ nvkmd_nouveau_bind_ctx_bind(struct nvkmd_ctx *_ctx, } ctx->req_ops[ctx->req.op_count++] = op; + prev_va = binds[i].va; } return VK_SUCCESS;