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
This commit is contained in:
1 parent
fb5273985c
commit
02b49458a3
2 files changed
+51
-13
No files matched your search
@@ -5586,11 +5586,11 @@ them.
|
||||
results, as can missing or incorrect display FPS information (see
|
||||
``--override-display-fps``).
|
||||
|
||||
``--vulkan-device=<device name>``
|
||||
The name of the Vulkan device to use for rendering and presentation. Use
|
||||
``--vulkan-device=<device name|UUID>``
|
||||
The name or UUID of the Vulkan device to use for rendering and presentation. Use
|
||||
``--vulkan-device=help`` to see the list of available devices and their
|
||||
names. If left unspecified, the first enumerated hardware Vulkan device will
|
||||
be used.
|
||||
names and UUIDs. If left unspecified, the first enumerated hardware Vulkan
|
||||
device will be used.
|
||||
|
||||
``--vulkan-swap-mode=<mode>``
|
||||
Controls the presentation mode of the vulkan swapchain. This is similar
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in new issue
Block a user