summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ameerj2021-10-22 23:46:21 -0400
committerGravatar Fernando Sahmkow2021-11-16 22:11:32 +0100
commit282a4501d9b8c3e68e1c4545778097888caa7a88 (patch)
treed2204b5eae6b59a34c0f7dc38a1183111db4adca /src
parentgl_rasterizer: Fix ScissorTest and Clear when scaling (diff)
downloadyuzu-282a4501d9b8c3e68e1c4545778097888caa7a88.tar.gz
yuzu-282a4501d9b8c3e68e1c4545778097888caa7a88.tar.xz
yuzu-282a4501d9b8c3e68e1c4545778097888caa7a88.zip
vk_texture_cache: Refactor 3D scaling helpers
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.cpp185
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.h2
2 files changed, 74 insertions, 113 deletions
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
index 413d472cd..85a1d520b 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
@@ -593,13 +593,16 @@ struct RangedBarrierRange {
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 is_bilinear, bool up_scaling = true) { 596 bool up_scaling = true) {
597 const bool is_2d = info.type == ImageType::e2D; 597 const bool is_2d = info.type == ImageType::e2D;
598 const auto resources = info.resources; 598 const auto resources = info.resources;
599 const VkExtent2D extent{ 599 const VkExtent2D extent{
600 .width = info.size.width, 600 .width = info.size.width,
601 .height = info.size.height, 601 .height = info.size.height,
602 }; 602 };
603 // Depth and integer formats must use NEAREST filter for blits.
604 const bool is_color{aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT};
605 const bool is_bilinear{is_color && !IsPixelFormatInteger(info.format)};
603 const VkFilter vk_filter = is_bilinear ? VK_FILTER_LINEAR : VK_FILTER_NEAREST; 606 const VkFilter vk_filter = is_bilinear ? VK_FILTER_LINEAR : VK_FILTER_NEAREST;
604 607
605 scheduler.RequestOutsideRenderPassOperationContext(); 608 scheduler.RequestOutsideRenderPassOperationContext();
@@ -1144,10 +1147,10 @@ bool Image::ScaleUp(bool ignore) {
1144 } 1147 }
1145 has_scaled = true; 1148 has_scaled = true;
1146 const auto& device = runtime->device; 1149 const auto& device = runtime->device;
1147 const bool is_2d = info.type == ImageType::e2D;
1148 const u32 scaled_width = resolution.ScaleUp(info.size.width);
1149 const u32 scaled_height = is_2d ? resolution.ScaleUp(info.size.height) : info.size.height;
1150 if (!scaled_image) { 1150 if (!scaled_image) {
1151 const bool is_2d = info.type == ImageType::e2D;
1152 const u32 scaled_width = resolution.ScaleUp(info.size.width);
1153 const u32 scaled_height = is_2d ? resolution.ScaleUp(info.size.height) : info.size.height;
1151 auto scaled_info = info; 1154 auto scaled_info = info;
1152 scaled_info.size.width = scaled_width; 1155 scaled_info.size.width = scaled_width;
1153 scaled_info.size.height = scaled_height; 1156 scaled_info.size.height = scaled_height;
@@ -1168,61 +1171,10 @@ bool Image::ScaleUp(bool ignore) {
1168 const PixelFormat format = StorageFormat(info.format); 1171 const PixelFormat format = StorageFormat(info.format);
1169 const auto vk_format = MaxwellToVK::SurfaceFormat(device, OPTIMAL_FORMAT, false, format).format; 1172 const auto vk_format = MaxwellToVK::SurfaceFormat(device, OPTIMAL_FORMAT, false, format).format;
1170 const auto blit_usage = VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT; 1173 const auto blit_usage = VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT;
1171 const bool is_color{aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT};
1172 const bool is_bilinear{is_color && !IsPixelFormatInteger(info.format)};
1173 if (device.IsFormatSupported(vk_format, blit_usage, OPTIMAL_FORMAT)) { 1174 if (device.IsFormatSupported(vk_format, blit_usage, OPTIMAL_FORMAT)) {
1174 BlitScale(*scheduler, *original_image, *scaled_image, info, aspect_mask, resolution, 1175 BlitScale(*scheduler, *original_image, *scaled_image, info, aspect_mask, resolution);
1175 device.IsFormatSupported(vk_format,
1176 VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT,
1177 OPTIMAL_FORMAT));
1178 } else { 1176 } else {
1179 using namespace VideoCommon; 1177 return BlitScaleHelper(true);
1180 static constexpr auto BLIT_OPERATION = Tegra::Engines::Fermi2D::Operation::SrcCopy;
1181 const auto operation = is_bilinear ? Tegra::Engines::Fermi2D::Filter::Bilinear
1182 : Tegra::Engines::Fermi2D::Filter::Point;
1183
1184 if (!scale_view) {
1185 const auto view_info = ImageViewInfo(ImageViewType::e2D, info.format);
1186 scale_view = std::make_unique<ImageView>(*runtime, view_info, NULL_IMAGE_ID, *this);
1187 }
1188 auto* view_ptr = scale_view.get();
1189
1190 const Region2D src_region{
1191 .start = {0, 0},
1192 .end = {static_cast<s32>(info.size.width), static_cast<s32>(info.size.height)},
1193 };
1194 const Region2D dst_region{
1195 .start = {0, 0},
1196 .end = {static_cast<s32>(scaled_width), static_cast<s32>(scaled_height)},
1197 };
1198 const VkExtent2D extent{
1199 .width = scaled_width,
1200 .height = scaled_height,
1201 };
1202 if (aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT) {
1203 if (!scale_framebuffer) {
1204 scale_framebuffer =
1205 std::make_unique<Framebuffer>(*runtime, view_ptr, nullptr, extent);
1206 }
1207 const auto color_view = scale_view->Handle(Shader::TextureType::Color2D);
1208
1209 runtime->blit_image_helper.BlitColor(scale_framebuffer.get(), color_view, dst_region,
1210 src_region, operation, BLIT_OPERATION);
1211 } else if (!runtime->device.IsBlitDepthStencilSupported() &&
1212 aspect_mask == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
1213 if (!scale_framebuffer) {
1214 scale_framebuffer =
1215 std::make_unique<Framebuffer>(*runtime, nullptr, view_ptr, extent);
1216 }
1217 runtime->blit_image_helper.BlitDepthStencil(
1218 scale_framebuffer.get(), scale_view->DepthView(), scale_view->StencilView(),
1219 dst_region, src_region, operation, BLIT_OPERATION);
1220 } else {
1221 // TODO: Use helper blits where applicable
1222 flags &= ~ImageFlagBits::Rescaled;
1223 LOG_ERROR(Render_Vulkan, "Device does not support scaling format {}", format);
1224 return false;
1225 }
1226 } 1178 }
1227 return true; 1179 return true;
1228} 1180}
@@ -1231,82 +1183,89 @@ bool Image::ScaleDown(bool ignore) {
1231 if (False(flags & ImageFlagBits::Rescaled)) { 1183 if (False(flags & ImageFlagBits::Rescaled)) {
1232 return false; 1184 return false;
1233 } 1185 }
1186 ASSERT(info.type != ImageType::Linear);
1234 flags &= ~ImageFlagBits::Rescaled; 1187 flags &= ~ImageFlagBits::Rescaled;
1235 const auto& resolution = runtime->resolution; 1188 const auto& resolution = runtime->resolution;
1236 if (!resolution.active) { 1189 if (!resolution.active) {
1237 return false; 1190 return false;
1238 } 1191 }
1192 current_image = *original_image;
1239 if (ignore) { 1193 if (ignore) {
1240 current_image = *original_image;
1241 return true; 1194 return true;
1242 } 1195 }
1243 const auto& device = runtime->device;
1244 const bool is_2d = info.type == ImageType::e2D;
1245 const u32 scaled_width = resolution.ScaleUp(info.size.width);
1246 const u32 scaled_height = is_2d ? resolution.ScaleUp(info.size.height) : info.size.height;
1247 if (aspect_mask == 0) { 1196 if (aspect_mask == 0) {
1248 aspect_mask = ImageAspectMask(info.format); 1197 aspect_mask = ImageAspectMask(info.format);
1249 } 1198 }
1250 static constexpr auto OPTIMAL_FORMAT = FormatType::Optimal; 1199 static constexpr auto OPTIMAL_FORMAT = FormatType::Optimal;
1251 const PixelFormat format = StorageFormat(info.format); 1200 const PixelFormat format = StorageFormat(info.format);
1201 const auto& device = runtime->device;
1252 const auto vk_format = MaxwellToVK::SurfaceFormat(device, OPTIMAL_FORMAT, false, format).format; 1202 const auto vk_format = MaxwellToVK::SurfaceFormat(device, OPTIMAL_FORMAT, false, format).format;
1253 const auto blit_usage = VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT; 1203 const auto blit_usage = VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT;
1254 const bool is_color{aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT};
1255 const bool is_bilinear{is_color && !IsPixelFormatInteger(info.format)};
1256 if (device.IsFormatSupported(vk_format, blit_usage, OPTIMAL_FORMAT)) { 1204 if (device.IsFormatSupported(vk_format, blit_usage, OPTIMAL_FORMAT)) {
1257 BlitScale(*scheduler, *scaled_image, *original_image, info, aspect_mask, resolution, 1205 BlitScale(*scheduler, *scaled_image, *original_image, info, aspect_mask, resolution, false);
1258 is_bilinear, false);
1259 } else { 1206 } else {
1260 using namespace VideoCommon; 1207 return BlitScaleHelper(false);
1261 static constexpr auto BLIT_OPERATION = Tegra::Engines::Fermi2D::Operation::SrcCopy; 1208 }
1262 const auto operation = is_bilinear ? Tegra::Engines::Fermi2D::Filter::Bilinear 1209 return true;
1263 : Tegra::Engines::Fermi2D::Filter::Point; 1210}
1264
1265 if (!normal_view) {
1266 const auto view_info = ImageViewInfo(ImageViewType::e2D, info.format);
1267 normal_view = std::make_unique<ImageView>(*runtime, view_info, NULL_IMAGE_ID, *this);
1268 }
1269 auto* view_ptr = normal_view.get();
1270 1211
1271 const Region2D src_region{ 1212bool Image::BlitScaleHelper(bool scale_up) {
1272 .start = {0, 0}, 1213 using namespace VideoCommon;
1273 .end = {static_cast<s32>(scaled_width), static_cast<s32>(scaled_height)}, 1214 static constexpr auto BLIT_OPERATION = Tegra::Engines::Fermi2D::Operation::SrcCopy;
1274 }; 1215 const bool is_color{aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT};
1275 const Region2D dst_region{ 1216 const bool is_bilinear{is_color && !IsPixelFormatInteger(info.format)};
1276 .start = {0, 0}, 1217 const auto operation = is_bilinear ? Tegra::Engines::Fermi2D::Filter::Bilinear
1277 .end = {static_cast<s32>(info.size.width), static_cast<s32>(info.size.height)}, 1218 : Tegra::Engines::Fermi2D::Filter::Point;
1278 }; 1219
1279 const VkExtent2D extent{ 1220 const bool is_2d = info.type == ImageType::e2D;
1280 .width = scaled_width, 1221 const auto& resolution = runtime->resolution;
1281 .height = scaled_height, 1222 const u32 scaled_width = resolution.ScaleUp(info.size.width);
1282 }; 1223 const u32 scaled_height = is_2d ? resolution.ScaleUp(info.size.height) : info.size.height;
1283 if (aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT) { 1224 if (!scale_view) {
1284 if (!normal_framebuffer) { 1225 const auto view_info = ImageViewInfo(ImageViewType::e2D, info.format);
1285 normal_framebuffer = 1226 scale_view = std::make_unique<ImageView>(*runtime, view_info, NULL_IMAGE_ID, *this);
1286 std::make_unique<Framebuffer>(*runtime, view_ptr, nullptr, extent); 1227 }
1287 } 1228
1288 const auto color_view = normal_view->Handle(Shader::TextureType::Color2D); 1229 const u32 src_width = scale_up ? info.size.width : scaled_width;
1289 1230 const u32 src_height = scale_up ? info.size.height : scaled_height;
1290 runtime->blit_image_helper.BlitColor(normal_framebuffer.get(), color_view, dst_region, 1231 const u32 dst_width = scale_up ? scaled_width : info.size.width;
1291 src_region, operation, BLIT_OPERATION); 1232 const u32 dst_height = scale_up ? scaled_height : info.size.height;
1292 } else if (!runtime->device.IsBlitDepthStencilSupported() && 1233 const Region2D src_region{
1293 aspect_mask == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { 1234 .start = {0, 0},
1294 if (!normal_framebuffer) { 1235 .end = {static_cast<s32>(src_width), static_cast<s32>(src_height)},
1295 normal_framebuffer = 1236 };
1296 std::make_unique<Framebuffer>(*runtime, nullptr, view_ptr, extent); 1237 const Region2D dst_region{
1297 } 1238 .start = {0, 0},
1298 runtime->blit_image_helper.BlitDepthStencil( 1239 .end = {static_cast<s32>(dst_width), static_cast<s32>(dst_height)},
1299 normal_framebuffer.get(), normal_view->DepthView(), normal_view->StencilView(), 1240 };
1300 dst_region, src_region, operation, BLIT_OPERATION); 1241 const VkExtent2D extent{
1301 } else { 1242 .width = scaled_width,
1302 // TODO: Use helper blits where applicable 1243 .height = scaled_height,
1303 flags &= ~ImageFlagBits::Rescaled; 1244 };
1304 LOG_ERROR(Render_Vulkan, "Device does not support scaling format {}", format); 1245
1305 return false; 1246 auto* view_ptr = scale_view.get();
1247 if (aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT) {
1248 if (!scale_framebuffer) {
1249 scale_framebuffer = std::make_unique<Framebuffer>(*runtime, view_ptr, nullptr, extent);
1250 }
1251 const auto color_view = scale_view->Handle(Shader::TextureType::Color2D);
1252
1253 runtime->blit_image_helper.BlitColor(scale_framebuffer.get(), color_view, dst_region,
1254 src_region, operation, BLIT_OPERATION);
1255 } else if (!runtime->device.IsBlitDepthStencilSupported() &&
1256 aspect_mask == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
1257 if (!scale_framebuffer) {
1258 scale_framebuffer = std::make_unique<Framebuffer>(*runtime, nullptr, view_ptr, extent);
1306 } 1259 }
1260 runtime->blit_image_helper.BlitDepthStencil(
1261 scale_framebuffer.get(), scale_view->DepthView(), scale_view->StencilView(), dst_region,
1262 src_region, operation, BLIT_OPERATION);
1263 } else {
1264 // TODO: Use helper blits where applicable
1265 flags &= ~ImageFlagBits::Rescaled;
1266 LOG_ERROR(Render_Vulkan, "Device does not support scaling format {}", info.format);
1267 return false;
1307 } 1268 }
1308 ASSERT(info.type != ImageType::Linear);
1309 current_image = *original_image;
1310 return true; 1269 return true;
1311} 1270}
1312 1271
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h
index 8dbddfaf7..9d149d306 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.h
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.h
@@ -134,6 +134,8 @@ public:
134 bool ScaleDown(bool ignore = false); 134 bool ScaleDown(bool ignore = false);
135 135
136private: 136private:
137 bool BlitScaleHelper(bool scale_up);
138
137 VKScheduler* scheduler{}; 139 VKScheduler* scheduler{};
138 TextureCacheRuntime* runtime{}; 140 TextureCacheRuntime* runtime{};
139 141