ui/vk: Reimplement vulkan GS selection; minor fixes for broken contexts on unsupported devices

This commit is contained in:
kd-11 2017-05-26 17:10:40 +03:00
parent 63cadab042
commit e6d55a6692
3 changed files with 54 additions and 18 deletions

View File

@ -451,9 +451,19 @@ VKGSRender::VKGSRender() : GSRender()
{
shaders_cache.load(rsx::old_shaders_cache::shader_language::glsl);
m_thread_context.createInstance("RPCS3");
m_thread_context.makeCurrentInstance(1);
m_thread_context.enable_debugging();
u32 instance_handle = m_thread_context.createInstance("RPCS3");
if (instance_handle > 0)
{
m_thread_context.makeCurrentInstance(instance_handle);
m_thread_context.enable_debugging();
}
else
{
LOG_FATAL(RSX, "Could not find a vulkan compatible GPU driver. Your GPU(s) may not support Vulkan, or you need to install the vulkan runtime and drivers");
m_device = VK_NULL_HANDLE;
return;
}
#ifdef _WIN32
HINSTANCE hInstance = NULL;
@ -462,10 +472,11 @@ VKGSRender::VKGSRender() : GSRender()
std::vector<vk::physical_device>& gpus = m_thread_context.enumerateDevices();
//Actually confirm that the loader found at least one compatible device
//This should not happen unless something is wrong with the driver setup on the target system
if (gpus.size() == 0)
{
//We can't throw in Emulator::Load, so we show error and return
LOG_FATAL(RSX, "Could not find a vulkan compatible GPU driver. Your GPU(s) may not support Vulkan, or you need to install the vulkan runtime and drivers");
LOG_FATAL(RSX, "No compatible GPU devices found");
m_device = VK_NULL_HANDLE;
return;
}

View File

@ -1019,11 +1019,16 @@ namespace vk
PFN_vkCreateDebugReportCallbackEXT createDebugReportCallback = nullptr;
VkDebugReportCallbackEXT m_debugger = nullptr;
bool loader_exists = false;
public:
context()
{
m_instance = nullptr;
//Check that some critical entry-points have been loaded into memory indicating prescence of a loader
loader_exists = (vkCreateInstance != nullptr);
}
~context()
@ -1066,8 +1071,10 @@ namespace vk
CHECK_RESULT(createDebugReportCallback(m_instance, &dbgCreateInfo, NULL, &m_debugger));
}
uint32_t createInstance(const char *app_name)
uint32_t createInstance(const char *app_name, bool fast = false)
{
if (!loader_exists) return 0;
//Initialize a vulkan instance
VkApplicationInfo app = {};
@ -1088,7 +1095,7 @@ namespace vk
std::vector<const char *> layers;
if (g_cfg.video.debug_output)
if (!fast && g_cfg.video.debug_output)
layers.push_back("VK_LAYER_LUNARG_standard_validation");
VkInstanceCreateInfo instance_info = {};
@ -1096,11 +1103,12 @@ namespace vk
instance_info.pApplicationInfo = &app;
instance_info.enabledLayerCount = static_cast<uint32_t>(layers.size());
instance_info.ppEnabledLayerNames = layers.data();
instance_info.enabledExtensionCount = 3;
instance_info.ppEnabledExtensionNames = requested_extensions;
instance_info.enabledExtensionCount = fast? 0: 3;
instance_info.ppEnabledExtensionNames = fast? nullptr: requested_extensions;
VkInstance instance;
CHECK_RESULT(vkCreateInstance(&instance_info, nullptr, &instance));
if (vkCreateInstance(&instance_info, nullptr, &instance) != VK_SUCCESS)
return 0;
m_vk_instances.push_back(instance);
return (u32)m_vk_instances.size();
@ -1137,6 +1145,9 @@ namespace vk
std::vector<physical_device>& enumerateDevices()
{
if (!loader_exists)
return gpus;
uint32_t num_gpus;
CHECK_RESULT(vkEnumeratePhysicalDevices(m_instance, &num_gpus, nullptr));

View File

@ -481,25 +481,39 @@ SettingsDialog::SettingsDialog(wxWindow* parent, const std::string& path)
#endif
#ifdef _WIN32
//TODO: This is very slow. Only init once
bool vulkan_supported = false;
vk::context device_enum_context;
device_enum_context.createInstance("RPCS3");
device_enum_context.makeCurrentInstance(1);
std::vector<vk::physical_device>& gpus = device_enum_context.enumerateDevices();
device_enum_context.close();
if (gpus.size() > 0)
u32 instance_handle = device_enum_context.createInstance("RPCS3", true);
if (instance_handle > 0)
{
for (auto& gpu : gpus)
device_enum_context.makeCurrentInstance(instance_handle);
std::vector<vk::physical_device>& gpus = device_enum_context.enumerateDevices();
if (gpus.size() > 0)
{
cbox_gs_vk_adapter->Append(gpu.name());
//A device with vulkan support found. Init data
vulkan_supported = true;
for (auto& gpu : gpus)
{
cbox_gs_vk_adapter->Append(gpu.name());
}
pads.emplace_back(std::make_unique<combobox_pad>(cfg_location{ "Video", "Vulkan", "Adapter" }, cbox_gs_vk_adapter));
}
pads.emplace_back(std::make_unique<combobox_pad>(cfg_location{"Video", "Vulkan", "Adapter"}, cbox_gs_vk_adapter));
}
else
if (!vulkan_supported)
{
// Removes Vulkan from Render list when the system doesn't support it
cbox_gs_render->Delete(cbox_gs_render->FindString("Vulkan"));
cbox_gs_vk_adapter->Enable(false);
}
device_enum_context.close();
#else
cbox_gs_vk_adapter->Enable(false);
#endif