diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index 5aed289926..08ebc4b5fb 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -547,18 +547,6 @@ VKGSRender::VKGSRender() : GSRender() vk::set_current_thread_ctx(m_thread_context); vk::set_current_renderer(m_swapchain->get_device()); - // Choose memory allocator (device memory) - if (g_cfg.video.disable_vulkan_mem_allocator) - { - m_mem_allocator = std::make_shared(*m_device, m_device->gpu()); - } - else - { - m_mem_allocator = std::make_shared(*m_device, m_device->gpu()); - } - - vk::set_current_mem_allocator(m_mem_allocator); - m_client_width = m_frame->client_width(); m_client_height = m_frame->client_height(); if (!m_swapchain->init(m_client_width, m_client_height)) @@ -782,7 +770,6 @@ VKGSRender::~VKGSRender() //Device handles/contexts m_swapchain->destroy(); - m_mem_allocator->destroy(); m_thread_context.close(); #if !defined(_WIN32) && defined(HAVE_VULKAN) diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.h b/rpcs3/Emu/RSX/VK/VKGSRender.h index 83a9bdafa6..4db0a003cd 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.h +++ b/rpcs3/Emu/RSX/VK/VKGSRender.h @@ -287,8 +287,6 @@ public: std::unique_ptr m_vertex_cache; std::unique_ptr m_shaders_cache; - std::shared_ptr m_mem_allocator; - private: std::unique_ptr m_prog_buffer; diff --git a/rpcs3/Emu/RSX/VK/VKHelpers.cpp b/rpcs3/Emu/RSX/VK/VKHelpers.cpp index 128b78fe19..ce2126fb23 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.cpp +++ b/rpcs3/Emu/RSX/VK/VKHelpers.cpp @@ -4,20 +4,19 @@ namespace vk { - context* g_current_vulkan_ctx = nullptr; - render_device g_current_renderer; - driver_vendor g_driver_vendor = driver_vendor::unknown; - std::shared_ptr g_mem_allocator = nullptr; + const context* g_current_vulkan_ctx = nullptr; + const render_device* g_current_renderer; std::unique_ptr g_null_texture; std::unique_ptr g_null_image_view; - std::unordered_map> g_typeless_textures; + std::unordered_map> g_typeless_textures; VkSampler g_null_sampler = nullptr; atomic_t g_cb_no_interrupt_flag { false }; //Driver compatibility workarounds + driver_vendor g_driver_vendor = driver_vendor::unknown; bool g_drv_no_primitive_restart_flag = false; bool g_drv_sanitize_fp_values = false; bool g_drv_disable_fence_reset = false; @@ -141,7 +140,7 @@ namespace vk sampler_info.compareOp = VK_COMPARE_OP_NEVER; sampler_info.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; - vkCreateSampler(g_current_renderer, &sampler_info, nullptr, &g_null_sampler); + vkCreateSampler(*g_current_renderer, &sampler_info, nullptr, &g_null_sampler); return g_null_sampler; } @@ -150,11 +149,11 @@ namespace vk if (g_null_image_view) return g_null_image_view->value; - g_null_texture.reset(new image(g_current_renderer, g_current_renderer.get_memory_mapping().device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, + g_null_texture.reset(new image(*g_current_renderer, g_current_renderer->get_memory_mapping().device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_IMAGE_TYPE_2D, VK_FORMAT_B8G8R8A8_UNORM, 4, 4, 1, 1, 1, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, 0)); - g_null_image_view.reset(new image_view(g_current_renderer, g_null_texture->value, VK_IMAGE_VIEW_TYPE_2D, + g_null_image_view.reset(new image_view(*g_current_renderer, g_null_texture->value, VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_B8G8R8A8_UNORM, {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A}, {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1})); @@ -173,12 +172,12 @@ namespace vk { auto create_texture = [&]() { - return new vk::image(g_current_renderer, g_current_renderer.get_memory_mapping().device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, + return new vk::image(*g_current_renderer, g_current_renderer->get_memory_mapping().device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_IMAGE_TYPE_2D, format, 4096, 4096, 1, 1, 1, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0); }; - auto &ptr = g_typeless_textures[format]; + auto &ptr = g_typeless_textures[(u32)format]; if (!ptr) { auto _img = create_texture(); @@ -206,39 +205,35 @@ namespace vk g_typeless_textures.clear(); if (g_null_sampler) - vkDestroySampler(g_current_renderer, g_null_sampler, nullptr); + vkDestroySampler(*g_current_renderer, g_null_sampler, nullptr); g_null_sampler = nullptr; } - void set_current_mem_allocator(std::shared_ptr mem_allocator) + vk::mem_allocator_base* get_current_mem_allocator() { - g_mem_allocator = mem_allocator; - } - - std::shared_ptr get_current_mem_allocator() - { - return g_mem_allocator; + verify (HERE, g_current_renderer); + return g_current_renderer->get_allocator(); } void set_current_thread_ctx(const vk::context &ctx) { - g_current_vulkan_ctx = (vk::context *)&ctx; + g_current_vulkan_ctx = &ctx; } - context *get_current_thread_ctx() + const context *get_current_thread_ctx() { return g_current_vulkan_ctx; } - vk::render_device *get_current_renderer() + const vk::render_device *get_current_renderer() { - return &g_current_renderer; + return g_current_renderer; } void set_current_renderer(const vk::render_device &device) { - g_current_renderer = device; + g_current_renderer = &device; g_cb_no_interrupt_flag.store(false); g_drv_no_primitive_restart_flag = false; g_drv_sanitize_fp_values = false; @@ -247,7 +242,7 @@ namespace vk g_num_total_frames = 0; g_driver_vendor = driver_vendor::unknown; - const auto gpu_name = g_current_renderer.gpu().name(); + const auto gpu_name = g_current_renderer->gpu().name(); //Radeon fails to properly handle degenerate primitives if primitive restart is enabled //One has to choose between using degenerate primitives or primitive restart to break up lists but not both @@ -488,15 +483,15 @@ namespace vk { if (g_drv_disable_fence_reset) { - vkDestroyFence(g_current_renderer, *pFence, nullptr); + vkDestroyFence(*g_current_renderer, *pFence, nullptr); VkFenceCreateInfo info = {}; info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; - CHECK_RESULT(vkCreateFence(g_current_renderer, &info, nullptr, pFence)); + CHECK_RESULT(vkCreateFence(*g_current_renderer, &info, nullptr, pFence)); } else { - CHECK_RESULT(vkResetFences(g_current_renderer, 1, pFence)); + CHECK_RESULT(vkResetFences(*g_current_renderer, 1, pFence)); } } diff --git a/rpcs3/Emu/RSX/VK/VKHelpers.h b/rpcs3/Emu/RSX/VK/VKHelpers.h index 41430935a9..10dbe23bee 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.h +++ b/rpcs3/Emu/RSX/VK/VKHelpers.h @@ -77,14 +77,13 @@ namespace vk struct memory_type_mapping; struct gpu_formats_support; - vk::context *get_current_thread_ctx(); + const vk::context *get_current_thread_ctx(); void set_current_thread_ctx(const vk::context &ctx); - vk::render_device *get_current_renderer(); + const vk::render_device *get_current_renderer(); void set_current_renderer(const vk::render_device &device); - void set_current_mem_allocator(std::shared_ptr mem_allocator); - std::shared_ptr get_current_mem_allocator(); + mem_allocator_base *get_current_mem_allocator(); //Compatibility workarounds bool emulate_primitive_restart(rsx::primitive_type type); @@ -167,178 +166,6 @@ namespace vk bool d32_sfloat_s8; }; - class physical_device - { - VkPhysicalDevice dev = nullptr; - VkPhysicalDeviceProperties props; - VkPhysicalDeviceMemoryProperties memory_properties; - std::vector queue_props; - - public: - - physical_device() {} - ~physical_device() {} - - void set_device(VkPhysicalDevice pdev) - { - dev = pdev; - vkGetPhysicalDeviceProperties(pdev, &props); - vkGetPhysicalDeviceMemoryProperties(pdev, &memory_properties); - } - - std::string name() const - { - return props.deviceName; - } - - uint32_t get_queue_count() const - { - if (queue_props.size()) - return (u32)queue_props.size(); - - uint32_t count = 0; - vkGetPhysicalDeviceQueueFamilyProperties(dev, &count, nullptr); - - return count; - } - - VkQueueFamilyProperties get_queue_properties(uint32_t queue) - { - if (!queue_props.size()) - { - uint32_t count = 0; - vkGetPhysicalDeviceQueueFamilyProperties(dev, &count, nullptr); - - queue_props.resize(count); - vkGetPhysicalDeviceQueueFamilyProperties(dev, &count, queue_props.data()); - } - - if (queue >= queue_props.size()) fmt::throw_exception("Bad queue index passed to get_queue_properties (%u)" HERE, queue); - return queue_props[queue]; - } - - VkPhysicalDeviceMemoryProperties get_memory_properties() const - { - return memory_properties; - } - - operator VkPhysicalDevice() const - { - return dev; - } - }; - - class render_device - { - physical_device *pgpu = nullptr; - memory_type_mapping memory_map{}; - gpu_formats_support m_formats_support{}; - VkDevice dev = VK_NULL_HANDLE; - - public: - render_device() - {} - - render_device(vk::physical_device &pdev, uint32_t graphics_queue_idx) - { - float queue_priorities[1] = { 0.f }; - pgpu = &pdev; - - VkDeviceQueueCreateInfo queue = {}; - queue.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - queue.pNext = NULL; - queue.queueFamilyIndex = graphics_queue_idx; - queue.queueCount = 1; - queue.pQueuePriorities = queue_priorities; - - //Set up instance information - const char *requested_extensions[] = - { - VK_KHR_SWAPCHAIN_EXTENSION_NAME - }; - - //Enable hardware features manually - //Currently we require: - //1. Anisotropic sampling - //2. DXT support - VkPhysicalDeviceFeatures available_features; - vkGetPhysicalDeviceFeatures(*pgpu, &available_features); - - available_features.samplerAnisotropy = VK_TRUE; - available_features.textureCompressionBC = VK_TRUE; - - VkDeviceCreateInfo device = {}; - device.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; - device.pNext = NULL; - device.queueCreateInfoCount = 1; - device.pQueueCreateInfos = &queue; - device.enabledLayerCount = 0; - device.ppEnabledLayerNames = nullptr; // Deprecated - device.enabledExtensionCount = 1; - device.ppEnabledExtensionNames = requested_extensions; - device.pEnabledFeatures = &available_features; - - CHECK_RESULT(vkCreateDevice(*pgpu, &device, nullptr, &dev)); - - memory_map = vk::get_memory_mapping(pdev); - m_formats_support = vk::get_optimal_tiling_supported_formats(pdev); - } - - ~render_device() - { - } - - void destroy() - { - if (dev && pgpu) - { - vkDestroyDevice(dev, nullptr); - dev = nullptr; - } - } - - bool get_compatible_memory_type(u32 typeBits, u32 desired_mask, u32 *type_index) - { - VkPhysicalDeviceMemoryProperties mem_infos = pgpu->get_memory_properties(); - - for (uint32_t i = 0; i < 32; i++) - { - if ((typeBits & 1) == 1) - { - if ((mem_infos.memoryTypes[i].propertyFlags & desired_mask) == desired_mask) - { - *type_index = i; - return true; - } - } - - typeBits >>= 1; - } - - return false; - } - - const physical_device& gpu() const - { - return *pgpu; - } - - const memory_type_mapping& get_memory_mapping() const - { - return memory_map; - } - - const gpu_formats_support& get_formats_support() const - { - return m_formats_support; - } - - operator VkDevice&() - { - return dev; - } - }; - // Memory Allocator - base class class mem_allocator_base @@ -530,10 +357,200 @@ namespace vk private: VkDevice m_device; - std::shared_ptr m_mem_allocator; + vk::mem_allocator_base* m_mem_allocator; mem_allocator_base::mem_handle_t m_mem_handle; }; + class physical_device + { + VkPhysicalDevice dev = nullptr; + VkPhysicalDeviceProperties props; + VkPhysicalDeviceMemoryProperties memory_properties; + std::vector queue_props; + + public: + + physical_device() {} + ~physical_device() {} + + void set_device(VkPhysicalDevice pdev) + { + dev = pdev; + vkGetPhysicalDeviceProperties(pdev, &props); + vkGetPhysicalDeviceMemoryProperties(pdev, &memory_properties); + } + + std::string name() const + { + return props.deviceName; + } + + uint32_t get_queue_count() const + { + if (queue_props.size()) + return (u32)queue_props.size(); + + uint32_t count = 0; + vkGetPhysicalDeviceQueueFamilyProperties(dev, &count, nullptr); + + return count; + } + + VkQueueFamilyProperties get_queue_properties(uint32_t queue) + { + if (!queue_props.size()) + { + uint32_t count = 0; + vkGetPhysicalDeviceQueueFamilyProperties(dev, &count, nullptr); + + queue_props.resize(count); + vkGetPhysicalDeviceQueueFamilyProperties(dev, &count, queue_props.data()); + } + + if (queue >= queue_props.size()) fmt::throw_exception("Bad queue index passed to get_queue_properties (%u)" HERE, queue); + return queue_props[queue]; + } + + VkPhysicalDeviceMemoryProperties get_memory_properties() const + { + return memory_properties; + } + + operator VkPhysicalDevice() const + { + return dev; + } + }; + + class render_device + { + physical_device *pgpu = nullptr; + memory_type_mapping memory_map{}; + gpu_formats_support m_formats_support{}; + std::unique_ptr m_allocator; + VkDevice dev = VK_NULL_HANDLE; + + public: + render_device() + {} + + ~render_device() + {} + + void create(vk::physical_device &pdev, uint32_t graphics_queue_idx) + { + float queue_priorities[1] = { 0.f }; + pgpu = &pdev; + + VkDeviceQueueCreateInfo queue = {}; + queue.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + queue.pNext = NULL; + queue.queueFamilyIndex = graphics_queue_idx; + queue.queueCount = 1; + queue.pQueuePriorities = queue_priorities; + + //Set up instance information + const char *requested_extensions[] = + { + VK_KHR_SWAPCHAIN_EXTENSION_NAME + }; + + //Enable hardware features manually + //Currently we require: + //1. Anisotropic sampling + //2. DXT support + VkPhysicalDeviceFeatures available_features; + vkGetPhysicalDeviceFeatures(*pgpu, &available_features); + + available_features.samplerAnisotropy = VK_TRUE; + available_features.textureCompressionBC = VK_TRUE; + + VkDeviceCreateInfo device = {}; + device.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; + device.pNext = NULL; + device.queueCreateInfoCount = 1; + device.pQueueCreateInfos = &queue; + device.enabledLayerCount = 0; + device.ppEnabledLayerNames = nullptr; // Deprecated + device.enabledExtensionCount = 1; + device.ppEnabledExtensionNames = requested_extensions; + device.pEnabledFeatures = &available_features; + + CHECK_RESULT(vkCreateDevice(*pgpu, &device, nullptr, &dev)); + + memory_map = vk::get_memory_mapping(pdev); + m_formats_support = vk::get_optimal_tiling_supported_formats(pdev); + + if (g_cfg.video.disable_vulkan_mem_allocator) + m_allocator = std::make_unique(dev, pdev); + else + m_allocator = std::make_unique(dev, pdev); + } + + void destroy() + { + if (dev && pgpu) + { + if (m_allocator) + { + m_allocator->destroy(); + m_allocator.reset(); + } + + vkDestroyDevice(dev, nullptr); + dev = nullptr; + memory_map = {}; + m_formats_support = {}; + } + } + + bool get_compatible_memory_type(u32 typeBits, u32 desired_mask, u32 *type_index) const + { + VkPhysicalDeviceMemoryProperties mem_infos = pgpu->get_memory_properties(); + + for (uint32_t i = 0; i < 32; i++) + { + if ((typeBits & 1) == 1) + { + if ((mem_infos.memoryTypes[i].propertyFlags & desired_mask) == desired_mask) + { + *type_index = i; + return true; + } + } + + typeBits >>= 1; + } + + return false; + } + + const physical_device& gpu() const + { + return *pgpu; + } + + const memory_type_mapping& get_memory_mapping() const + { + return memory_map; + } + + const gpu_formats_support& get_formats_support() const + { + return m_formats_support; + } + + mem_allocator_base* get_allocator() const + { + return m_allocator.get(); + } + + operator VkDevice() const + { + return dev; + } + }; + struct image { VkImage value = VK_NULL_HANDLE; @@ -542,7 +559,7 @@ namespace vk VkImageCreateInfo info = {}; std::shared_ptr memory; - image(vk::render_device &dev, + image(const vk::render_device &dev, uint32_t memory_type_index, uint32_t access_flags, VkImageType image_type, @@ -1179,7 +1196,7 @@ public: public: swapchain_base(physical_device &gpu, uint32_t _present_queue, uint32_t _graphics_queue, VkFormat format = VK_FORMAT_B8G8R8A8_UNORM) { - dev = render_device(gpu, _graphics_queue); + dev.create(gpu, _graphics_queue); if (_graphics_queue < UINT32_MAX) vkGetDeviceQueue(dev, _graphics_queue, 0, &vk_graphics_queue); if (_present_queue < UINT32_MAX) vkGetDeviceQueue(dev, _present_queue, 0, &vk_present_queue);