diff --git a/src/common/vulkan/context.cpp b/src/common/vulkan/context.cpp
index 1a82ad927..382b6a096 100644
--- a/src/common/vulkan/context.cpp
+++ b/src/common/vulkan/context.cpp
@@ -271,7 +271,7 @@ Context::GPUNameList Context::EnumerateGPUNames(VkInstance instance)
   return gpu_names;
 }
 
-bool Context::Create(u32 gpu_index, const WindowInfo* wi, std::unique_ptr<SwapChain>* out_swap_chain,
+bool Context::Create(std::string_view gpu_name, const WindowInfo* wi, std::unique_ptr<SwapChain>* out_swap_chain,
                      bool enable_debug_reports, bool enable_validation_layer)
 {
   AssertMsg(!g_vulkan_context, "Has no current context");
@@ -306,14 +306,27 @@ bool Context::Create(u32 gpu_index, const WindowInfo* wi, std::unique_ptr<SwapCh
     return false;
   }
 
+  u32 gpu_index = 0;
   GPUNameList gpu_names = EnumerateGPUNames(instance);
-  for (u32 i = 0; i < gpu_names.size(); i++)
-    Log_InfoPrintf("GPU %u: %s", static_cast<u32>(i), gpu_names[i].c_str());
-
-  if (gpu_index >= gpus.size())
+  if (!gpu_name.empty())
   {
-    Log_WarningPrintf("GPU index (%u) out of range (%u), using first", gpu_index, static_cast<u32>(gpus.size()));
-    gpu_index = 0;
+    for (; gpu_index < static_cast<u32>(gpu_names.size()); gpu_index++)
+    {
+      Log_InfoPrintf("GPU %u: %s", static_cast<u32>(gpu_index), gpu_names[gpu_index].c_str());
+      if (gpu_names[gpu_index] == gpu_name)
+        break;
+    }
+
+    if (gpu_index == static_cast<u32>(gpu_names.size()))
+    {
+      Log_WarningPrintf("Requested GPU '%s' not found, using first (%s)", std::string(gpu_name).c_str(),
+                        gpu_names[0].c_str());
+      gpu_index = 0;
+    }
+  }
+  else
+  {
+    Log_InfoPrintf("No GPU requested, using first (%s)", gpu_names[0].c_str());
   }
 
   VkSurfaceKHR surface = VK_NULL_HANDLE;
diff --git a/src/common/vulkan/context.h b/src/common/vulkan/context.h
index 31163c38e..c99c76815 100644
--- a/src/common/vulkan/context.h
+++ b/src/common/vulkan/context.h
@@ -43,7 +43,7 @@ public:
   static GPUNameList EnumerateGPUNames(VkInstance instance);
 
   // Creates a new context and sets it up as global.
-  static bool Create(u32 gpu_index, const WindowInfo* wi, std::unique_ptr<SwapChain>* out_swap_chain,
+  static bool Create(std::string_view gpu_name, const WindowInfo* wi, std::unique_ptr<SwapChain>* out_swap_chain,
                      bool enable_debug_reports, bool enable_validation_layer);
 
   // Destroys context.
diff --git a/src/frontend-common/vulkan_host_display.cpp b/src/frontend-common/vulkan_host_display.cpp
index 69d22e6d5..2d5e14c7b 100644
--- a/src/frontend-common/vulkan_host_display.cpp
+++ b/src/frontend-common/vulkan_host_display.cpp
@@ -194,7 +194,7 @@ void VulkanHostDisplay::SetVSync(bool enabled)
 
 bool VulkanHostDisplay::CreateContextAndSwapChain(const WindowInfo& wi, bool debug_device)
 {
-  if (!Vulkan::Context::Create(0u, &wi, &m_swap_chain, debug_device, false))
+  if (!Vulkan::Context::Create({}, &wi, &m_swap_chain, debug_device, false))
   {
     Log_ErrorPrintf("Failed to create Vulkan context");
     return false;