summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Rodrigo Locatti2021-01-24 18:44:51 -0300
committerGravatar GitHub2021-01-24 18:44:51 -0300
commitb769b1be26958eb89b2de938b95c48d390bd1fd8 (patch)
tree900612a33a52d0ee49294547503b873c9862f7fe
parentMerge pull request #5151 from comex/xx-vfs (diff)
parentvk_texture_cache: Support image store on sRGB images with VkImageViewUsageCre... (diff)
downloadyuzu-b769b1be26958eb89b2de938b95c48d390bd1fd8.tar.gz
yuzu-b769b1be26958eb89b2de938b95c48d390bd1fd8.tar.xz
yuzu-b769b1be26958eb89b2de938b95c48d390bd1fd8.zip
Merge pull request #5363 from ReinUsesLisp/vk-image-usage
vk_texture_cache: Support image store on sRGB images with VkImageViewUsageCreateInfo
-rw-r--r--src/video_core/renderer_vulkan/maxwell_to_vk.cpp27
-rw-r--r--src/video_core/renderer_vulkan/maxwell_to_vk.h10
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.cpp73
3 files changed, 72 insertions, 38 deletions
diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp
index ca7c2c579..b4473f194 100644
--- a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp
+++ b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp
@@ -110,8 +110,8 @@ VkCompareOp DepthCompareFunction(Tegra::Texture::DepthCompareFunc depth_compare_
110} // namespace Sampler 110} // namespace Sampler
111 111
112namespace { 112namespace {
113 113constexpr u32 Attachable = 1 << 0;
114enum : u32 { Attachable = 1, Storage = 2 }; 114constexpr u32 Storage = 1 << 1;
115 115
116struct FormatTuple { 116struct FormatTuple {
117 VkFormat format; ///< Vulkan format 117 VkFormat format; ///< Vulkan format
@@ -222,22 +222,27 @@ constexpr bool IsZetaFormat(PixelFormat pixel_format) {
222 222
223} // Anonymous namespace 223} // Anonymous namespace
224 224
225FormatInfo SurfaceFormat(const Device& device, FormatType format_type, PixelFormat pixel_format) { 225FormatInfo SurfaceFormat(const Device& device, FormatType format_type, bool with_srgb,
226 ASSERT(static_cast<std::size_t>(pixel_format) < std::size(tex_format_tuples)); 226 PixelFormat pixel_format) {
227 227 ASSERT(static_cast<size_t>(pixel_format) < std::size(tex_format_tuples));
228 auto tuple = tex_format_tuples[static_cast<std::size_t>(pixel_format)]; 228 FormatTuple tuple = tex_format_tuples[static_cast<size_t>(pixel_format)];
229 if (tuple.format == VK_FORMAT_UNDEFINED) { 229 if (tuple.format == VK_FORMAT_UNDEFINED) {
230 UNIMPLEMENTED_MSG("Unimplemented texture format with pixel format={}", pixel_format); 230 UNIMPLEMENTED_MSG("Unimplemented texture format with pixel format={}", pixel_format);
231 return {VK_FORMAT_A8B8G8R8_UNORM_PACK32, true, true}; 231 return FormatInfo{VK_FORMAT_A8B8G8R8_UNORM_PACK32, true, true};
232 } 232 }
233 233
234 // Use A8B8G8R8_UNORM on hardware that doesn't support ASTC natively 234 // Use A8B8G8R8_UNORM on hardware that doesn't support ASTC natively
235 if (!device.IsOptimalAstcSupported() && VideoCore::Surface::IsPixelFormatASTC(pixel_format)) { 235 if (!device.IsOptimalAstcSupported() && VideoCore::Surface::IsPixelFormatASTC(pixel_format)) {
236 const bool is_srgb = VideoCore::Surface::IsPixelFormatSRGB(pixel_format); 236 const bool is_srgb = with_srgb && VideoCore::Surface::IsPixelFormatSRGB(pixel_format);
237 tuple.format = is_srgb ? VK_FORMAT_A8B8G8R8_SRGB_PACK32 : VK_FORMAT_A8B8G8R8_UNORM_PACK32; 237 if (is_srgb) {
238 tuple.format = VK_FORMAT_A8B8G8R8_SRGB_PACK32;
239 } else {
240 tuple.format = VK_FORMAT_A8B8G8R8_UNORM_PACK32;
241 tuple.usage |= Storage;
242 }
238 } 243 }
239 const bool attachable = tuple.usage & Attachable; 244 const bool attachable = (tuple.usage & Attachable) != 0;
240 const bool storage = tuple.usage & Storage; 245 const bool storage = (tuple.usage & Storage) != 0;
241 246
242 VkFormatFeatureFlags usage{}; 247 VkFormatFeatureFlags usage{};
243 switch (format_type) { 248 switch (format_type) {
diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.h b/src/video_core/renderer_vulkan/maxwell_to_vk.h
index 537969840..e59e6b6e2 100644
--- a/src/video_core/renderer_vulkan/maxwell_to_vk.h
+++ b/src/video_core/renderer_vulkan/maxwell_to_vk.h
@@ -35,7 +35,15 @@ struct FormatInfo {
35 bool storage; 35 bool storage;
36}; 36};
37 37
38FormatInfo SurfaceFormat(const Device& device, FormatType format_type, PixelFormat pixel_format); 38/**
39 * Returns format properties supported in the host
40 * @param device Host device
41 * @param format_type Type of image the buffer will use
42 * @param with_srgb True when the format can be sRGB when converted to another format (ASTC)
43 * @param pixel_format Guest pixel format to describe
44 */
45[[nodiscard]] FormatInfo SurfaceFormat(const Device& device, FormatType format_type, bool with_srgb,
46 PixelFormat pixel_format);
39 47
40VkShaderStageFlagBits ShaderStage(Tegra::Engines::ShaderType stage); 48VkShaderStageFlagBits ShaderStage(Tegra::Engines::ShaderType stage);
41 49
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
index ab14922d7..aa7c5d7c6 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
@@ -95,20 +95,12 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
95 } 95 }
96} 96}
97 97
98[[nodiscard]] VkImageCreateInfo MakeImageCreateInfo(const Device& device, const ImageInfo& info) { 98[[nodiscard]] VkImageUsageFlags ImageUsageFlags(const MaxwellToVK::FormatInfo& info,
99 const auto format_info = MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, info.format); 99 PixelFormat format) {
100 VkImageCreateFlags flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
101 if (info.type == ImageType::e2D && info.resources.layers >= 6 &&
102 info.size.width == info.size.height) {
103 flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
104 }
105 if (info.type == ImageType::e3D) {
106 flags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT;
107 }
108 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | 100 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
109 VK_IMAGE_USAGE_SAMPLED_BIT; 101 VK_IMAGE_USAGE_SAMPLED_BIT;
110 if (format_info.attachable) { 102 if (info.attachable) {
111 switch (VideoCore::Surface::GetFormatType(info.format)) { 103 switch (VideoCore::Surface::GetFormatType(format)) {
112 case VideoCore::Surface::SurfaceType::ColorTexture: 104 case VideoCore::Surface::SurfaceType::ColorTexture:
113 usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 105 usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
114 break; 106 break;
@@ -120,9 +112,33 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
120 UNREACHABLE_MSG("Invalid surface type"); 112 UNREACHABLE_MSG("Invalid surface type");
121 } 113 }
122 } 114 }
123 if (format_info.storage) { 115 if (info.storage) {
124 usage |= VK_IMAGE_USAGE_STORAGE_BIT; 116 usage |= VK_IMAGE_USAGE_STORAGE_BIT;
125 } 117 }
118 return usage;
119}
120
121/// Returns the preferred format for a VkImage
122[[nodiscard]] PixelFormat StorageFormat(PixelFormat format) {
123 switch (format) {
124 case PixelFormat::A8B8G8R8_SRGB:
125 return PixelFormat::A8B8G8R8_UNORM;
126 default:
127 return format;
128 }
129}
130
131[[nodiscard]] VkImageCreateInfo MakeImageCreateInfo(const Device& device, const ImageInfo& info) {
132 const PixelFormat format = StorageFormat(info.format);
133 const auto format_info = MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, false, format);
134 VkImageCreateFlags flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
135 if (info.type == ImageType::e2D && info.resources.layers >= 6 &&
136 info.size.width == info.size.height) {
137 flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
138 }
139 if (info.type == ImageType::e3D) {
140 flags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT;
141 }
126 const auto [samples_x, samples_y] = VideoCommon::SamplesLog2(info.num_samples); 142 const auto [samples_x, samples_y] = VideoCommon::SamplesLog2(info.num_samples);
127 return VkImageCreateInfo{ 143 return VkImageCreateInfo{
128 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, 144 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
@@ -130,17 +146,16 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
130 .flags = flags, 146 .flags = flags,
131 .imageType = ConvertImageType(info.type), 147 .imageType = ConvertImageType(info.type),
132 .format = format_info.format, 148 .format = format_info.format,
133 .extent = 149 .extent{
134 { 150 .width = info.size.width >> samples_x,
135 .width = info.size.width >> samples_x, 151 .height = info.size.height >> samples_y,
136 .height = info.size.height >> samples_y, 152 .depth = info.size.depth,
137 .depth = info.size.depth, 153 },
138 },
139 .mipLevels = static_cast<u32>(info.resources.levels), 154 .mipLevels = static_cast<u32>(info.resources.levels),
140 .arrayLayers = static_cast<u32>(info.resources.layers), 155 .arrayLayers = static_cast<u32>(info.resources.layers),
141 .samples = ConvertSampleCount(info.num_samples), 156 .samples = ConvertSampleCount(info.num_samples),
142 .tiling = VK_IMAGE_TILING_OPTIMAL, 157 .tiling = VK_IMAGE_TILING_OPTIMAL,
143 .usage = usage, 158 .usage = ImageUsageFlags(format_info, format),
144 .sharingMode = VK_SHARING_MODE_EXCLUSIVE, 159 .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
145 .queueFamilyIndexCount = 0, 160 .queueFamilyIndexCount = 0,
146 .pQueueFamilyIndices = nullptr, 161 .pQueueFamilyIndices = nullptr,
@@ -209,10 +224,11 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
209 224
210[[nodiscard]] VkAttachmentDescription AttachmentDescription(const Device& device, 225[[nodiscard]] VkAttachmentDescription AttachmentDescription(const Device& device,
211 const ImageView* image_view) { 226 const ImageView* image_view) {
212 const auto pixel_format = image_view->format; 227 using MaxwellToVK::SurfaceFormat;
228 const PixelFormat pixel_format = image_view->format;
213 return VkAttachmentDescription{ 229 return VkAttachmentDescription{
214 .flags = VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT, 230 .flags = VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT,
215 .format = MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, pixel_format).format, 231 .format = SurfaceFormat(device, FormatType::Optimal, true, pixel_format).format,
216 .samples = image_view->Samples(), 232 .samples = image_view->Samples(),
217 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, 233 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
218 .storeOp = VK_ATTACHMENT_STORE_OP_STORE, 234 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
@@ -868,11 +884,16 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI
868 std::ranges::transform(swizzle, swizzle.begin(), ConvertGreenRed); 884 std::ranges::transform(swizzle, swizzle.begin(), ConvertGreenRed);
869 } 885 }
870 } 886 }
871 const VkFormat vk_format = 887 const auto format_info = MaxwellToVK::SurfaceFormat(*device, FormatType::Optimal, true, format);
872 MaxwellToVK::SurfaceFormat(*device, FormatType::Optimal, format).format; 888 const VkFormat vk_format = format_info.format;
889 const VkImageViewUsageCreateInfo image_view_usage{
890 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO,
891 .pNext = nullptr,
892 .usage = ImageUsageFlags(format_info, format),
893 };
873 const VkImageViewCreateInfo create_info{ 894 const VkImageViewCreateInfo create_info{
874 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 895 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
875 .pNext = nullptr, 896 .pNext = &image_view_usage,
876 .flags = 0, 897 .flags = 0,
877 .image = image.Handle(), 898 .image = image.Handle(),
878 .viewType = VkImageViewType{}, 899 .viewType = VkImageViewType{},
@@ -962,7 +983,7 @@ vk::ImageView ImageView::MakeDepthStencilView(VkImageAspectFlags aspect_mask) {
962 .flags = 0, 983 .flags = 0,
963 .image = image_handle, 984 .image = image_handle,
964 .viewType = ImageViewType(type), 985 .viewType = ImageViewType(type),
965 .format = MaxwellToVK::SurfaceFormat(*device, FormatType::Optimal, format).format, 986 .format = MaxwellToVK::SurfaceFormat(*device, FormatType::Optimal, true, format).format,
966 .components{ 987 .components{
967 .r = VK_COMPONENT_SWIZZLE_IDENTITY, 988 .r = VK_COMPONENT_SWIZZLE_IDENTITY,
968 .g = VK_COMPONENT_SWIZZLE_IDENTITY, 989 .g = VK_COMPONENT_SWIZZLE_IDENTITY,