From 6448eade2ef126a88068cde66b77e7788c3fab08 Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Sun, 18 Jun 2023 04:59:12 -0400 Subject: externals: Add vma and initialize it video_core: Move vma implementation to library --- src/video_core/vulkan_common/vulkan_device.cpp | 23 ++++++++++++++++++++++- src/video_core/vulkan_common/vulkan_device.h | 3 +++ 2 files changed, 25 insertions(+), 1 deletion(-) (limited to 'src/video_core/vulkan_common') diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 3d2e9a16a..631d5e378 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -22,6 +22,10 @@ #include #endif +#define VMA_STATIC_VULKAN_FUNCTIONS 0 +#define VMA_DYNAMIC_VULKAN_FUNCTIONS 1 +#include + namespace Vulkan { using namespace Common::Literals; namespace { @@ -592,9 +596,26 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR graphics_queue = logical.GetQueue(graphics_family); present_queue = logical.GetQueue(present_family); + + const VmaVulkanFunctions functions = { + .vkGetInstanceProcAddr = dld.vkGetInstanceProcAddr, + .vkGetDeviceProcAddr = dld.vkGetDeviceProcAddr, + }; + + const VmaAllocatorCreateInfo allocator_info = { + .physicalDevice = physical, + .device = *logical, + .pVulkanFunctions = &functions, + .instance = instance, + .vulkanApiVersion = VK_API_VERSION_1_1, + }; + + vk::Check(vmaCreateAllocator(&allocator_info, &allocator)); } -Device::~Device() = default; +Device::~Device() { + vmaDestroyAllocator(allocator); +} VkFormat Device::GetSupportedFormat(VkFormat wanted_format, VkFormatFeatureFlags wanted_usage, FormatType format_type) const { diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index f314d0ffe..123d3b1c4 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -13,6 +13,8 @@ #include "common/settings.h" #include "video_core/vulkan_common/vulkan_wrapper.h" +VK_DEFINE_HANDLE(VmaAllocator) + // Define all features which may be used by the implementation here. // Vulkan version in the macro describes the minimum version required for feature availability. // If the Vulkan version is lower than the required version, the named extension is required. @@ -618,6 +620,7 @@ private: private: VkInstance instance; ///< Vulkan instance. + VmaAllocator allocator; ///< VMA allocator. vk::DeviceDispatch dld; ///< Device function pointers. vk::PhysicalDevice physical; ///< Physical device. vk::Device logical; ///< Logical device. -- cgit v1.2.3 From c60eed36b7439a7921ea5e86e1300e96e30c8f8a Mon Sep 17 00:00:00 2001 From: GPUCode Date: Wed, 24 May 2023 20:32:12 +0300 Subject: memory_allocator: Remove OpenGL interop * Appears to be unused atm --- .../vulkan_common/vulkan_memory_allocator.cpp | 58 +--------------------- .../vulkan_common/vulkan_memory_allocator.h | 11 ++-- 2 files changed, 5 insertions(+), 64 deletions(-) (limited to 'src/video_core/vulkan_common') diff --git a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp index e28a556f8..f87c99603 100644 --- a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp +++ b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp @@ -6,8 +6,6 @@ #include #include -#include - #include "common/alignment.h" #include "common/assert.h" #include "common/common_types.h" @@ -54,17 +52,6 @@ struct Range { return VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; } -constexpr VkExportMemoryAllocateInfo EXPORT_ALLOCATE_INFO{ - .sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO, - .pNext = nullptr, -#ifdef _WIN32 - .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT, -#elif __unix__ - .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT, -#else - .handleTypes = 0, -#endif -}; } // Anonymous namespace class MemoryAllocation { @@ -74,14 +61,6 @@ public: : allocator{allocator_}, memory{std::move(memory_)}, allocation_size{allocation_size_}, property_flags{properties}, shifted_memory_type{1U << type} {} -#if defined(_WIN32) || defined(__unix__) - ~MemoryAllocation() { - if (owning_opengl_handle != 0) { - glDeleteMemoryObjectsEXT(1, &owning_opengl_handle); - } - } -#endif - MemoryAllocation& operator=(const MemoryAllocation&) = delete; MemoryAllocation(const MemoryAllocation&) = delete; @@ -120,31 +99,6 @@ public: return memory_mapped_span; } -#ifdef _WIN32 - [[nodiscard]] u32 ExportOpenGLHandle() { - if (!owning_opengl_handle) { - glCreateMemoryObjectsEXT(1, &owning_opengl_handle); - glImportMemoryWin32HandleEXT(owning_opengl_handle, allocation_size, - GL_HANDLE_TYPE_OPAQUE_WIN32_EXT, - memory.GetMemoryWin32HandleKHR()); - } - return owning_opengl_handle; - } -#elif __unix__ - [[nodiscard]] u32 ExportOpenGLHandle() { - if (!owning_opengl_handle) { - glCreateMemoryObjectsEXT(1, &owning_opengl_handle); - glImportMemoryFdEXT(owning_opengl_handle, allocation_size, GL_HANDLE_TYPE_OPAQUE_FD_EXT, - memory.GetMemoryFdKHR()); - } - return owning_opengl_handle; - } -#else - [[nodiscard]] u32 ExportOpenGLHandle() { - return 0; - } -#endif - /// Returns whether this allocation is compatible with the arguments. [[nodiscard]] bool IsCompatible(VkMemoryPropertyFlags flags, u32 type_mask) const { return (flags & property_flags) == flags && (type_mask & shifted_memory_type) != 0; @@ -182,9 +136,6 @@ private: const u32 shifted_memory_type; ///< Shifted Vulkan memory type. std::vector commits; ///< All commit ranges done from this allocation. std::span memory_mapped_span; ///< Memory mapped span. Empty if not queried before. -#if defined(_WIN32) || defined(__unix__) - u32 owning_opengl_handle{}; ///< Owning OpenGL memory object handle. -#endif }; MemoryCommit::MemoryCommit(MemoryAllocation* allocation_, VkDeviceMemory memory_, u64 begin_, @@ -216,19 +167,14 @@ std::span MemoryCommit::Map() { return span; } -u32 MemoryCommit::ExportOpenGLHandle() const { - return allocation->ExportOpenGLHandle(); -} - void MemoryCommit::Release() { if (allocation) { allocation->Free(begin); } } -MemoryAllocator::MemoryAllocator(const Device& device_, bool export_allocations_) +MemoryAllocator::MemoryAllocator(const Device& device_) : device{device_}, properties{device_.GetPhysical().GetMemoryProperties().memoryProperties}, - export_allocations{export_allocations_}, buffer_image_granularity{ device_.GetPhysical().GetProperties().limits.bufferImageGranularity} {} @@ -271,7 +217,7 @@ bool MemoryAllocator::TryAllocMemory(VkMemoryPropertyFlags flags, u32 type_mask, const u32 type = FindType(flags, type_mask).value(); vk::DeviceMemory memory = device.GetLogical().TryAllocateMemory({ .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, - .pNext = export_allocations ? &EXPORT_ALLOCATE_INFO : nullptr, + .pNext = nullptr, .allocationSize = size, .memoryTypeIndex = type, }); diff --git a/src/video_core/vulkan_common/vulkan_memory_allocator.h b/src/video_core/vulkan_common/vulkan_memory_allocator.h index a5bff03fe..494f30f51 100644 --- a/src/video_core/vulkan_common/vulkan_memory_allocator.h +++ b/src/video_core/vulkan_common/vulkan_memory_allocator.h @@ -41,9 +41,6 @@ public: /// It will map the backing allocation if it hasn't been mapped before. std::span Map(); - /// Returns an non-owning OpenGL handle, creating one if it doesn't exist. - u32 ExportOpenGLHandle() const; - /// Returns the Vulkan memory handler. VkDeviceMemory Memory() const { return memory; @@ -74,11 +71,10 @@ public: * Construct memory allocator * * @param device_ Device to allocate from - * @param export_allocations_ True when allocations have to be exported * * @throw vk::Exception on failure */ - explicit MemoryAllocator(const Device& device_, bool export_allocations_); + explicit MemoryAllocator(const Device& device_); ~MemoryAllocator(); MemoryAllocator& operator=(const MemoryAllocator&) = delete; @@ -117,9 +113,8 @@ private: /// Returns index to the fastest memory type compatible with the passed requirements. std::optional FindType(VkMemoryPropertyFlags flags, u32 type_mask) const; - const Device& device; ///< Device handle. - const VkPhysicalDeviceMemoryProperties properties; ///< Physical device properties. - const bool export_allocations; ///< True when memory allocations have to be exported. + const Device& device; ///< Device handle. + const VkPhysicalDeviceMemoryProperties properties; ///< Physical device properties. std::vector> allocations; ///< Current allocations. VkDeviceSize buffer_image_granularity; // The granularity for adjacent offsets between buffers // and optimal images -- cgit v1.2.3 From 48e39756f1ec6e6b0ef48f2444ce38a4e861e898 Mon Sep 17 00:00:00 2001 From: GPUCode Date: Wed, 24 May 2023 22:39:58 +0300 Subject: renderer_vulkan: Use VMA for images --- src/video_core/vulkan_common/vulkan_device.h | 5 ++ .../vulkan_common/vulkan_memory_allocator.cpp | 30 +++++++--- .../vulkan_common/vulkan_memory_allocator.h | 5 +- src/video_core/vulkan_common/vulkan_wrapper.cpp | 28 ++++----- src/video_core/vulkan_common/vulkan_wrapper.h | 70 ++++++++++++++++++---- 5 files changed, 100 insertions(+), 38 deletions(-) (limited to 'src/video_core/vulkan_common') diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index 123d3b1c4..9936f5658 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -210,6 +210,11 @@ public: return dld; } + /// Returns the VMA allocator. + VmaAllocator GetAllocator() const { + return allocator; + } + /// Returns the logical device. const vk::Device& GetLogical() const { return logical; diff --git a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp index f87c99603..7f860cccd 100644 --- a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp +++ b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp @@ -15,6 +15,10 @@ #include "video_core/vulkan_common/vulkan_memory_allocator.h" #include "video_core/vulkan_common/vulkan_wrapper.h" +#define VMA_STATIC_VULKAN_FUNCTIONS 0 +#define VMA_DYNAMIC_VULKAN_FUNCTIONS 1 +#include + namespace Vulkan { namespace { struct Range { @@ -180,6 +184,24 @@ MemoryAllocator::MemoryAllocator(const Device& device_) MemoryAllocator::~MemoryAllocator() = default; +vk::Image MemoryAllocator::CreateImage(const VkImageCreateInfo& ci) const { + const VmaAllocationCreateInfo alloc_info = { + .flags = VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT, + .usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, + .requiredFlags = 0, + .preferredFlags = 0, + .pool = VK_NULL_HANDLE, + .pUserData = nullptr, + }; + + VkImage handle{}; + VmaAllocation allocation{}; + vk::Check( + vmaCreateImage(device.GetAllocator(), &ci, &alloc_info, &handle, &allocation, nullptr)); + return vk::Image(handle, *device.GetLogical(), device.GetAllocator(), allocation, + device.GetDispatchLoader()); +} + MemoryCommit MemoryAllocator::Commit(const VkMemoryRequirements& requirements, MemoryUsage usage) { // Find the fastest memory flags we can afford with the current requirements const u32 type_mask = requirements.memoryTypeBits; @@ -205,14 +227,6 @@ MemoryCommit MemoryAllocator::Commit(const vk::Buffer& buffer, MemoryUsage usage return commit; } -MemoryCommit MemoryAllocator::Commit(const vk::Image& image, MemoryUsage usage) { - VkMemoryRequirements requirements = device.GetLogical().GetImageMemoryRequirements(*image); - requirements.size = Common::AlignUp(requirements.size, buffer_image_granularity); - auto commit = Commit(requirements, usage); - image.BindMemory(commit.Memory(), commit.Offset()); - return commit; -} - bool MemoryAllocator::TryAllocMemory(VkMemoryPropertyFlags flags, u32 type_mask, u64 size) { const u32 type = FindType(flags, type_mask).value(); vk::DeviceMemory memory = device.GetLogical().TryAllocateMemory({ diff --git a/src/video_core/vulkan_common/vulkan_memory_allocator.h b/src/video_core/vulkan_common/vulkan_memory_allocator.h index 494f30f51..f9ee53cfb 100644 --- a/src/video_core/vulkan_common/vulkan_memory_allocator.h +++ b/src/video_core/vulkan_common/vulkan_memory_allocator.h @@ -80,6 +80,8 @@ public: MemoryAllocator& operator=(const MemoryAllocator&) = delete; MemoryAllocator(const MemoryAllocator&) = delete; + vk::Image CreateImage(const VkImageCreateInfo& ci) const; + /** * Commits a memory with the specified requirements. * @@ -93,9 +95,6 @@ public: /// Commits memory required by the buffer and binds it. MemoryCommit Commit(const vk::Buffer& buffer, MemoryUsage usage); - /// Commits memory required by the image and binds it. - MemoryCommit Commit(const vk::Image& image, MemoryUsage usage); - private: /// Tries to allocate a chunk of memory. bool TryAllocMemory(VkMemoryPropertyFlags flags, u32 type_mask, u64 size); diff --git a/src/video_core/vulkan_common/vulkan_wrapper.cpp b/src/video_core/vulkan_common/vulkan_wrapper.cpp index 336f53700..5d088dc58 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.cpp +++ b/src/video_core/vulkan_common/vulkan_wrapper.cpp @@ -12,6 +12,10 @@ #include "video_core/vulkan_common/vulkan_wrapper.h" +#define VMA_STATIC_VULKAN_FUNCTIONS 0 +#define VMA_DYNAMIC_VULKAN_FUNCTIONS 1 +#include + namespace Vulkan::vk { namespace { @@ -547,6 +551,16 @@ DebugUtilsMessenger Instance::CreateDebugUtilsMessenger( return DebugUtilsMessenger(object, handle, *dld); } +void Image::SetObjectNameEXT(const char* name) const { + SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_IMAGE, name); +} + +void Image::Release() const noexcept { + if (handle) { + vmaDestroyImage(allocator, handle, allocation); + } +} + void Buffer::BindMemory(VkDeviceMemory memory, VkDeviceSize offset) const { Check(dld->vkBindBufferMemory(owner, handle, memory, offset)); } @@ -559,14 +573,6 @@ void BufferView::SetObjectNameEXT(const char* name) const { SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_BUFFER_VIEW, name); } -void Image::BindMemory(VkDeviceMemory memory, VkDeviceSize offset) const { - Check(dld->vkBindImageMemory(owner, handle, memory, offset)); -} - -void Image::SetObjectNameEXT(const char* name) const { - SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_IMAGE, name); -} - void ImageView::SetObjectNameEXT(const char* name) const { SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_IMAGE_VIEW, name); } @@ -713,12 +719,6 @@ BufferView Device::CreateBufferView(const VkBufferViewCreateInfo& ci) const { return BufferView(object, handle, *dld); } -Image Device::CreateImage(const VkImageCreateInfo& ci) const { - VkImage object; - Check(dld->vkCreateImage(handle, &ci, nullptr, &object)); - return Image(object, handle, *dld); -} - ImageView Device::CreateImageView(const VkImageViewCreateInfo& ci) const { VkImageView object; Check(dld->vkCreateImageView(handle, &ci, nullptr, &object)); diff --git a/src/video_core/vulkan_common/vulkan_wrapper.h b/src/video_core/vulkan_common/vulkan_wrapper.h index 4ff328a21..8ec708774 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.h +++ b/src/video_core/vulkan_common/vulkan_wrapper.h @@ -32,6 +32,9 @@ #pragma warning(disable : 26812) // Disable prefer enum class over enum #endif +VK_DEFINE_HANDLE(VmaAllocator) +VK_DEFINE_HANDLE(VmaAllocation) + namespace Vulkan::vk { /** @@ -616,6 +619,60 @@ public: } }; +class Image { +public: + explicit Image(VkImage handle_, VkDevice owner_, VmaAllocator allocator_, + VmaAllocation allocation_, const DeviceDispatch& dld_) noexcept + : handle{handle_}, owner{owner_}, allocator{allocator_}, + allocation{allocation_}, dld{&dld_} {} + Image() = default; + + Image(const Image&) = delete; + Image& operator=(const Image&) = delete; + + Image(Image&& rhs) noexcept + : handle{std::exchange(rhs.handle, nullptr)}, owner{rhs.owner}, allocator{rhs.allocator}, + allocation{rhs.allocation}, dld{rhs.dld} {} + + Image& operator=(Image&& rhs) noexcept { + Release(); + handle = std::exchange(rhs.handle, nullptr); + owner = rhs.owner; + allocator = rhs.allocator; + allocation = rhs.allocation; + dld = rhs.dld; + return *this; + } + + ~Image() noexcept { + Release(); + } + + VkImage operator*() const noexcept { + return handle; + } + + void reset() noexcept { + Release(); + handle = nullptr; + } + + explicit operator bool() const noexcept { + return handle != nullptr; + } + + void SetObjectNameEXT(const char* name) const; + +private: + void Release() const noexcept; + + VkImage handle = nullptr; + VkDevice owner = nullptr; + VmaAllocator allocator = nullptr; + VmaAllocation allocation = nullptr; + const DeviceDispatch* dld = nullptr; +}; + class Queue { public: /// Construct an empty queue handle. @@ -658,17 +715,6 @@ public: void SetObjectNameEXT(const char* name) const; }; -class Image : public Handle { - using Handle::Handle; - -public: - /// Attaches a memory allocation. - void BindMemory(VkDeviceMemory memory, VkDeviceSize offset) const; - - /// Set object name. - void SetObjectNameEXT(const char* name) const; -}; - class ImageView : public Handle { using Handle::Handle; @@ -844,8 +890,6 @@ public: BufferView CreateBufferView(const VkBufferViewCreateInfo& ci) const; - Image CreateImage(const VkImageCreateInfo& ci) const; - ImageView CreateImageView(const VkImageViewCreateInfo& ci) const; Semaphore CreateSemaphore() const; -- cgit v1.2.3 From 7b2f680468bbac206f96b26a1300939be90f5f1b Mon Sep 17 00:00:00 2001 From: GPUCode Date: Sat, 27 May 2023 17:09:17 +0300 Subject: renderer_vulkan: Use VMA for buffers --- src/video_core/vulkan_common/vulkan_device.cpp | 1 + .../vulkan_common/vulkan_memory_allocator.cpp | 107 ++++++++++++++++----- .../vulkan_common/vulkan_memory_allocator.h | 12 ++- src/video_core/vulkan_common/vulkan_wrapper.cpp | 24 +++-- src/video_core/vulkan_common/vulkan_wrapper.h | 91 +++++++++++++++--- 5 files changed, 186 insertions(+), 49 deletions(-) (limited to 'src/video_core/vulkan_common') diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 631d5e378..541f0c1da 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -603,6 +603,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR }; const VmaAllocatorCreateInfo allocator_info = { + .flags = VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT, .physicalDevice = physical, .device = *logical, .pVulkanFunctions = &functions, diff --git a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp index 7f860cccd..d2e1ef58e 100644 --- a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp +++ b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp @@ -51,11 +51,59 @@ struct Range { case MemoryUsage::Download: return VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT; + case MemoryUsage::Stream: + return VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | + VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; } ASSERT_MSG(false, "Invalid memory usage={}", usage); return VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; } +[[nodiscard]] VkMemoryPropertyFlags MemoryUsageRequiredVmaFlags(MemoryUsage usage) { + switch (usage) { + case MemoryUsage::DeviceLocal: + return VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + case MemoryUsage::Upload: + case MemoryUsage::Stream: + return VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; + case MemoryUsage::Download: + return VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT; + } + ASSERT_MSG(false, "Invalid memory usage={}", usage); + return {}; +} + +[[nodiscard]] VkMemoryPropertyFlags MemoryUsagePreferedVmaFlags(MemoryUsage usage) { + return usage != MemoryUsage::DeviceLocal ? VK_MEMORY_PROPERTY_HOST_COHERENT_BIT + : VkMemoryPropertyFlags{}; +} + +[[nodiscard]] VmaAllocationCreateFlags MemoryUsageVmaFlags(MemoryUsage usage) { + switch (usage) { + case MemoryUsage::Upload: + case MemoryUsage::Stream: + return VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT; + case MemoryUsage::Download: + return VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT; + case MemoryUsage::DeviceLocal: + return VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | + VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT; + } + return {}; +} + +[[nodiscard]] VmaMemoryUsage MemoryUsageVma(MemoryUsage usage) { + switch (usage) { + case MemoryUsage::DeviceLocal: + case MemoryUsage::Stream: + return VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE; + case MemoryUsage::Upload: + case MemoryUsage::Download: + return VMA_MEMORY_USAGE_AUTO_PREFER_HOST; + } + return VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE; +} + } // Anonymous namespace class MemoryAllocation { @@ -178,17 +226,18 @@ void MemoryCommit::Release() { } MemoryAllocator::MemoryAllocator(const Device& device_) - : device{device_}, properties{device_.GetPhysical().GetMemoryProperties().memoryProperties}, + : device{device_}, allocator{device.GetAllocator()}, + properties{device_.GetPhysical().GetMemoryProperties().memoryProperties}, buffer_image_granularity{ device_.GetPhysical().GetProperties().limits.bufferImageGranularity} {} MemoryAllocator::~MemoryAllocator() = default; vk::Image MemoryAllocator::CreateImage(const VkImageCreateInfo& ci) const { - const VmaAllocationCreateInfo alloc_info = { + const VmaAllocationCreateInfo alloc_ci = { .flags = VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT, .usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, - .requiredFlags = 0, + .requiredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, .preferredFlags = 0, .pool = VK_NULL_HANDLE, .pUserData = nullptr, @@ -196,12 +245,40 @@ vk::Image MemoryAllocator::CreateImage(const VkImageCreateInfo& ci) const { VkImage handle{}; VmaAllocation allocation{}; - vk::Check( - vmaCreateImage(device.GetAllocator(), &ci, &alloc_info, &handle, &allocation, nullptr)); - return vk::Image(handle, *device.GetLogical(), device.GetAllocator(), allocation, + + vk::Check(vmaCreateImage(allocator, &ci, &alloc_ci, &handle, &allocation, nullptr)); + + return vk::Image(handle, *device.GetLogical(), allocator, allocation, device.GetDispatchLoader()); } +vk::Buffer MemoryAllocator::CreateBuffer(const VkBufferCreateInfo& ci, MemoryUsage usage) const { + const VmaAllocationCreateInfo alloc_ci = { + .flags = VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT | + MemoryUsageVmaFlags(usage), + .usage = MemoryUsageVma(usage), + .requiredFlags = MemoryUsageRequiredVmaFlags(usage), + .preferredFlags = MemoryUsagePreferedVmaFlags(usage), + .pool = VK_NULL_HANDLE, + .pUserData = nullptr, + }; + + VkBuffer handle{}; + VmaAllocationInfo alloc_info{}; + VmaAllocation allocation{}; + VkMemoryPropertyFlags property_flags{}; + + vk::Check(vmaCreateBuffer(allocator, &ci, &alloc_ci, &handle, &allocation, &alloc_info)); + vmaGetAllocationMemoryProperties(allocator, allocation, &property_flags); + + u8* data = reinterpret_cast(alloc_info.pMappedData); + const std::span mapped_data = data ? std::span{data, ci.size} : std::span{}; + const bool is_coherent = property_flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; + + return vk::Buffer(handle, *device.GetLogical(), allocator, allocation, mapped_data, is_coherent, + device.GetDispatchLoader()); +} + MemoryCommit MemoryAllocator::Commit(const VkMemoryRequirements& requirements, MemoryUsage usage) { // Find the fastest memory flags we can afford with the current requirements const u32 type_mask = requirements.memoryTypeBits; @@ -221,12 +298,6 @@ MemoryCommit MemoryAllocator::Commit(const VkMemoryRequirements& requirements, M return TryCommit(requirements, flags).value(); } -MemoryCommit MemoryAllocator::Commit(const vk::Buffer& buffer, MemoryUsage usage) { - auto commit = Commit(device.GetLogical().GetBufferMemoryRequirements(*buffer), usage); - buffer.BindMemory(commit.Memory(), commit.Offset()); - return commit; -} - bool MemoryAllocator::TryAllocMemory(VkMemoryPropertyFlags flags, u32 type_mask, u64 size) { const u32 type = FindType(flags, type_mask).value(); vk::DeviceMemory memory = device.GetLogical().TryAllocateMemory({ @@ -302,16 +373,4 @@ std::optional MemoryAllocator::FindType(VkMemoryPropertyFlags flags, u32 ty return std::nullopt; } -bool IsHostVisible(MemoryUsage usage) noexcept { - switch (usage) { - case MemoryUsage::DeviceLocal: - return false; - case MemoryUsage::Upload: - case MemoryUsage::Download: - return true; - } - ASSERT_MSG(false, "Invalid memory usage={}", usage); - return false; -} - } // namespace Vulkan diff --git a/src/video_core/vulkan_common/vulkan_memory_allocator.h b/src/video_core/vulkan_common/vulkan_memory_allocator.h index f9ee53cfb..f449bc8d0 100644 --- a/src/video_core/vulkan_common/vulkan_memory_allocator.h +++ b/src/video_core/vulkan_common/vulkan_memory_allocator.h @@ -9,6 +9,8 @@ #include "common/common_types.h" #include "video_core/vulkan_common/vulkan_wrapper.h" +VK_DEFINE_HANDLE(VmaAllocator) + namespace Vulkan { class Device; @@ -17,9 +19,11 @@ class MemoryAllocation; /// Hints and requirements for the backing memory type of a commit enum class MemoryUsage { - DeviceLocal, ///< Hints device local usages, fastest memory type to read and write from the GPU + DeviceLocal, ///< Requests device local host visible buffer, falling back to device local + ///< memory. Upload, ///< Requires a host visible memory type optimized for CPU to GPU uploads Download, ///< Requires a host visible memory type optimized for GPU to CPU readbacks + Stream, ///< Requests device local host visible buffer, falling back host memory. }; /// Ownership handle of a memory commitment. @@ -82,6 +86,8 @@ public: vk::Image CreateImage(const VkImageCreateInfo& ci) const; + vk::Buffer CreateBuffer(const VkBufferCreateInfo& ci, MemoryUsage usage) const; + /** * Commits a memory with the specified requirements. * @@ -113,13 +119,11 @@ private: std::optional FindType(VkMemoryPropertyFlags flags, u32 type_mask) const; const Device& device; ///< Device handle. + VmaAllocator allocator; ///< Vma allocator. const VkPhysicalDeviceMemoryProperties properties; ///< Physical device properties. std::vector> allocations; ///< Current allocations. VkDeviceSize buffer_image_granularity; // The granularity for adjacent offsets between buffers // and optimal images }; -/// Returns true when a memory usage is guaranteed to be host visible. -bool IsHostVisible(MemoryUsage usage) noexcept; - } // namespace Vulkan diff --git a/src/video_core/vulkan_common/vulkan_wrapper.cpp b/src/video_core/vulkan_common/vulkan_wrapper.cpp index 5d088dc58..c01a9478e 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.cpp +++ b/src/video_core/vulkan_common/vulkan_wrapper.cpp @@ -561,14 +561,28 @@ void Image::Release() const noexcept { } } -void Buffer::BindMemory(VkDeviceMemory memory, VkDeviceSize offset) const { - Check(dld->vkBindBufferMemory(owner, handle, memory, offset)); +void Buffer::Flush() const { + if (!is_coherent) { + vmaFlushAllocation(allocator, allocation, 0, VK_WHOLE_SIZE); + } +} + +void Buffer::Invalidate() const { + if (!is_coherent) { + vmaInvalidateAllocation(allocator, allocation, 0, VK_WHOLE_SIZE); + } } void Buffer::SetObjectNameEXT(const char* name) const { SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_BUFFER, name); } +void Buffer::Release() const noexcept { + if (handle) { + vmaDestroyBuffer(allocator, handle, allocation); + } +} + void BufferView::SetObjectNameEXT(const char* name) const { SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_BUFFER_VIEW, name); } @@ -707,12 +721,6 @@ Queue Device::GetQueue(u32 family_index) const noexcept { return Queue(queue, *dld); } -Buffer Device::CreateBuffer(const VkBufferCreateInfo& ci) const { - VkBuffer object; - Check(dld->vkCreateBuffer(handle, &ci, nullptr, &object)); - return Buffer(object, handle, *dld); -} - BufferView Device::CreateBufferView(const VkBufferViewCreateInfo& ci) const { VkBufferView object; Check(dld->vkCreateBufferView(handle, &ci, nullptr, &object)); diff --git a/src/video_core/vulkan_common/vulkan_wrapper.h b/src/video_core/vulkan_common/vulkan_wrapper.h index 8ec708774..44fce47a5 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.h +++ b/src/video_core/vulkan_common/vulkan_wrapper.h @@ -673,6 +673,84 @@ private: const DeviceDispatch* dld = nullptr; }; +class Buffer { +public: + explicit Buffer(VkBuffer handle_, VkDevice owner_, VmaAllocator allocator_, + VmaAllocation allocation_, std::span mapped_, bool is_coherent_, + const DeviceDispatch& dld_) noexcept + : handle{handle_}, owner{owner_}, allocator{allocator_}, + allocation{allocation_}, mapped{mapped_}, is_coherent{is_coherent_}, dld{&dld_} {} + Buffer() = default; + + Buffer(const Buffer&) = delete; + Buffer& operator=(const Buffer&) = delete; + + Buffer(Buffer&& rhs) noexcept + : handle{std::exchange(rhs.handle, nullptr)}, owner{rhs.owner}, allocator{rhs.allocator}, + allocation{rhs.allocation}, mapped{rhs.mapped}, + is_coherent{rhs.is_coherent}, dld{rhs.dld} {} + + Buffer& operator=(Buffer&& rhs) noexcept { + Release(); + handle = std::exchange(rhs.handle, nullptr); + owner = rhs.owner; + allocator = rhs.allocator; + allocation = rhs.allocation; + mapped = rhs.mapped; + is_coherent = rhs.is_coherent; + dld = rhs.dld; + return *this; + } + + ~Buffer() noexcept { + Release(); + } + + VkBuffer operator*() const noexcept { + return handle; + } + + void reset() noexcept { + Release(); + handle = nullptr; + } + + explicit operator bool() const noexcept { + return handle != nullptr; + } + + /// Returns the host mapped memory, an empty span otherwise. + std::span Mapped() noexcept { + return mapped; + } + + std::span Mapped() const noexcept { + return mapped; + } + + /// Returns true if the buffer is mapped to the host. + bool IsHostVisible() const noexcept { + return !mapped.empty(); + } + + void Flush() const; + + void Invalidate() const; + + void SetObjectNameEXT(const char* name) const; + +private: + void Release() const noexcept; + + VkBuffer handle = nullptr; + VkDevice owner = nullptr; + VmaAllocator allocator = nullptr; + VmaAllocation allocation = nullptr; + std::span mapped = {}; + bool is_coherent = false; + const DeviceDispatch* dld = nullptr; +}; + class Queue { public: /// Construct an empty queue handle. @@ -696,17 +774,6 @@ private: const DeviceDispatch* dld = nullptr; }; -class Buffer : public Handle { - using Handle::Handle; - -public: - /// Attaches a memory allocation. - void BindMemory(VkDeviceMemory memory, VkDeviceSize offset) const; - - /// Set object name. - void SetObjectNameEXT(const char* name) const; -}; - class BufferView : public Handle { using Handle::Handle; @@ -886,8 +953,6 @@ public: Queue GetQueue(u32 family_index) const noexcept; - Buffer CreateBuffer(const VkBufferCreateInfo& ci) const; - BufferView CreateBufferView(const VkBufferViewCreateInfo& ci) const; ImageView CreateImageView(const VkImageViewCreateInfo& ci) const; -- cgit v1.2.3 From ee0d68300e68a221d9930935f26d0c96be79357b Mon Sep 17 00:00:00 2001 From: GPUCode Date: Sun, 18 Jun 2023 12:27:31 +0300 Subject: renderer_vulkan: Add missing initializers --- src/video_core/vulkan_common/vulkan_device.cpp | 12 ++++++++---- src/video_core/vulkan_common/vulkan_memory_allocator.cpp | 6 +++++- 2 files changed, 13 insertions(+), 5 deletions(-) (limited to 'src/video_core/vulkan_common') diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 541f0c1da..94dd1aa14 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -597,18 +597,22 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR graphics_queue = logical.GetQueue(graphics_family); present_queue = logical.GetQueue(present_family); - const VmaVulkanFunctions functions = { - .vkGetInstanceProcAddr = dld.vkGetInstanceProcAddr, - .vkGetDeviceProcAddr = dld.vkGetDeviceProcAddr, - }; + VmaVulkanFunctions functions{}; + functions.vkGetInstanceProcAddr = dld.vkGetInstanceProcAddr; + functions.vkGetDeviceProcAddr = dld.vkGetDeviceProcAddr; const VmaAllocatorCreateInfo allocator_info = { .flags = VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT, .physicalDevice = physical, .device = *logical, + .preferredLargeHeapBlockSize = 0, + .pAllocationCallbacks = nullptr, + .pDeviceMemoryCallbacks = nullptr, + .pHeapSizeLimit = nullptr, .pVulkanFunctions = &functions, .instance = instance, .vulkanApiVersion = VK_API_VERSION_1_1, + .pTypeExternalMemoryHandleTypes = nullptr, }; vk::Check(vmaCreateAllocator(&allocator_info, &allocator)); diff --git a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp index d2e1ef58e..20d36680c 100644 --- a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp +++ b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp @@ -75,7 +75,7 @@ struct Range { [[nodiscard]] VkMemoryPropertyFlags MemoryUsagePreferedVmaFlags(MemoryUsage usage) { return usage != MemoryUsage::DeviceLocal ? VK_MEMORY_PROPERTY_HOST_COHERENT_BIT - : VkMemoryPropertyFlags{}; + : VkMemoryPropertyFlagBits{}; } [[nodiscard]] VmaAllocationCreateFlags MemoryUsageVmaFlags(MemoryUsage usage) { @@ -239,8 +239,10 @@ vk::Image MemoryAllocator::CreateImage(const VkImageCreateInfo& ci) const { .usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, .requiredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, .preferredFlags = 0, + .memoryTypeBits = 0, .pool = VK_NULL_HANDLE, .pUserData = nullptr, + .priority = 0.f, }; VkImage handle{}; @@ -259,8 +261,10 @@ vk::Buffer MemoryAllocator::CreateBuffer(const VkBufferCreateInfo& ci, MemoryUsa .usage = MemoryUsageVma(usage), .requiredFlags = MemoryUsageRequiredVmaFlags(usage), .preferredFlags = MemoryUsagePreferedVmaFlags(usage), + .memoryTypeBits = 0, .pool = VK_NULL_HANDLE, .pUserData = nullptr, + .priority = 0.f, }; VkBuffer handle{}; -- cgit v1.2.3 From 346c253cd2397ac152fd10f6b99d6af79349a77f Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Thu, 15 Jun 2023 16:16:36 -0400 Subject: video_core: Formalize HasBrokenCompute Also limits it to only affected Intel proprietrary driver versions. vulkan_device: Move broken compute determination vk_device: Remove errant back quote --- src/video_core/vulkan_common/vulkan_device.cpp | 2 ++ src/video_core/vulkan_common/vulkan_device.h | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+) (limited to 'src/video_core/vulkan_common') diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index dcedf4425..e38e34bc8 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -562,6 +562,8 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR LOG_WARNING(Render_Vulkan, "Intel proprietary drivers do not support MSAA image blits"); cant_blit_msaa = true; } + has_broken_compute = + CheckBrokenCompute(properties.driver.driverID, properties.properties.driverVersion); if (is_intel_anv || (is_qualcomm && !is_s8gen2)) { LOG_WARNING(Render_Vulkan, "Driver does not support native BGR format"); must_emulate_bgr565 = true; diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index 8c7e44fcb..e54828088 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -10,6 +10,7 @@ #include #include "common/common_types.h" +#include "common/logging/log.h" #include "common/settings.h" #include "video_core/vulkan_common/vulkan_wrapper.h" @@ -518,6 +519,11 @@ public: return has_renderdoc || has_nsight_graphics || Settings::values.renderer_debug.GetValue(); } + /// @returns True if compute pipelines can cause crashing. + bool HasBrokenCompute() const { + return has_broken_compute; + } + /// Returns true when the device does not properly support cube compatibility. bool HasBrokenCubeImageCompability() const { return has_broken_cube_compatibility; @@ -579,6 +585,22 @@ public: return supports_conditional_barriers; } + [[nodiscard]] static constexpr bool CheckBrokenCompute(VkDriverId driver_id, + u32 driver_version) { + if (driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS) { + const u32 major = VK_API_VERSION_MAJOR(driver_version); + const u32 minor = VK_API_VERSION_MINOR(driver_version); + const u32 patch = VK_API_VERSION_PATCH(driver_version); + if (major == 0 && minor == 405 && patch < 286) { + LOG_WARNING( + Render_Vulkan, + "Intel proprietary drivers 0.405.0 until 0.405.286 have broken compute"); + return true; + } + } + return {}; + } + private: /// Checks if the physical device is suitable and configures the object state /// with all necessary info about its properties. @@ -672,6 +694,7 @@ private: bool is_integrated{}; ///< Is GPU an iGPU. bool is_virtual{}; ///< Is GPU a virtual GPU. bool is_non_gpu{}; ///< Is SoftwareRasterizer, FPGA, non-GPU device. + bool has_broken_compute{}; ///< Compute shaders can cause crashes bool has_broken_cube_compatibility{}; ///< Has broken cube compatibility bit bool has_renderdoc{}; ///< Has RenderDoc attached bool has_nsight_graphics{}; ///< Has Nsight Graphics attached -- cgit v1.2.3 From 197e13d93d6740cda589d88804262d6bdd176a74 Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Mon, 19 Jun 2023 17:33:30 -0400 Subject: video_core: Check broken compute earlier Checks it as the system is determining what settings to enable. Reduces the need to check settings while the system is running. --- src/video_core/vulkan_common/vulkan_device.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/video_core/vulkan_common') diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index e38e34bc8..fa9cde75b 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -563,7 +563,8 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR cant_blit_msaa = true; } has_broken_compute = - CheckBrokenCompute(properties.driver.driverID, properties.properties.driverVersion); + CheckBrokenCompute(properties.driver.driverID, properties.properties.driverVersion) && + !Settings::values.enable_compute_pipelines.GetValue(); if (is_intel_anv || (is_qualcomm && !is_s8gen2)) { LOG_WARNING(Render_Vulkan, "Driver does not support native BGR format"); must_emulate_bgr565 = true; -- cgit v1.2.3 From 78ff2862f6a0785247d3aa64bdc210b545e4d82d Mon Sep 17 00:00:00 2001 From: toast2903 <22451773+lat9nq@users.noreply.github.com> Date: Sun, 18 Jun 2023 23:29:27 -0400 Subject: vulkan_device: Remove brace initializer Co-authored-by: Tobias --- src/video_core/vulkan_common/vulkan_device.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/video_core/vulkan_common') diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index e54828088..0b634a876 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -598,7 +598,7 @@ public: return true; } } - return {}; + return false; } private: -- cgit v1.2.3 From 5da70f719703084482933e103e561cc98163f370 Mon Sep 17 00:00:00 2001 From: Kelebek1 Date: Tue, 23 May 2023 14:45:54 +0100 Subject: Remove memory allocations in some hot paths --- src/video_core/vulkan_common/vulkan_device.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/video_core/vulkan_common') diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index fa9cde75b..b11abe311 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -316,6 +316,7 @@ NvidiaArchitecture GetNvidiaArchitecture(vk::PhysicalDevice physical, std::vector ExtensionListForVulkan( const std::set>& extensions) { std::vector output; + output.reserve(extensions.size()); for (const auto& extension : extensions) { output.push_back(extension.c_str()); } -- cgit v1.2.3 From 75fb29e08e3891ecfc5d96d54603cda806ebd426 Mon Sep 17 00:00:00 2001 From: GPUCode Date: Thu, 22 Jun 2023 20:03:12 +0300 Subject: vulkan_common: Remove required flags * Allows VMA to fallback to system RAM instead of crashing --- src/video_core/vulkan_common/vulkan_memory_allocator.cpp | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) (limited to 'src/video_core/vulkan_common') diff --git a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp index 20d36680c..70db41343 100644 --- a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp +++ b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp @@ -59,20 +59,6 @@ struct Range { return VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; } -[[nodiscard]] VkMemoryPropertyFlags MemoryUsageRequiredVmaFlags(MemoryUsage usage) { - switch (usage) { - case MemoryUsage::DeviceLocal: - return VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; - case MemoryUsage::Upload: - case MemoryUsage::Stream: - return VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; - case MemoryUsage::Download: - return VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT; - } - ASSERT_MSG(false, "Invalid memory usage={}", usage); - return {}; -} - [[nodiscard]] VkMemoryPropertyFlags MemoryUsagePreferedVmaFlags(MemoryUsage usage) { return usage != MemoryUsage::DeviceLocal ? VK_MEMORY_PROPERTY_HOST_COHERENT_BIT : VkMemoryPropertyFlagBits{}; @@ -259,7 +245,7 @@ vk::Buffer MemoryAllocator::CreateBuffer(const VkBufferCreateInfo& ci, MemoryUsa .flags = VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT | MemoryUsageVmaFlags(usage), .usage = MemoryUsageVma(usage), - .requiredFlags = MemoryUsageRequiredVmaFlags(usage), + .requiredFlags = 0, .preferredFlags = MemoryUsagePreferedVmaFlags(usage), .memoryTypeBits = 0, .pool = VK_NULL_HANDLE, -- cgit v1.2.3 From b6c6dcc5760ebaf08460c176c42d1c4729e2eb21 Mon Sep 17 00:00:00 2001 From: GPUCode Date: Sun, 25 Jun 2023 15:08:38 +0300 Subject: externals: Use cmake subdirectory --- src/video_core/vulkan_common/vulkan_device.cpp | 2 -- src/video_core/vulkan_common/vulkan_memory_allocator.cpp | 2 -- src/video_core/vulkan_common/vulkan_wrapper.cpp | 2 -- 3 files changed, 6 deletions(-) (limited to 'src/video_core/vulkan_common') diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 94dd1aa14..31226084f 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -22,8 +22,6 @@ #include #endif -#define VMA_STATIC_VULKAN_FUNCTIONS 0 -#define VMA_DYNAMIC_VULKAN_FUNCTIONS 1 #include namespace Vulkan { diff --git a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp index 70db41343..a2ef0efa4 100644 --- a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp +++ b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp @@ -15,8 +15,6 @@ #include "video_core/vulkan_common/vulkan_memory_allocator.h" #include "video_core/vulkan_common/vulkan_wrapper.h" -#define VMA_STATIC_VULKAN_FUNCTIONS 0 -#define VMA_DYNAMIC_VULKAN_FUNCTIONS 1 #include namespace Vulkan { diff --git a/src/video_core/vulkan_common/vulkan_wrapper.cpp b/src/video_core/vulkan_common/vulkan_wrapper.cpp index c01a9478e..28fcb21a0 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.cpp +++ b/src/video_core/vulkan_common/vulkan_wrapper.cpp @@ -12,8 +12,6 @@ #include "video_core/vulkan_common/vulkan_wrapper.h" -#define VMA_STATIC_VULKAN_FUNCTIONS 0 -#define VMA_DYNAMIC_VULKAN_FUNCTIONS 1 #include namespace Vulkan::vk { -- cgit v1.2.3 From 72e7f5b4dd08e9ea46ee049d8f2564a8808273d4 Mon Sep 17 00:00:00 2001 From: GPUCode Date: Sat, 3 Jun 2023 09:21:52 +0300 Subject: renderer_vulkan: Add suport for debug report callback --- .../vulkan_common/vulkan_debug_callback.cpp | 40 ++++++++++++--- .../vulkan_common/vulkan_debug_callback.h | 4 +- src/video_core/vulkan_common/vulkan_device.cpp | 2 +- src/video_core/vulkan_common/vulkan_instance.cpp | 58 ++++++++++++---------- src/video_core/vulkan_common/vulkan_wrapper.cpp | 14 ++++++ src/video_core/vulkan_common/vulkan_wrapper.h | 9 ++++ 6 files changed, 92 insertions(+), 35 deletions(-) (limited to 'src/video_core/vulkan_common') diff --git a/src/video_core/vulkan_common/vulkan_debug_callback.cpp b/src/video_core/vulkan_common/vulkan_debug_callback.cpp index 9de484c29..67e8065a4 100644 --- a/src/video_core/vulkan_common/vulkan_debug_callback.cpp +++ b/src/video_core/vulkan_common/vulkan_debug_callback.cpp @@ -7,10 +7,10 @@ namespace Vulkan { namespace { -VkBool32 Callback(VkDebugUtilsMessageSeverityFlagBitsEXT severity, - VkDebugUtilsMessageTypeFlagsEXT type, - const VkDebugUtilsMessengerCallbackDataEXT* data, - [[maybe_unused]] void* user_data) { +VkBool32 DebugUtilCallback(VkDebugUtilsMessageSeverityFlagBitsEXT severity, + VkDebugUtilsMessageTypeFlagsEXT type, + const VkDebugUtilsMessengerCallbackDataEXT* data, + [[maybe_unused]] void* user_data) { // Skip logging known false-positive validation errors switch (static_cast(data->messageIdNumber)) { #ifdef ANDROID @@ -62,9 +62,26 @@ VkBool32 Callback(VkDebugUtilsMessageSeverityFlagBitsEXT severity, } return VK_FALSE; } + +VkBool32 DebugReportCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, + uint64_t object, size_t location, int32_t messageCode, + const char* pLayerPrefix, const char* pMessage, void* pUserData) { + const VkDebugReportFlagBitsEXT severity = static_cast(flags); + const std::string_view message{pMessage}; + if (severity & VK_DEBUG_REPORT_ERROR_BIT_EXT) { + LOG_CRITICAL(Render_Vulkan, "{}", message); + } else if (severity & VK_DEBUG_REPORT_WARNING_BIT_EXT) { + LOG_WARNING(Render_Vulkan, "{}", message); + } else if (severity & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) { + LOG_INFO(Render_Vulkan, "{}", message); + } else if (severity & VK_DEBUG_REPORT_DEBUG_BIT_EXT) { + LOG_DEBUG(Render_Vulkan, "{}", message); + } + return VK_FALSE; +} } // Anonymous namespace -vk::DebugUtilsMessenger CreateDebugCallback(const vk::Instance& instance) { +vk::DebugUtilsMessenger CreateDebugUtilsCallback(const vk::Instance& instance) { return instance.CreateDebugUtilsMessenger(VkDebugUtilsMessengerCreateInfoEXT{ .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT, .pNext = nullptr, @@ -76,7 +93,18 @@ vk::DebugUtilsMessenger CreateDebugCallback(const vk::Instance& instance) { .messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, - .pfnUserCallback = Callback, + .pfnUserCallback = DebugUtilCallback, + .pUserData = nullptr, + }); +} + +vk::DebugReportCallback CreateDebugReportCallback(const vk::Instance& instance) { + return instance.CreateDebugReportCallback({ + .sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT, + .pNext = nullptr, + .flags = VK_DEBUG_REPORT_DEBUG_BIT_EXT | VK_DEBUG_REPORT_INFORMATION_BIT_EXT | + VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT, + .pfnCallback = DebugReportCallback, .pUserData = nullptr, }); } diff --git a/src/video_core/vulkan_common/vulkan_debug_callback.h b/src/video_core/vulkan_common/vulkan_debug_callback.h index 71b1f69ec..a8af7b406 100644 --- a/src/video_core/vulkan_common/vulkan_debug_callback.h +++ b/src/video_core/vulkan_common/vulkan_debug_callback.h @@ -7,6 +7,8 @@ namespace Vulkan { -vk::DebugUtilsMessenger CreateDebugCallback(const vk::Instance& instance); +vk::DebugUtilsMessenger CreateDebugUtilsCallback(const vk::Instance& instance); + +vk::DebugReportCallback CreateDebugReportCallback(const vk::Instance& instance); } // namespace Vulkan diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index e4ca65b58..9743a82f5 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -349,7 +349,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR const bool is_s8gen2 = device_id == 0x43050a01; const bool is_arm = driver_id == VK_DRIVER_ID_ARM_PROPRIETARY; - if ((is_mvk || is_qualcomm || is_turnip) && !is_suitable) { + if ((is_mvk || is_qualcomm || is_turnip || is_arm) && !is_suitable) { LOG_WARNING(Render_Vulkan, "Unsuitable driver, continuing anyway"); } else if (!is_suitable) { throw vk::Exception(VK_ERROR_INCOMPATIBLE_DRIVER); diff --git a/src/video_core/vulkan_common/vulkan_instance.cpp b/src/video_core/vulkan_common/vulkan_instance.cpp index b6d83e446..7624a9b32 100644 --- a/src/video_core/vulkan_common/vulkan_instance.cpp +++ b/src/video_core/vulkan_common/vulkan_instance.cpp @@ -31,10 +31,34 @@ namespace Vulkan { namespace { + +[[nodiscard]] bool AreExtensionsSupported(const vk::InstanceDispatch& dld, + std::span extensions) { + const std::optional properties = vk::EnumerateInstanceExtensionProperties(dld); + if (!properties) { + LOG_ERROR(Render_Vulkan, "Failed to query extension properties"); + return false; + } + for (const char* extension : extensions) { + const auto it = std::ranges::find_if(*properties, [extension](const auto& prop) { + return std::strcmp(extension, prop.extensionName) == 0; + }); + if (it == properties->end()) { + LOG_ERROR(Render_Vulkan, "Required instance extension {} is not available", extension); + return false; + } + } + return true; +} + [[nodiscard]] std::vector RequiredExtensions( - Core::Frontend::WindowSystemType window_type, bool enable_validation) { + const vk::InstanceDispatch& dld, Core::Frontend::WindowSystemType window_type, + bool enable_validation) { std::vector extensions; extensions.reserve(6); +#ifdef __APPLE__ + extensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME); +#endif switch (window_type) { case Core::Frontend::WindowSystemType::Headless: break; @@ -66,35 +90,14 @@ namespace { extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME); } if (enable_validation) { - extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); + const bool debug_utils = + AreExtensionsSupported(dld, std::array{VK_EXT_DEBUG_UTILS_EXTENSION_NAME}); + extensions.push_back(debug_utils ? VK_EXT_DEBUG_UTILS_EXTENSION_NAME + : VK_EXT_DEBUG_REPORT_EXTENSION_NAME); } - extensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - -#ifdef __APPLE__ - extensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME); -#endif return extensions; } -[[nodiscard]] bool AreExtensionsSupported(const vk::InstanceDispatch& dld, - std::span extensions) { - const std::optional properties = vk::EnumerateInstanceExtensionProperties(dld); - if (!properties) { - LOG_ERROR(Render_Vulkan, "Failed to query extension properties"); - return false; - } - for (const char* extension : extensions) { - const auto it = std::ranges::find_if(*properties, [extension](const auto& prop) { - return std::strcmp(extension, prop.extensionName) == 0; - }); - if (it == properties->end()) { - LOG_ERROR(Render_Vulkan, "Required instance extension {} is not available", extension); - return false; - } - } - return true; -} - [[nodiscard]] std::vector Layers(bool enable_validation) { std::vector layers; if (enable_validation) { @@ -138,7 +141,8 @@ vk::Instance CreateInstance(const Common::DynamicLibrary& library, vk::InstanceD LOG_ERROR(Render_Vulkan, "Failed to load Vulkan function pointers"); throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED); } - const std::vector extensions = RequiredExtensions(window_type, enable_validation); + const std::vector extensions = + RequiredExtensions(dld, window_type, enable_validation); if (!AreExtensionsSupported(dld, extensions)) { throw vk::Exception(VK_ERROR_EXTENSION_NOT_PRESENT); } diff --git a/src/video_core/vulkan_common/vulkan_wrapper.cpp b/src/video_core/vulkan_common/vulkan_wrapper.cpp index 28fcb21a0..2fa29793a 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.cpp +++ b/src/video_core/vulkan_common/vulkan_wrapper.cpp @@ -259,7 +259,9 @@ bool Load(VkInstance instance, InstanceDispatch& dld) noexcept { // These functions may fail to load depending on the enabled extensions. // Don't return a failure on these. X(vkCreateDebugUtilsMessengerEXT); + X(vkCreateDebugReportCallbackEXT); X(vkDestroyDebugUtilsMessengerEXT); + X(vkDestroyDebugReportCallbackEXT); X(vkDestroySurfaceKHR); X(vkGetPhysicalDeviceFeatures2); X(vkGetPhysicalDeviceProperties2); @@ -481,6 +483,11 @@ void Destroy(VkInstance instance, VkDebugUtilsMessengerEXT handle, dld.vkDestroyDebugUtilsMessengerEXT(instance, handle, nullptr); } +void Destroy(VkInstance instance, VkDebugReportCallbackEXT handle, + const InstanceDispatch& dld) noexcept { + dld.vkDestroyDebugReportCallbackEXT(instance, handle, nullptr); +} + void Destroy(VkInstance instance, VkSurfaceKHR handle, const InstanceDispatch& dld) noexcept { dld.vkDestroySurfaceKHR(instance, handle, nullptr); } @@ -549,6 +556,13 @@ DebugUtilsMessenger Instance::CreateDebugUtilsMessenger( return DebugUtilsMessenger(object, handle, *dld); } +DebugReportCallback Instance::CreateDebugReportCallback( + const VkDebugReportCallbackCreateInfoEXT& create_info) const { + VkDebugReportCallbackEXT object; + Check(dld->vkCreateDebugReportCallbackEXT(handle, &create_info, nullptr, &object)); + return DebugReportCallback(object, handle, *dld); +} + void Image::SetObjectNameEXT(const char* name) const { SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_IMAGE, name); } diff --git a/src/video_core/vulkan_common/vulkan_wrapper.h b/src/video_core/vulkan_common/vulkan_wrapper.h index 44fce47a5..b5e70fcd4 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.h +++ b/src/video_core/vulkan_common/vulkan_wrapper.h @@ -164,8 +164,10 @@ struct InstanceDispatch { PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties{}; PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT{}; + PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT{}; PFN_vkCreateDevice vkCreateDevice{}; PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT{}; + PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT{}; PFN_vkDestroyDevice vkDestroyDevice{}; PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR{}; PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties{}; @@ -366,6 +368,7 @@ void Destroy(VkDevice, VkSwapchainKHR, const DeviceDispatch&) noexcept; void Destroy(VkDevice, VkSemaphore, const DeviceDispatch&) noexcept; void Destroy(VkDevice, VkShaderModule, const DeviceDispatch&) noexcept; void Destroy(VkInstance, VkDebugUtilsMessengerEXT, const InstanceDispatch&) noexcept; +void Destroy(VkInstance, VkDebugReportCallbackEXT, const InstanceDispatch&) noexcept; void Destroy(VkInstance, VkSurfaceKHR, const InstanceDispatch&) noexcept; VkResult Free(VkDevice, VkDescriptorPool, Span, const DeviceDispatch&) noexcept; @@ -581,6 +584,7 @@ private: }; using DebugUtilsMessenger = Handle; +using DebugReportCallback = Handle; using DescriptorSetLayout = Handle; using DescriptorUpdateTemplate = Handle; using Pipeline = Handle; @@ -613,6 +617,11 @@ public: DebugUtilsMessenger CreateDebugUtilsMessenger( const VkDebugUtilsMessengerCreateInfoEXT& create_info) const; + /// Creates a debug report callback. + /// @throw Exception on creation failure. + DebugReportCallback CreateDebugReportCallback( + const VkDebugReportCallbackCreateInfoEXT& create_info) const; + /// Returns dispatch table. const InstanceDispatch& Dispatch() const noexcept { return *dld; -- cgit v1.2.3 From c339af37a73de144fbbad706e43aefe278640cd7 Mon Sep 17 00:00:00 2001 From: GPUCode Date: Mon, 5 Jun 2023 19:03:16 +0300 Subject: renderer_vulkan: Respect viewport limit --- src/video_core/vulkan_common/vulkan_device.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/video_core/vulkan_common') diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index b84af3dfb..8a05a4fab 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -588,6 +588,10 @@ public: return properties.properties.limits.maxVertexInputBindings; } + u32 GetMaxViewports() const { + return properties.properties.limits.maxViewports; + } + bool SupportsConditionalBarriers() const { return supports_conditional_barriers; } -- cgit v1.2.3 From 1522b956583aab463bd1576652d1794fe989437d Mon Sep 17 00:00:00 2001 From: GPUCode Date: Mon, 5 Jun 2023 19:04:22 +0300 Subject: renderer_vulkan: Bump minimum SPIRV version * 1.3 is guaranteed on all 1.1 drivers --- src/video_core/vulkan_common/vulkan_device.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/video_core/vulkan_common') diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index 8a05a4fab..13ca24ef5 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -518,7 +518,7 @@ public: if (extensions.spirv_1_4) { return 0x00010400U; } - return 0x00010000U; + return 0x00010300U; } /// Returns true when a known debugging tool is attached. -- cgit v1.2.3 From 220a42896d350399f1f2d77432aa571ade3c9cdd Mon Sep 17 00:00:00 2001 From: GPUCode Date: Mon, 5 Jun 2023 19:07:05 +0300 Subject: renderer_vulkan: Don't assume debug tool with debug renderer * Causes crashes because mali drivers don't support debug utils --- src/video_core/vulkan_common/vulkan_device.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/video_core/vulkan_common') diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index 13ca24ef5..7be631122 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -523,7 +523,7 @@ public: /// Returns true when a known debugging tool is attached. bool HasDebuggingToolAttached() const { - return has_renderdoc || has_nsight_graphics || Settings::values.renderer_debug.GetValue(); + return has_renderdoc || has_nsight_graphics; } /// @returns True if compute pipelines can cause crashing. -- cgit v1.2.3 From b8c96cee5f2eb0bd5ba9ef46746daec78ee3bb44 Mon Sep 17 00:00:00 2001 From: GPUCode Date: Mon, 5 Jun 2023 19:27:36 +0300 Subject: renderer_vulkan: Add more feature checking --- src/video_core/vulkan_common/vulkan_device.cpp | 4 ++++ src/video_core/vulkan_common/vulkan_device.h | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) (limited to 'src/video_core/vulkan_common') diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 9743a82f5..70436cf1c 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -905,6 +905,10 @@ bool Device::GetSuitability(bool requires_swapchain) { properties.driver.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES; SetNext(next, properties.driver); + // Retrieve subgroup properties. + properties.subgroup_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES; + SetNext(next, properties.subgroup_properties); + // Retrieve relevant extension properties. if (extensions.shader_float_controls) { properties.float_controls.sType = diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index 7be631122..e05d04db3 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -323,6 +323,11 @@ public: return properties.subgroup_size_control.requiredSubgroupSizeStages & stage; } + /// Returns true if the device supports the provided subgroup feature. + bool IsSubgroupFeatureSupported(VkSubgroupFeatureFlagBits feature) const { + return properties.subgroup_properties.supportedOperations & feature; + } + /// Returns the maximum number of push descriptors. u32 MaxPushDescriptors() const { return properties.push_descriptor.maxPushDescriptors; @@ -388,6 +393,11 @@ public: return extensions.swapchain_mutable_format; } + /// Returns true if VK_KHR_shader_float_controls is enabled. + bool IsKhrShaderFloatControlsSupported() const { + return extensions.shader_float_controls; + } + /// Returns true if the device supports VK_KHR_workgroup_memory_explicit_layout. bool IsKhrWorkgroupMemoryExplicitLayoutSupported() const { return extensions.workgroup_memory_explicit_layout; @@ -487,6 +497,11 @@ public: return extensions.shader_stencil_export; } + /// Returns true if the device supports VK_EXT_shader_demote_to_helper_invocation + bool IsExtShaderDemoteToHelperInvocationSupported() const { + return extensions.shader_demote_to_helper_invocation; + } + /// Returns true if the device supports VK_EXT_conservative_rasterization. bool IsExtConservativeRasterizationSupported() const { return extensions.conservative_rasterization; @@ -684,6 +699,7 @@ private: struct Properties { VkPhysicalDeviceDriverProperties driver{}; + VkPhysicalDeviceSubgroupProperties subgroup_properties{}; VkPhysicalDeviceFloatControlsProperties float_controls{}; VkPhysicalDevicePushDescriptorPropertiesKHR push_descriptor{}; VkPhysicalDeviceSubgroupSizeControlProperties subgroup_size_control{}; -- cgit v1.2.3 From eac46ad7ceca5e35b396a8b80bfc38dc6ef1a4fe Mon Sep 17 00:00:00 2001 From: GPUCode Date: Tue, 6 Jun 2023 23:10:06 +0300 Subject: video_core: Add BCn decoding support --- src/video_core/vulkan_common/vulkan_device.h | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'src/video_core/vulkan_common') diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index e05d04db3..1f17265d5 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -293,6 +293,11 @@ public: return features.features.textureCompressionASTC_LDR; } + /// Returns true if BCn is natively supported. + bool IsOptimalBcnSupported() const { + return features.features.textureCompressionBC; + } + /// Returns true if descriptor aliasing is natively supported. bool IsDescriptorAliasingSupported() const { return GetDriverID() != VK_DRIVER_ID_QUALCOMM_PROPRIETARY; @@ -423,6 +428,11 @@ public: return extensions.sampler_filter_minmax; } + /// Returns true if the device supports VK_EXT_shader_stencil_export. + bool IsExtShaderStencilExportSupported() const { + return extensions.shader_stencil_export; + } + /// Returns true if the device supports VK_EXT_depth_range_unrestricted. bool IsExtDepthRangeUnrestrictedSupported() const { return extensions.depth_range_unrestricted; @@ -492,11 +502,6 @@ public: return extensions.vertex_input_dynamic_state; } - /// Returns true if the device supports VK_EXT_shader_stencil_export. - bool IsExtShaderStencilExportSupported() const { - return extensions.shader_stencil_export; - } - /// Returns true if the device supports VK_EXT_shader_demote_to_helper_invocation bool IsExtShaderDemoteToHelperInvocationSupported() const { return extensions.shader_demote_to_helper_invocation; -- cgit v1.2.3 From ed93cbd4621c6a0c0ffaa272951e1990732df18f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=ADas=20Locatti?= <42481638+goldenx86@users.noreply.github.com> Date: Wed, 28 Jun 2023 20:10:27 -0300 Subject: Blacklist EDS3 blending from new AMD drivers --- src/video_core/vulkan_common/vulkan_device.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/video_core/vulkan_common') diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 70436cf1c..421e71e5a 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -528,6 +528,14 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR } sets_per_pool = 64; + if (extensions.extended_dynamic_state3 && is_amd_driver && + properties.properties.driverVersion >= VK_MAKE_API_VERSION(0, 2, 0, 270)) { + LOG_WARNING(Render_Vulkan, + "AMD drivers after 23.5.2 have broken extendedDynamicState3ColorBlendEquation"); + features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable = false; + features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation = false; + dynamic_state3_blending = false; + } if (is_amd_driver) { // AMD drivers need a higher amount of Sets per Pool in certain circumstances like in XC2. sets_per_pool = 96; -- cgit v1.2.3