summaryrefslogtreecommitdiff
path: root/src/video_core/renderer_vulkan
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2021-10-17 18:01:18 +0200
committerGravatar Fernando Sahmkow2021-11-16 22:11:31 +0100
commit425ab9ef4b982213f4ee0d53196f5474e255374f (patch)
tree467bc959ea481d58514d11ca73e8f31b3557d4aa /src/video_core/renderer_vulkan
parentPresentation: add Nearest Neighbor filter. (diff)
downloadyuzu-425ab9ef4b982213f4ee0d53196f5474e255374f.tar.gz
yuzu-425ab9ef4b982213f4ee0d53196f5474e255374f.tar.xz
yuzu-425ab9ef4b982213f4ee0d53196f5474e255374f.zip
Texture Cache: Fix downscaling and correct memory comsumption.
Diffstat (limited to 'src/video_core/renderer_vulkan')
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.cpp93
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.h3
2 files changed, 86 insertions, 10 deletions
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
index 17c62e27d..51367c01d 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
@@ -592,7 +592,8 @@ struct RangedBarrierRange {
592} 592}
593 593
594void BlitScale(VKScheduler& scheduler, VkImage src_image, VkImage dst_image, const ImageInfo& info, 594void BlitScale(VKScheduler& scheduler, VkImage src_image, VkImage dst_image, const ImageInfo& info,
595 VkImageAspectFlags aspect_mask, const Settings::ResolutionScalingInfo& resolution) { 595 VkImageAspectFlags aspect_mask, const Settings::ResolutionScalingInfo& resolution,
596 bool up_scaling = true) {
596 const bool is_2d = info.type == ImageType::e2D; 597 const bool is_2d = info.type == ImageType::e2D;
597 const auto resources = info.resources; 598 const auto resources = info.resources;
598 const VkExtent2D extent{ 599 const VkExtent2D extent{
@@ -605,14 +606,16 @@ void BlitScale(VKScheduler& scheduler, VkImage src_image, VkImage dst_image, con
605 606
606 scheduler.RequestOutsideRenderPassOperationContext(); 607 scheduler.RequestOutsideRenderPassOperationContext();
607 scheduler.Record([dst_image, src_image, extent, resources, aspect_mask, resolution, is_2d, 608 scheduler.Record([dst_image, src_image, extent, resources, aspect_mask, resolution, is_2d,
608 vk_filter](vk::CommandBuffer cmdbuf) { 609 vk_filter, up_scaling](vk::CommandBuffer cmdbuf) {
609 const VkOffset2D src_size{ 610 const VkOffset2D src_size{
610 .x = static_cast<s32>(extent.width), 611 .x = static_cast<s32>(up_scaling ? extent.width : resolution.ScaleUp(extent.width)),
611 .y = static_cast<s32>(extent.height), 612 .y = static_cast<s32>(is_2d && up_scaling ? extent.height
613 : resolution.ScaleUp(extent.height)),
612 }; 614 };
613 const VkOffset2D dst_size{ 615 const VkOffset2D dst_size{
614 .x = static_cast<s32>(resolution.ScaleUp(extent.width)), 616 .x = static_cast<s32>(up_scaling ? resolution.ScaleUp(extent.width) : extent.width),
615 .y = static_cast<s32>(is_2d ? resolution.ScaleUp(extent.height) : extent.height), 617 .y = static_cast<s32>(is_2d && up_scaling ? resolution.ScaleUp(extent.height)
618 : extent.height),
616 }; 619 };
617 boost::container::small_vector<VkImageBlit, 4> regions; 620 boost::container::small_vector<VkImageBlit, 4> regions;
618 regions.reserve(resources.levels); 621 regions.reserve(resources.levels);
@@ -1134,6 +1137,7 @@ bool Image::ScaleUp() {
1134 if (!resolution.active) { 1137 if (!resolution.active) {
1135 return false; 1138 return false;
1136 } 1139 }
1140 scale_count++;
1137 const auto& device = runtime->device; 1141 const auto& device = runtime->device;
1138 const bool is_2d = info.type == ImageType::e2D; 1142 const bool is_2d = info.type == ImageType::e2D;
1139 const u32 scaled_width = resolution.ScaleUp(info.size.width); 1143 const u32 scaled_width = resolution.ScaleUp(info.size.width);
@@ -1161,8 +1165,10 @@ bool Image::ScaleUp() {
1161 using namespace VideoCommon; 1165 using namespace VideoCommon;
1162 static constexpr auto BLIT_OPERATION = Tegra::Engines::Fermi2D::Operation::SrcCopy; 1166 static constexpr auto BLIT_OPERATION = Tegra::Engines::Fermi2D::Operation::SrcCopy;
1163 1167
1164 const auto view_info = ImageViewInfo(ImageViewType::e2D, info.format); 1168 if (!scale_view) {
1165 scale_view = std::make_unique<ImageView>(*runtime, view_info, NULL_IMAGE_ID, *this); 1169 const auto view_info = ImageViewInfo(ImageViewType::e2D, info.format);
1170 scale_view = std::make_unique<ImageView>(*runtime, view_info, NULL_IMAGE_ID, *this);
1171 }
1166 auto* view_ptr = scale_view.get(); 1172 auto* view_ptr = scale_view.get();
1167 1173
1168 const Region2D src_region{ 1174 const Region2D src_region{
@@ -1178,7 +1184,10 @@ bool Image::ScaleUp() {
1178 .height = scaled_height, 1184 .height = scaled_height,
1179 }; 1185 };
1180 if (aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT) { 1186 if (aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT) {
1181 scale_framebuffer = std::make_unique<Framebuffer>(*runtime, view_ptr, nullptr, extent); 1187 if (!scale_framebuffer) {
1188 scale_framebuffer =
1189 std::make_unique<Framebuffer>(*runtime, view_ptr, nullptr, extent);
1190 }
1182 const auto color_view = scale_view->Handle(Shader::TextureType::Color2D); 1191 const auto color_view = scale_view->Handle(Shader::TextureType::Color2D);
1183 1192
1184 runtime->blit_image_helper.BlitColor( 1193 runtime->blit_image_helper.BlitColor(
@@ -1186,7 +1195,10 @@ bool Image::ScaleUp() {
1186 Tegra::Engines::Fermi2D::Filter::Bilinear, BLIT_OPERATION); 1195 Tegra::Engines::Fermi2D::Filter::Bilinear, BLIT_OPERATION);
1187 } else if (!runtime->device.IsBlitDepthStencilSupported() && 1196 } else if (!runtime->device.IsBlitDepthStencilSupported() &&
1188 aspect_mask == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { 1197 aspect_mask == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
1189 scale_framebuffer = std::make_unique<Framebuffer>(*runtime, nullptr, view_ptr, extent); 1198 if (!scale_framebuffer) {
1199 scale_framebuffer =
1200 std::make_unique<Framebuffer>(*runtime, view_ptr, nullptr, extent);
1201 }
1190 runtime->blit_image_helper.BlitDepthStencil( 1202 runtime->blit_image_helper.BlitDepthStencil(
1191 scale_framebuffer.get(), scale_view->DepthView(), scale_view->StencilView(), 1203 scale_framebuffer.get(), scale_view->DepthView(), scale_view->StencilView(),
1192 dst_region, src_region, Tegra::Engines::Fermi2D::Filter::Point, BLIT_OPERATION); 1204 dst_region, src_region, Tegra::Engines::Fermi2D::Filter::Point, BLIT_OPERATION);
@@ -1209,6 +1221,67 @@ bool Image::ScaleDown() {
1209 if (!resolution.active) { 1221 if (!resolution.active) {
1210 return false; 1222 return false;
1211 } 1223 }
1224 const auto& device = runtime->device;
1225 const bool is_2d = info.type == ImageType::e2D;
1226 const u32 scaled_width = resolution.ScaleUp(info.size.width);
1227 const u32 scaled_height = is_2d ? resolution.ScaleUp(info.size.height) : info.size.height;
1228 if (aspect_mask == 0) {
1229 aspect_mask = ImageAspectMask(info.format);
1230 }
1231 static constexpr auto OPTIMAL_FORMAT = FormatType::Optimal;
1232 const PixelFormat format = StorageFormat(info.format);
1233 const auto vk_format = MaxwellToVK::SurfaceFormat(device, OPTIMAL_FORMAT, false, format).format;
1234 const auto blit_usage = VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT;
1235 if (device.IsFormatSupported(vk_format, blit_usage, OPTIMAL_FORMAT)) {
1236 BlitScale(*scheduler, *scaled_image, *original_image, info, aspect_mask, resolution, false);
1237 } else {
1238 using namespace VideoCommon;
1239 static constexpr auto BLIT_OPERATION = Tegra::Engines::Fermi2D::Operation::SrcCopy;
1240
1241 if (!normal_view) {
1242 const auto view_info = ImageViewInfo(ImageViewType::e2D, info.format);
1243 normal_view = std::make_unique<ImageView>(*runtime, view_info, NULL_IMAGE_ID, *this);
1244 }
1245 auto* view_ptr = normal_view.get();
1246
1247 const Region2D src_region{
1248 .start = {0, 0},
1249 .end = {static_cast<s32>(scaled_width), static_cast<s32>(scaled_height)},
1250 };
1251 const Region2D dst_region{
1252 .start = {0, 0},
1253 .end = {static_cast<s32>(info.size.width), static_cast<s32>(info.size.height)},
1254 };
1255 const VkExtent2D extent{
1256 .width = scaled_width,
1257 .height = scaled_height,
1258 };
1259 if (aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT) {
1260 if (!normal_framebuffer) {
1261 normal_framebuffer =
1262 std::make_unique<Framebuffer>(*runtime, view_ptr, nullptr, extent);
1263 }
1264 const auto color_view = normal_view->Handle(Shader::TextureType::Color2D);
1265
1266 runtime->blit_image_helper.BlitColor(
1267 normal_framebuffer.get(), color_view, dst_region, src_region,
1268 Tegra::Engines::Fermi2D::Filter::Bilinear, BLIT_OPERATION);
1269 } else if (!runtime->device.IsBlitDepthStencilSupported() &&
1270 aspect_mask == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
1271 if (!normal_framebuffer) {
1272 normal_framebuffer =
1273 std::make_unique<Framebuffer>(*runtime, view_ptr, nullptr, extent);
1274 }
1275 runtime->blit_image_helper.BlitDepthStencil(
1276 normal_framebuffer.get(), normal_view->DepthView(), normal_view->StencilView(),
1277 dst_region, src_region, Tegra::Engines::Fermi2D::Filter::Point, BLIT_OPERATION);
1278 } else {
1279 // TODO: Use helper blits where applicable
1280 flags &= ~ImageFlagBits::Rescaled;
1281 LOG_ERROR(Render_Vulkan, "Device does not support scaling format {}", format);
1282 return false;
1283 }
1284 }
1212 ASSERT(info.type != ImageType::Linear); 1285 ASSERT(info.type != ImageType::Linear);
1213 current_image = *original_image; 1286 current_image = *original_image;
1214 return true; 1287 return true;
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h
index 6dc190632..df854a20c 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.h
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.h
@@ -148,6 +148,9 @@ private:
148 148
149 std::unique_ptr<Framebuffer> scale_framebuffer; 149 std::unique_ptr<Framebuffer> scale_framebuffer;
150 std::unique_ptr<ImageView> scale_view; 150 std::unique_ptr<ImageView> scale_view;
151
152 std::unique_ptr<Framebuffer> normal_framebuffer;
153 std::unique_ptr<ImageView> normal_view;
151}; 154};
152 155
153class ImageView : public VideoCommon::ImageViewBase { 156class ImageView : public VideoCommon::ImageViewBase {