From 88445fc12aaaeac5a2e71b6381917c2b056f89b7 Mon Sep 17 00:00:00 2001 From: Faith Ekstrand Date: Fri, 19 Jan 2024 16:24:39 -0600 Subject: [PATCH] nouveau/winsys: Allow only allocating a subset of engines Part-of: --- src/nouveau/mme/tests/mme_runner.cpp | 2 +- src/nouveau/vulkan/nvk_device.c | 7 +++- src/nouveau/winsys/nouveau_context.c | 63 ++++++++++++++++++---------- src/nouveau/winsys/nouveau_context.h | 12 +++++- src/nouveau/winsys/nouveau_device.c | 2 +- 5 files changed, 59 insertions(+), 27 deletions(-) diff --git a/src/nouveau/mme/tests/mme_runner.cpp b/src/nouveau/mme/tests/mme_runner.cpp index ccf7ca42867..c144ab624a1 100644 --- a/src/nouveau/mme/tests/mme_runner.cpp +++ b/src/nouveau/mme/tests/mme_runner.cpp @@ -91,7 +91,7 @@ mme_hw_runner::set_up_hw(uint16_t min_cls, uint16_t max_cls) devinfo = &dev->info; - int ret = nouveau_ws_context_create(dev, &ctx); + int ret = nouveau_ws_context_create(dev, NOUVEAU_WS_ENGINE_3D, &ctx); if (ret) return false; diff --git a/src/nouveau/vulkan/nvk_device.c b/src/nouveau/vulkan/nvk_device.c index c92a53ce316..637155636d4 100644 --- a/src/nouveau/vulkan/nvk_device.c +++ b/src/nouveau/vulkan/nvk_device.c @@ -166,7 +166,12 @@ nvk_CreateDevice(VkPhysicalDevice physicalDevice, dev->vk.command_buffer_ops = &nvk_cmd_buffer_ops; dev->pdev = pdev; - ret = nouveau_ws_context_create(dev->ws_dev, &dev->ws_ctx); + const enum nouveau_ws_engines engines = + NOUVEAU_WS_ENGINE_COPY | + NOUVEAU_WS_ENGINE_3D | + NOUVEAU_WS_ENGINE_COMPUTE; + + ret = nouveau_ws_context_create(dev->ws_dev, engines, &dev->ws_ctx); if (ret) { if (ret == -ENOSPC) result = vk_error(dev, VK_ERROR_TOO_MANY_OBJECTS); diff --git a/src/nouveau/winsys/nouveau_context.c b/src/nouveau/winsys/nouveau_context.c index 3a4a817d86d..52c65adf29d 100644 --- a/src/nouveau/winsys/nouveau_context.c +++ b/src/nouveau/winsys/nouveau_context.c @@ -121,7 +121,9 @@ nouveau_ws_channel_dealloc(int fd, int channel) } int -nouveau_ws_context_create(struct nouveau_ws_device *dev, struct nouveau_ws_context **out) +nouveau_ws_context_create(struct nouveau_ws_device *dev, + enum nouveau_ws_engines engines, + struct nouveau_ws_context **out) { struct drm_nouveau_channel_alloc req = { }; uint32_t classes[NOUVEAU_WS_CONTEXT_MAX_CLASSES]; @@ -141,32 +143,47 @@ nouveau_ws_context_create(struct nouveau_ws_device *dev, struct nouveau_ws_conte base = (0xbeef + req.channel) << 16; - uint32_t obj_class = nouveau_ws_context_find_class(classes, 0xb5); - ret = nouveau_ws_subchan_alloc(dev->fd, req.channel, 0, obj_class, &(*out)->copy); - if (ret) - goto fail_subchan; + if (engines & NOUVEAU_WS_ENGINE_COPY) { + uint32_t obj_class = nouveau_ws_context_find_class(classes, 0xb5); + ret = nouveau_ws_subchan_alloc(dev->fd, req.channel, 0, + obj_class, &(*out)->copy); + if (ret) + goto fail_subchan; + } - obj_class = nouveau_ws_context_find_class(classes, 0x2d); - ret = nouveau_ws_subchan_alloc(dev->fd, req.channel, base | 0x902d, obj_class, &(*out)->eng2d); - if (ret) - goto fail_subchan; + if (engines & NOUVEAU_WS_ENGINE_2D) { + uint32_t obj_class = nouveau_ws_context_find_class(classes, 0x2d); + ret = nouveau_ws_subchan_alloc(dev->fd, req.channel, base | 0x902d, + obj_class, &(*out)->eng2d); + if (ret) + goto fail_subchan; + } - obj_class = nouveau_ws_context_find_class(classes, 0x97); - ret = nouveau_ws_subchan_alloc(dev->fd, req.channel, base | 0x003d, obj_class, &(*out)->eng3d); - if (ret) - goto fail_subchan; + if (engines & NOUVEAU_WS_ENGINE_3D) { + uint32_t obj_class = nouveau_ws_context_find_class(classes, 0x97); + ret = nouveau_ws_subchan_alloc(dev->fd, req.channel, base | 0x003d, + obj_class, &(*out)->eng3d); + if (ret) + goto fail_subchan; + } - obj_class = nouveau_ws_context_find_class(classes, 0x40); - if (!obj_class) - obj_class = nouveau_ws_context_find_class(classes, 0x39); - ret = nouveau_ws_subchan_alloc(dev->fd, req.channel, base | 0x323f, obj_class, &(*out)->m2mf); - if (ret) - goto fail_subchan; + if (engines & NOUVEAU_WS_ENGINE_M2MF) { + uint32_t obj_class = nouveau_ws_context_find_class(classes, 0x40); + if (!obj_class) + obj_class = nouveau_ws_context_find_class(classes, 0x39); + ret = nouveau_ws_subchan_alloc(dev->fd, req.channel, base | 0x323f, + obj_class, &(*out)->m2mf); + if (ret) + goto fail_subchan; + } - obj_class = nouveau_ws_context_find_class(classes, 0xc0); - ret = nouveau_ws_subchan_alloc(dev->fd, req.channel, base | 0x00c0, obj_class, &(*out)->compute); - if (ret) - goto fail_subchan; + if (engines & NOUVEAU_WS_ENGINE_COMPUTE) { + uint32_t obj_class = nouveau_ws_context_find_class(classes, 0xc0); + ret = nouveau_ws_subchan_alloc(dev->fd, req.channel, base | 0x00c0, + obj_class, &(*out)->compute); + if (ret) + goto fail_subchan; + } (*out)->channel = req.channel; (*out)->dev = dev; diff --git a/src/nouveau/winsys/nouveau_context.h b/src/nouveau/winsys/nouveau_context.h index cf2f7d05a15..3eb8fa36117 100644 --- a/src/nouveau/winsys/nouveau_context.h +++ b/src/nouveau/winsys/nouveau_context.h @@ -13,6 +13,14 @@ struct nouveau_ws_object { uint16_t cls; }; +enum nouveau_ws_engines { + NOUVEAU_WS_ENGINE_COPY = (1 << 0), + NOUVEAU_WS_ENGINE_2D = (1 << 1), + NOUVEAU_WS_ENGINE_3D = (1 << 2), + NOUVEAU_WS_ENGINE_M2MF = (1 << 3), + NOUVEAU_WS_ENGINE_COMPUTE = (1 << 4), +}; + struct nouveau_ws_context { struct nouveau_ws_device *dev; @@ -25,7 +33,9 @@ struct nouveau_ws_context { struct nouveau_ws_object compute; }; -int nouveau_ws_context_create(struct nouveau_ws_device *, struct nouveau_ws_context **out); +int nouveau_ws_context_create(struct nouveau_ws_device *, + enum nouveau_ws_engines engines, + struct nouveau_ws_context **out); bool nouveau_ws_context_killed(struct nouveau_ws_context *); void nouveau_ws_context_destroy(struct nouveau_ws_context *); diff --git a/src/nouveau/winsys/nouveau_device.c b/src/nouveau/winsys/nouveau_device.c index 904a7ad6241..9faf196d004 100644 --- a/src/nouveau/winsys/nouveau_device.c +++ b/src/nouveau/winsys/nouveau_device.c @@ -326,7 +326,7 @@ nouveau_ws_device_new(drmDevicePtr drm_device) nouveau_ws_device_set_dbg_flags(device); struct nouveau_ws_context *tmp_ctx; - if (nouveau_ws_context_create(device, &tmp_ctx)) + if (nouveau_ws_context_create(device, ~0, &tmp_ctx)) goto out_err; device->info.sm = sm_for_chipset(device->info.chipset);