summaryrefslogtreecommitdiffstats
path: root/video/out/vulkan/context.c
diff options
context:
space:
mode:
authorPhilip Langdale <philipl@overt.org>2022-11-26 10:02:17 -0800
committerPhilip Langdale <github.philipl@overt.org>2023-09-04 15:22:20 -0700
commit02b49458a37313efa1b6bbaf99a73f406cd3eece (patch)
tree8e7b9773f9c6f4a806cb635fc4610e0c91fa014f /video/out/vulkan/context.c
parentfb5273985cf2f5ae2c84eb95e1f79c49a549e2e5 (diff)
downloadmpv-02b49458a37313efa1b6bbaf99a73f406cd3eece.tar.bz2
mpv-02b49458a37313efa1b6bbaf99a73f406cd3eece.tar.xz
vo: vulkan: allow picking devices by UUID
We currently only allow specifying the Vulkan device to use by name. We did this to avoid confusion around devices being enumerated in an unpredictable order. However, there is a valid edge case where a system may contain multiple devices of the same type - which means they will have the same name, and so you can't control which one is used. This change implements picking devices by UUID so that if names don't work, you have some option available. As Vulkan 1.1 is a hard requirement for libplacebo, we can just use UUIDs without conditional checks. Fixes #10898
Diffstat (limited to 'video/out/vulkan/context.c')
-rw-r--r--video/out/vulkan/context.c56
1 files changed, 47 insertions, 9 deletions
diff --git a/video/out/vulkan/context.c b/video/out/vulkan/context.c
index a478024233..fda56bd829 100644
--- a/video/out/vulkan/context.c
+++ b/video/out/vulkan/context.c
@@ -15,6 +15,14 @@
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "config.h"
+
+#if HAVE_LAVU_UUID
+#include <libavutil/uuid.h>
+#else
+#include "misc/uuid.h"
+#endif
+
#include "options/m_config.h"
#include "video/out/placebo/ra_pl.h"
@@ -39,6 +47,10 @@ static int vk_validate_dev(struct mp_log *log, const struct m_option *opt,
// Create a dummy instance to validate/list the devices
VkInstanceCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
+ .pApplicationInfo = &(VkApplicationInfo) {
+ .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
+ .apiVersion = VK_API_VERSION_1_1,
+ }
};
VkInstance inst;
@@ -64,21 +76,39 @@ static int vk_validate_dev(struct mp_log *log, const struct m_option *opt,
ret = M_OPT_EXIT;
}
+ AVUUID param_uuid;
+ bool is_uuid = av_uuid_parse(*value, param_uuid) == 0;
+
for (int i = 0; i < num; i++) {
- VkPhysicalDeviceProperties prop;
- vkGetPhysicalDeviceProperties(devices[i], &prop);
+ VkPhysicalDeviceIDPropertiesKHR id_prop = { 0 };
+ id_prop.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHR;
+
+ VkPhysicalDeviceProperties2KHR prop2 = { 0 };
+ prop2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR;
+ prop2.pNext = &id_prop;
+
+ vkGetPhysicalDeviceProperties2(devices[i], &prop2);
+
+ const VkPhysicalDeviceProperties *prop = &prop2.properties;
if (help) {
- mp_info(log, " '%s' (GPU %d, ID %x:%x)\n", prop.deviceName, i,
- (unsigned)prop.vendorID, (unsigned)prop.deviceID);
- } else if (bstr_equals0(param, prop.deviceName)) {
+ char device_uuid[37];
+ av_uuid_unparse(id_prop.deviceUUID, device_uuid);
+ mp_info(log, " '%s' (GPU %d, PCI ID %x:%x, UUID %s)\n",
+ prop->deviceName, i, (unsigned)prop->vendorID,
+ (unsigned)prop->deviceID, device_uuid);
+ } else if (bstr_equals0(param, prop->deviceName)) {
+ ret = 0;
+ goto done;
+ } else if (is_uuid && av_uuid_equal(param_uuid, id_prop.deviceUUID)) {
ret = 0;
goto done;
}
}
if (!help)
- mp_err(log, "No device with name '%.*s'!\n", BSTR_P(param));
+ mp_err(log, "No device with %s '%.*s'!\n", is_uuid ? "UUID" : "name",
+ BSTR_P(param));
done:
talloc_free(devices);
@@ -198,23 +228,31 @@ bool ra_vk_ctx_init(struct ra_ctx *ctx, struct mpvk_ctx *vk,
features.pNext = &atomic_float_feature;
#endif
+ AVUUID param_uuid = { 0 };
+ bool is_uuid = p->opts->device &&
+ av_uuid_parse(p->opts->device, param_uuid) == 0;
+
assert(vk->pllog);
assert(vk->vkinst);
- vk->vulkan = pl_vulkan_create(vk->pllog, &(struct pl_vulkan_params) {
+ struct pl_vulkan_params device_params = {
.instance = vk->vkinst->instance,
.get_proc_addr = vk->vkinst->get_proc_addr,
.surface = vk->surface,
.async_transfer = p->opts->async_transfer,
.async_compute = p->opts->async_compute,
.queue_count = p->opts->queue_count,
- .device_name = p->opts->device,
#if HAVE_VULKAN_INTEROP
.extra_queues = VK_QUEUE_VIDEO_DECODE_BIT_KHR,
.opt_extensions = opt_extensions,
.num_opt_extensions = MP_ARRAY_SIZE(opt_extensions),
#endif
.features = &features,
- });
+ .device_name = is_uuid ? NULL : p->opts->device,
+ };
+ if (is_uuid)
+ av_uuid_copy(device_params.device_uuid, param_uuid);
+
+ vk->vulkan = pl_vulkan_create(vk->pllog, &device_params);
if (!vk->vulkan)
goto error;