diff --git a/rpcs3/Emu/RSX/VK/VKHelpers.cpp b/rpcs3/Emu/RSX/VK/VKHelpers.cpp index 3f6d90601a..0ec296d0c5 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.cpp +++ b/rpcs3/Emu/RSX/VK/VKHelpers.cpp @@ -11,6 +11,46 @@ namespace vk { + static chip_family_table s_AMD_family_tree = []() + { + chip_family_table table; + table.default_ = chip_class::AMD_gcn_generic; + + // AMD cards. See https://github.com/torvalds/linux/blob/master/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c + table.add(0x67C0, 0x67FF, chip_class::AMD_polaris); + table.add(0x6FDF, chip_class::AMD_polaris); // RX580 2048SP + table.add(0x6980, 0x699F, chip_class::AMD_polaris); // Polaris12 + table.add(0x694C, 0x694F, chip_class::AMD_vega); // VegaM + table.add(0x6860, 0x686F, chip_class::AMD_vega); // VegaPro + table.add(0x687F, chip_class::AMD_vega); // Vega56/64 + table.add(0x69A0, 0x69AF, chip_class::AMD_vega); // Vega12 + table.add(0x66A0, 0x66AF, chip_class::AMD_vega); // Vega20 + table.add(0x15DD, chip_class::AMD_vega); // Raven Ridge + table.add(0x15D8, chip_class::AMD_vega); // Raven Ridge + table.add(0x7310, 0x731F, chip_class::AMD_navi); // Navi10 + table.add(0x7340, 0x7340, chip_class::AMD_navi); // Navi14 + + return table; + }(); + + static chip_family_table s_NV_family_tree = []() + { + chip_family_table table; + table.default_ = chip_class::NV_generic; + + // NV cards. See https://envytools.readthedocs.io/en/latest/hw/pciid.html + // NOTE: Since NV device IDs are linearly incremented per generation, there is no need to carefully check all the ranges + table.add(0x1B00, 0x1D80, chip_class::NV_pascal); + table.add(0x1D81, 0x1DBA, chip_class::NV_volta); + table.add(0x1E02, 0x1F51, chip_class::NV_turing); // RTX 20 + table.add(0x2182, chip_class::NV_turing); // TU116 + table.add(0x2184, chip_class::NV_turing); // TU116 + table.add(0x1F82, chip_class::NV_turing); // TU117 + table.add(0x1F91, chip_class::NV_turing); // TU117 + + return table; + }(); + const context* g_current_vulkan_ctx = nullptr; const render_device* g_current_renderer; @@ -34,6 +74,7 @@ namespace vk // Driver compatibility workarounds VkFlags g_heap_compatible_buffer_types = 0; driver_vendor g_driver_vendor = driver_vendor::unknown; + chip_class g_chip_class = chip_class::unknown; bool g_drv_no_primitive_restart_flag = false; bool g_drv_sanitize_fp_values = false; bool g_drv_disable_fence_reset = false; @@ -126,6 +167,21 @@ namespace vk return result; } + chip_class get_chip_family(uint32_t vendor_id, uint32_t device_id) + { + if (vendor_id == 0x10DE) + { + return s_NV_family_tree.find(device_id); + } + + if (vendor_id == 0x1002) + { + return s_AMD_family_tree.find(device_id); + } + + return chip_class::unknown; + } + VkAllocationCallbacks default_callbacks() { VkAllocationCallbacks callbacks; @@ -321,11 +377,15 @@ namespace vk g_drv_disable_fence_reset = false; g_num_processed_frames = 0; g_num_total_frames = 0; - g_driver_vendor = driver_vendor::unknown; g_heap_compatible_buffer_types = 0; - const auto gpu_name = g_current_renderer->gpu().get_name(); - switch (g_driver_vendor = g_current_renderer->gpu().get_driver_vendor()) + const auto& gpu = g_current_renderer->gpu(); + const auto gpu_name = gpu.get_name(); + + g_driver_vendor = gpu.get_driver_vendor(); + g_chip_class = gpu.get_chip_class(); + + switch (g_driver_vendor) { case driver_vendor::AMD: case driver_vendor::RADV: @@ -391,6 +451,11 @@ namespace vk return g_driver_vendor; } + chip_class get_chip_family() + { + return g_chip_class; + } + bool emulate_primitive_restart(rsx::primitive_type type) { if (g_drv_no_primitive_restart_flag) diff --git a/rpcs3/Emu/RSX/VK/VKHelpers.h b/rpcs3/Emu/RSX/VK/VKHelpers.h index 569b8c0fe5..2b901c7f5b 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.h +++ b/rpcs3/Emu/RSX/VK/VKHelpers.h @@ -80,6 +80,19 @@ namespace vk INTEL }; + enum class chip_class + { + unknown, + AMD_gcn_generic, + AMD_polaris, + AMD_vega, + AMD_navi, + NV_generic, + NV_pascal, + NV_volta, + NV_turing + }; + class context; class render_device; class swap_chain_image; @@ -107,6 +120,8 @@ namespace vk bool fence_reset_disabled(); VkFlags get_heap_compatible_buffer_types(); driver_vendor get_driver_vendor(); + chip_class get_chip_family(uint32_t vendor_id, uint32_t device_id); + chip_class get_chip_family(); VkComponentMapping default_component_map(); VkComponentMapping apply_swizzle_remap(const std::array& base_remap, const std::pair, std::array>& remap_vector); @@ -216,6 +231,35 @@ namespace vk bool allow_int8; }; + struct chip_family_table + { + chip_class default_ = chip_class::unknown; + std::unordered_map lut; + + void add(uint32_t first, uint32_t last, chip_class family) + { + for (auto i = first; i <= last; ++i) + { + lut[i] = family; + } + } + + void add(uint32_t id, chip_class family) + { + lut[id] = family; + } + + chip_class find(uint32_t device_id) + { + if (auto found = lut.find(device_id); found != lut.end()) + { + return found->second; + } + + return default_; + } + }; + // Memory Allocator - base class class mem_allocator_base @@ -630,6 +674,11 @@ private: } } + chip_class get_chip_class() const + { + return get_chip_family(props.vendorID, props.deviceID); + } + uint32_t get_queue_count() const { if (!queue_props.empty())