diff --git a/src/video_core/texture_cache/image.cpp b/src/video_core/texture_cache/image.cpp index 7788ac982..16a9ce96a 100644 --- a/src/video_core/texture_cache/image.cpp +++ b/src/video_core/texture_cache/image.cpp @@ -86,6 +86,28 @@ static vk::ImageUsageFlags ImageUsageFlags(const ImageInfo& info) { return usage; } +static vk::FormatFeatureFlags2 FormatFeatureFlags(const vk::ImageUsageFlags usage_flags) { + vk::FormatFeatureFlags2 feature_flags{}; + if (usage_flags & vk::ImageUsageFlagBits::eTransferSrc) { + feature_flags |= vk::FormatFeatureFlagBits2::eTransferSrc; + } + if (usage_flags & vk::ImageUsageFlagBits::eTransferDst) { + feature_flags |= vk::FormatFeatureFlagBits2::eTransferDst; + } + if (usage_flags & vk::ImageUsageFlagBits::eSampled) { + feature_flags |= vk::FormatFeatureFlagBits2::eSampledImage; + } + if (usage_flags & vk::ImageUsageFlagBits::eColorAttachment) { + feature_flags |= vk::FormatFeatureFlagBits2::eColorAttachment; + } + if (usage_flags & vk::ImageUsageFlagBits::eDepthStencilAttachment) { + feature_flags |= vk::FormatFeatureFlagBits2::eDepthStencilAttachment; + } + // Note: StorageImage is intentionally ignored for now since it is always set, and can mess up + // compatibility checks. + return feature_flags; +} + UniqueImage::UniqueImage(vk::Device device_, VmaAllocator allocator_) : device{device_}, allocator{allocator_} {} @@ -132,6 +154,7 @@ Image::Image(const Vulkan::Instance& instance_, Vulkan::Scheduler& scheduler_, } usage = ImageUsageFlags(info); + format_features = FormatFeatureFlags(usage); switch (info.pixel_format) { case vk::Format::eD16Unorm: @@ -149,8 +172,7 @@ Image::Image(const Vulkan::Instance& instance_, Vulkan::Scheduler& scheduler_, } constexpr auto tiling = vk::ImageTiling::eOptimal; - const auto supported_format = - instance->GetSupportedFormat(info.pixel_format, vk::FormatFeatureFlagBits2::eSampledImage); + const auto supported_format = instance->GetSupportedFormat(info.pixel_format, format_features); const auto properties = instance->GetPhysicalDevice().getImageFormatProperties( supported_format, info.type, tiling, usage, flags); const auto supported_samples = properties.result == vk::Result::eSuccess diff --git a/src/video_core/texture_cache/image.h b/src/video_core/texture_cache/image.h index 01e6fe8f3..312ff97e8 100644 --- a/src/video_core/texture_cache/image.h +++ b/src/video_core/texture_cache/image.h @@ -114,6 +114,7 @@ struct Image { // Resource state tracking vk::ImageUsageFlags usage; + vk::FormatFeatureFlags2 format_features; struct State { vk::Flags pl_stage = vk::PipelineStageFlagBits2::eAllCommands; vk::Flags access_mask = vk::AccessFlagBits2::eNone; diff --git a/src/video_core/texture_cache/image_view.cpp b/src/video_core/texture_cache/image_view.cpp index 024374649..a77798e1b 100644 --- a/src/video_core/texture_cache/image_view.cpp +++ b/src/video_core/texture_cache/image_view.cpp @@ -164,9 +164,9 @@ ImageView::ImageView(const Vulkan::Instance& instance, const ImageViewInfo& info .pNext = &usage_ci, .image = image.image, .viewType = info.type, - .format = instance.GetSupportedFormat(format, vk::FormatFeatureFlagBits2::eSampledImage), - .components = instance.GetSupportedComponentSwizzle( - format, info.mapping, vk::FormatFeatureFlagBits2::eSampledImage), + .format = instance.GetSupportedFormat(format, image.format_features), + .components = + instance.GetSupportedComponentSwizzle(format, info.mapping, image.format_features), .subresourceRange{ .aspectMask = aspect, .baseMipLevel = info.range.base.level,