summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_vulkan/vk_device.cpp96
-rw-r--r--src/video_core/renderer_vulkan/vk_device.h4
2 files changed, 39 insertions, 61 deletions
diff --git a/src/video_core/renderer_vulkan/vk_device.cpp b/src/video_core/renderer_vulkan/vk_device.cpp
index 831603e87..07edf556d 100644
--- a/src/video_core/renderer_vulkan/vk_device.cpp
+++ b/src/video_core/renderer_vulkan/vk_device.cpp
@@ -210,6 +210,7 @@ VKDevice::VKDevice(VkInstance instance_, u32 instance_version_, vk::PhysicalDevi
210 VkSurfaceKHR surface, const vk::InstanceDispatch& dld_) 210 VkSurfaceKHR surface, const vk::InstanceDispatch& dld_)
211 : instance{instance_}, dld{dld_}, physical{physical_}, properties{physical.GetProperties()}, 211 : instance{instance_}, dld{dld_}, physical{physical_}, properties{physical.GetProperties()},
212 instance_version{instance_version_}, format_properties{GetFormatProperties(physical, dld)} { 212 instance_version{instance_version_}, format_properties{GetFormatProperties(physical, dld)} {
213 CheckSuitability();
213 SetupFamilies(surface); 214 SetupFamilies(surface);
214 SetupFeatures(); 215 SetupFeatures();
215 216
@@ -548,64 +549,41 @@ bool VKDevice::IsFormatSupported(VkFormat wanted_format, VkFormatFeatureFlags wa
548 return (supported_usage & wanted_usage) == wanted_usage; 549 return (supported_usage & wanted_usage) == wanted_usage;
549} 550}
550 551
551bool VKDevice::IsSuitable(vk::PhysicalDevice physical, VkSurfaceKHR surface) { 552void VKDevice::CheckSuitability() const {
552 bool is_suitable = true;
553 std::bitset<REQUIRED_EXTENSIONS.size()> available_extensions; 553 std::bitset<REQUIRED_EXTENSIONS.size()> available_extensions;
554 554 for (const VkExtensionProperties& property : physical.EnumerateDeviceExtensionProperties()) {
555 for (const auto& prop : physical.EnumerateDeviceExtensionProperties()) {
556 for (std::size_t i = 0; i < REQUIRED_EXTENSIONS.size(); ++i) { 555 for (std::size_t i = 0; i < REQUIRED_EXTENSIONS.size(); ++i) {
557 if (available_extensions[i]) { 556 if (available_extensions[i]) {
558 continue; 557 continue;
559 } 558 }
560 const std::string_view name{prop.extensionName}; 559 const std::string_view name{property.extensionName};
561 available_extensions[i] = name == REQUIRED_EXTENSIONS[i]; 560 available_extensions[i] = name == REQUIRED_EXTENSIONS[i];
562 } 561 }
563 } 562 }
564 if (!available_extensions.all()) { 563 for (size_t i = 0; i < REQUIRED_EXTENSIONS.size(); ++i) {
565 for (std::size_t i = 0; i < REQUIRED_EXTENSIONS.size(); ++i) { 564 if (available_extensions[i]) {
566 if (available_extensions[i]) {
567 continue;
568 }
569 LOG_ERROR(Render_Vulkan, "Missing required extension: {}", REQUIRED_EXTENSIONS[i]);
570 is_suitable = false;
571 }
572 }
573
574 bool has_graphics{}, has_present{};
575 const std::vector queue_family_properties = physical.GetQueueFamilyProperties();
576 for (u32 i = 0; i < static_cast<u32>(queue_family_properties.size()); ++i) {
577 const auto& family = queue_family_properties[i];
578 if (family.queueCount == 0) {
579 continue; 565 continue;
580 } 566 }
581 has_graphics |= family.queueFlags & VK_QUEUE_GRAPHICS_BIT; 567 LOG_ERROR(Render_Vulkan, "Missing required extension: {}", REQUIRED_EXTENSIONS[i]);
582 has_present |= physical.GetSurfaceSupportKHR(i, surface); 568 throw vk::Exception(VK_ERROR_EXTENSION_NOT_PRESENT);
583 } 569 }
584 if (!has_graphics || !has_present) {
585 LOG_ERROR(Render_Vulkan, "Device lacks a graphics and present queue");
586 is_suitable = false;
587 }
588
589 // TODO(Rodrigo): Check if the device matches all requeriments. 570 // TODO(Rodrigo): Check if the device matches all requeriments.
590 const auto properties{physical.GetProperties()}; 571 const VkPhysicalDeviceLimits& limits{properties.limits};
591 const auto& limits{properties.limits};
592 572
593 constexpr u32 required_ubo_size = 65536; 573 constexpr u32 required_ubo_size = 65536;
594 if (limits.maxUniformBufferRange < required_ubo_size) { 574 if (limits.maxUniformBufferRange < required_ubo_size) {
595 LOG_ERROR(Render_Vulkan, "Device UBO size {} is too small, {} is required", 575 LOG_ERROR(Render_Vulkan, "Device UBO size {} is too small, {} is required",
596 limits.maxUniformBufferRange, required_ubo_size); 576 limits.maxUniformBufferRange, required_ubo_size);
597 is_suitable = false; 577 throw vk::Exception(VK_ERROR_FEATURE_NOT_PRESENT);
598 } 578 }
599
600 constexpr u32 required_num_viewports = 16; 579 constexpr u32 required_num_viewports = 16;
601 if (limits.maxViewports < required_num_viewports) { 580 if (limits.maxViewports < required_num_viewports) {
602 LOG_INFO(Render_Vulkan, "Device number of viewports {} is too small, {} is required", 581 LOG_INFO(Render_Vulkan, "Device number of viewports {} is too small, {} is required",
603 limits.maxViewports, required_num_viewports); 582 limits.maxViewports, required_num_viewports);
604 is_suitable = false; 583 throw vk::Exception(VK_ERROR_FEATURE_NOT_PRESENT);
605 } 584 }
606 585 const VkPhysicalDeviceFeatures features{physical.GetFeatures()};
607 const auto features{physical.GetFeatures()}; 586 const std::array feature_report{
608 const std::array feature_report = {
609 std::make_pair(features.vertexPipelineStoresAndAtomics, "vertexPipelineStoresAndAtomics"), 587 std::make_pair(features.vertexPipelineStoresAndAtomics, "vertexPipelineStoresAndAtomics"),
610 std::make_pair(features.imageCubeArray, "imageCubeArray"), 588 std::make_pair(features.imageCubeArray, "imageCubeArray"),
611 std::make_pair(features.independentBlend, "independentBlend"), 589 std::make_pair(features.independentBlend, "independentBlend"),
@@ -623,19 +601,13 @@ bool VKDevice::IsSuitable(vk::PhysicalDevice physical, VkSurfaceKHR surface) {
623 std::make_pair(features.shaderStorageImageWriteWithoutFormat, 601 std::make_pair(features.shaderStorageImageWriteWithoutFormat,
624 "shaderStorageImageWriteWithoutFormat"), 602 "shaderStorageImageWriteWithoutFormat"),
625 }; 603 };
626 for (const auto& [supported, name] : feature_report) { 604 for (const auto& [is_supported, name] : feature_report) {
627 if (supported) { 605 if (is_supported) {
628 continue; 606 continue;
629 } 607 }
630 LOG_ERROR(Render_Vulkan, "Missing required feature: {}", name); 608 LOG_ERROR(Render_Vulkan, "Missing required feature: {}", name);
631 is_suitable = false; 609 throw vk::Exception(VK_ERROR_FEATURE_NOT_PRESENT);
632 }
633
634 if (!is_suitable) {
635 LOG_ERROR(Render_Vulkan, "{} is not suitable", properties.deviceName);
636 } 610 }
637
638 return is_suitable;
639} 611}
640 612
641std::vector<const char*> VKDevice::LoadExtensions() { 613std::vector<const char*> VKDevice::LoadExtensions() {
@@ -794,28 +766,34 @@ std::vector<const char*> VKDevice::LoadExtensions() {
794} 766}
795 767
796void VKDevice::SetupFamilies(VkSurfaceKHR surface) { 768void VKDevice::SetupFamilies(VkSurfaceKHR surface) {
797 std::optional<u32> graphics_family_, present_family_;
798
799 const std::vector queue_family_properties = physical.GetQueueFamilyProperties(); 769 const std::vector queue_family_properties = physical.GetQueueFamilyProperties();
800 for (u32 i = 0; i < static_cast<u32>(queue_family_properties.size()); ++i) { 770 std::optional<u32> graphics;
801 if (graphics_family_ && present_family_) 771 std::optional<u32> present;
772 for (u32 index = 0; index < static_cast<u32>(queue_family_properties.size()); ++index) {
773 if (graphics && present) {
802 break; 774 break;
803 775 }
804 const auto& queue_family = queue_family_properties[i]; 776 const VkQueueFamilyProperties& queue_family = queue_family_properties[index];
805 if (queue_family.queueCount == 0) 777 if (queue_family.queueCount == 0) {
806 continue; 778 continue;
807 779 }
808 if (queue_family.queueFlags & VK_QUEUE_GRAPHICS_BIT) { 780 if (queue_family.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
809 graphics_family_ = i; 781 graphics = index;
810 } 782 }
811 if (physical.GetSurfaceSupportKHR(i, surface)) { 783 if (physical.GetSurfaceSupportKHR(index, surface)) {
812 present_family_ = i; 784 present = index;
813 } 785 }
814 } 786 }
815 ASSERT(graphics_family_ && present_family_); 787 if (!graphics) {
816 788 LOG_ERROR(Render_Vulkan, "Device lacks a graphics queue");
817 graphics_family = *graphics_family_; 789 throw vk::Exception(VK_ERROR_FEATURE_NOT_PRESENT);
818 present_family = *present_family_; 790 }
791 if (!present) {
792 LOG_ERROR(Render_Vulkan, "Device lacks a present queue");
793 throw vk::Exception(VK_ERROR_FEATURE_NOT_PRESENT);
794 }
795 graphics_family = *graphics;
796 present_family = *present;
819} 797}
820 798
821void VKDevice::SetupFeatures() { 799void VKDevice::SetupFeatures() {
diff --git a/src/video_core/renderer_vulkan/vk_device.h b/src/video_core/renderer_vulkan/vk_device.h
index 67617f86d..63e123d02 100644
--- a/src/video_core/renderer_vulkan/vk_device.h
+++ b/src/video_core/renderer_vulkan/vk_device.h
@@ -229,10 +229,10 @@ public:
229 return use_asynchronous_shaders; 229 return use_asynchronous_shaders;
230 } 230 }
231 231
232private:
232 /// Checks if the physical device is suitable. 233 /// Checks if the physical device is suitable.
233 static bool IsSuitable(vk::PhysicalDevice physical, VkSurfaceKHR surface); 234 void CheckSuitability() const;
234 235
235private:
236 /// Loads extensions into a vector and stores available ones in this object. 236 /// Loads extensions into a vector and stores available ones in this object.
237 std::vector<const char*> LoadExtensions(); 237 std::vector<const char*> LoadExtensions();
238 238