diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 8909c77af3..24853ebb9e 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -1406,7 +1406,7 @@ Image::Image(TextureCacheRuntime& runtime_, const ImageInfo& info_, GPUVAddr gpu if (runtime->device.HasDebuggingToolAttached()) { original_image.SetObjectNameEXT(VideoCommon::Name(*this).c_str()); } - current_image = *original_image; + current_image = &Image::original_image; storage_image_views.resize(info.resources.levels); if (IsPixelFormatASTC(info.format) && !runtime->device.IsOptimalAstcSupported() && Settings::values.astc_recompression.GetValue() == @@ -1550,8 +1550,8 @@ VkImageView Image::StorageImageView(s32 level) noexcept { if (!view) { const auto format_info = MaxwellToVK::SurfaceFormat(runtime->device, FormatType::Optimal, true, info.format); - view = - MakeStorageView(runtime->device.GetLogical(), level, current_image, format_info.format); + view = MakeStorageView(runtime->device.GetLogical(), level, *(this->*current_image), + format_info.format); } return *view; } @@ -1582,7 +1582,7 @@ bool Image::ScaleUp(bool ignore) { runtime->ViewFormats(info.format)); ignore = false; } - current_image = *scaled_image; + current_image = &Image::scaled_image; if (ignore) { return true; } @@ -1607,7 +1607,7 @@ bool Image::ScaleDown(bool ignore) { } ASSERT(info.type != ImageType::Linear); flags &= ~ImageFlagBits::Rescaled; - current_image = *original_image; + current_image = &Image::original_image; if (ignore) { return true; } @@ -1726,7 +1726,7 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI const VkImageViewUsageCreateInfo image_view_usage{ .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO, .pNext = nullptr, - .usage = ImageUsageFlags(format_info, format), + .usage = image.UsageFlags(), }; const VkImageViewCreateInfo create_info{ .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, @@ -2087,4 +2087,4 @@ void TextureCacheRuntime::TransitionImageLayout(Image& image) { } } -} // namespace Vulkan \ No newline at end of file +} // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h index 8501ec384b..4161d7ff92 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.h +++ b/src/video_core/renderer_vulkan/vk_texture_cache.h @@ -24,7 +24,6 @@ using Common::SlotVector; using VideoCommon::ImageId; using VideoCommon::NUM_RT; using VideoCommon::Region2D; -using VideoCommon::RenderTargets; using VideoCore::Surface::PixelFormat; class BlitImageHelper; @@ -157,13 +156,17 @@ public: std::span copies); [[nodiscard]] VkImage Handle() const noexcept { - return current_image; + return *(this->*current_image); } [[nodiscard]] VkImageAspectFlags AspectMask() const noexcept { return aspect_mask; } + [[nodiscard]] VkImageUsageFlags UsageFlags() const noexcept { + return (this->*current_image).UsageFlags(); + } + /// Returns true when the image is already initialized and mark it as initialized [[nodiscard]] bool ExchangeInitialization() noexcept { return std::exchange(initialized, true); @@ -186,11 +189,15 @@ private: TextureCacheRuntime* runtime{}; vk::Image original_image; + vk::Image scaled_image; + + // Use a pointer to field because it is relative, so that the object can be + // moved without breaking the reference. + vk::Image Image::*current_image{}; + std::vector storage_image_views; VkImageAspectFlags aspect_mask = 0; bool initialized = false; - vk::Image scaled_image{}; - VkImage current_image{}; std::unique_ptr scale_framebuffer; std::unique_ptr scale_view; diff --git a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp index 8f4a57e3ca..54331688e3 100644 --- a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp +++ b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp @@ -247,7 +247,7 @@ vk::Image MemoryAllocator::CreateImage(const VkImageCreateInfo& ci) const { vk::Check(vmaCreateImage(allocator, &ci, &alloc_ci, &handle, &allocation, nullptr)); - return vk::Image(handle, *device.GetLogical(), allocator, allocation, + return vk::Image(handle, ci.usage, *device.GetLogical(), allocator, allocation, device.GetDispatchLoader()); } diff --git a/src/video_core/vulkan_common/vulkan_wrapper.h b/src/video_core/vulkan_common/vulkan_wrapper.h index 757f3c8afb..1bb8a47bdf 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.h +++ b/src/video_core/vulkan_common/vulkan_wrapper.h @@ -623,9 +623,10 @@ public: class Image { public: - explicit Image(VkImage handle_, VkDevice owner_, VmaAllocator allocator_, - VmaAllocation allocation_, const DeviceDispatch& dld_) noexcept - : handle{handle_}, owner{owner_}, allocator{allocator_}, + explicit Image(VkImage handle_, VkImageUsageFlags usage_, VkDevice owner_, + VmaAllocator allocator_, VmaAllocation allocation_, + const DeviceDispatch& dld_) noexcept + : handle{handle_}, usage{usage_}, owner{owner_}, allocator{allocator_}, allocation{allocation_}, dld{&dld_} {} Image() = default; @@ -633,12 +634,13 @@ public: 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} {} + : handle{std::exchange(rhs.handle, nullptr)}, usage{rhs.usage}, owner{rhs.owner}, + allocator{rhs.allocator}, allocation{rhs.allocation}, dld{rhs.dld} {} Image& operator=(Image&& rhs) noexcept { Release(); handle = std::exchange(rhs.handle, nullptr); + usage = rhs.usage; owner = rhs.owner; allocator = rhs.allocator; allocation = rhs.allocation; @@ -665,10 +667,15 @@ public: void SetObjectNameEXT(const char* name) const; + [[nodiscard]] VkImageUsageFlags UsageFlags() const noexcept { + return usage; + } + private: void Release() const noexcept; VkImage handle = nullptr; + VkImageUsageFlags usage{}; VkDevice owner = nullptr; VmaAllocator allocator = nullptr; VmaAllocation allocation = nullptr;