summaryrefslogtreecommitdiff
path: root/src/video_core/renderer_vulkan
diff options
context:
space:
mode:
authorGravatar ameerj2021-05-07 22:14:21 -0400
committerGravatar ameerj2021-05-07 22:14:21 -0400
commit3671fd0a97351c1e5b2ea691d85ab45d5f83288e (patch)
treea4723be2513e3d5dbd7de423c865c2ff78c06843 /src/video_core/renderer_vulkan
parentMerge pull request #6279 from ogniK5377/nvhost-prof (diff)
downloadyuzu-3671fd0a97351c1e5b2ea691d85ab45d5f83288e.tar.gz
yuzu-3671fd0a97351c1e5b2ea691d85ab45d5f83288e.tar.xz
yuzu-3671fd0a97351c1e5b2ea691d85ab45d5f83288e.zip
texture_cache: Handle out of bound texture blits
Some games interleave a texture blit using regions which are out-of-bounds. This addresses the interleaving to avoid oob reads from the src texture.
Diffstat (limited to 'src/video_core/renderer_vulkan')
-rw-r--r--src/video_core/renderer_vulkan/blit_image.cpp26
-rw-r--r--src/video_core/renderer_vulkan/blit_image.h10
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.cpp38
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.h5
4 files changed, 36 insertions, 43 deletions
diff --git a/src/video_core/renderer_vulkan/blit_image.cpp b/src/video_core/renderer_vulkan/blit_image.cpp
index 1f6a169ae..b7f5b8bc2 100644
--- a/src/video_core/renderer_vulkan/blit_image.cpp
+++ b/src/video_core/renderer_vulkan/blit_image.cpp
@@ -289,16 +289,15 @@ void UpdateTwoTexturesDescriptorSet(const Device& device, VkDescriptorSet descri
289 device.GetLogical().UpdateDescriptorSets(write_descriptor_sets, nullptr); 289 device.GetLogical().UpdateDescriptorSets(write_descriptor_sets, nullptr);
290} 290}
291 291
292void BindBlitState(vk::CommandBuffer cmdbuf, VkPipelineLayout layout, 292void BindBlitState(vk::CommandBuffer cmdbuf, VkPipelineLayout layout, const Region2D& dst_region,
293 const std::array<Offset2D, 2>& dst_region, 293 const Region2D& src_region) {
294 const std::array<Offset2D, 2>& src_region) {
295 const VkOffset2D offset{ 294 const VkOffset2D offset{
296 .x = std::min(dst_region[0].x, dst_region[1].x), 295 .x = std::min(dst_region.start.x, dst_region.end.x),
297 .y = std::min(dst_region[0].y, dst_region[1].y), 296 .y = std::min(dst_region.start.y, dst_region.end.y),
298 }; 297 };
299 const VkExtent2D extent{ 298 const VkExtent2D extent{
300 .width = static_cast<u32>(std::abs(dst_region[1].x - dst_region[0].x)), 299 .width = static_cast<u32>(std::abs(dst_region.end.x - dst_region.start.x)),
301 .height = static_cast<u32>(std::abs(dst_region[1].y - dst_region[0].y)), 300 .height = static_cast<u32>(std::abs(dst_region.end.y - dst_region.start.y)),
302 }; 301 };
303 const VkViewport viewport{ 302 const VkViewport viewport{
304 .x = static_cast<float>(offset.x), 303 .x = static_cast<float>(offset.x),
@@ -313,11 +312,12 @@ void BindBlitState(vk::CommandBuffer cmdbuf, VkPipelineLayout layout,
313 .offset = offset, 312 .offset = offset,
314 .extent = extent, 313 .extent = extent,
315 }; 314 };
316 const float scale_x = static_cast<float>(src_region[1].x - src_region[0].x); 315 const float scale_x = static_cast<float>(src_region.end.x - src_region.start.x);
317 const float scale_y = static_cast<float>(src_region[1].y - src_region[0].y); 316 const float scale_y = static_cast<float>(src_region.end.y - src_region.start.y);
318 const PushConstants push_constants{ 317 const PushConstants push_constants{
319 .tex_scale = {scale_x, scale_y}, 318 .tex_scale = {scale_x, scale_y},
320 .tex_offset = {static_cast<float>(src_region[0].x), static_cast<float>(src_region[0].y)}, 319 .tex_offset = {static_cast<float>(src_region.start.x),
320 static_cast<float>(src_region.start.y)},
321 }; 321 };
322 cmdbuf.SetViewport(0, viewport); 322 cmdbuf.SetViewport(0, viewport);
323 cmdbuf.SetScissor(0, scissor); 323 cmdbuf.SetScissor(0, scissor);
@@ -353,8 +353,7 @@ BlitImageHelper::BlitImageHelper(const Device& device_, VKScheduler& scheduler_,
353BlitImageHelper::~BlitImageHelper() = default; 353BlitImageHelper::~BlitImageHelper() = default;
354 354
355void BlitImageHelper::BlitColor(const Framebuffer* dst_framebuffer, const ImageView& src_image_view, 355void BlitImageHelper::BlitColor(const Framebuffer* dst_framebuffer, const ImageView& src_image_view,
356 const std::array<Offset2D, 2>& dst_region, 356 const Region2D& dst_region, const Region2D& src_region,
357 const std::array<Offset2D, 2>& src_region,
358 Tegra::Engines::Fermi2D::Filter filter, 357 Tegra::Engines::Fermi2D::Filter filter,
359 Tegra::Engines::Fermi2D::Operation operation) { 358 Tegra::Engines::Fermi2D::Operation operation) {
360 const bool is_linear = filter == Tegra::Engines::Fermi2D::Filter::Bilinear; 359 const bool is_linear = filter == Tegra::Engines::Fermi2D::Filter::Bilinear;
@@ -383,8 +382,7 @@ void BlitImageHelper::BlitColor(const Framebuffer* dst_framebuffer, const ImageV
383 382
384void BlitImageHelper::BlitDepthStencil(const Framebuffer* dst_framebuffer, 383void BlitImageHelper::BlitDepthStencil(const Framebuffer* dst_framebuffer,
385 VkImageView src_depth_view, VkImageView src_stencil_view, 384 VkImageView src_depth_view, VkImageView src_stencil_view,
386 const std::array<Offset2D, 2>& dst_region, 385 const Region2D& dst_region, const Region2D& src_region,
387 const std::array<Offset2D, 2>& src_region,
388 Tegra::Engines::Fermi2D::Filter filter, 386 Tegra::Engines::Fermi2D::Filter filter,
389 Tegra::Engines::Fermi2D::Operation operation) { 387 Tegra::Engines::Fermi2D::Operation operation) {
390 ASSERT(filter == Tegra::Engines::Fermi2D::Filter::Point); 388 ASSERT(filter == Tegra::Engines::Fermi2D::Filter::Point);
diff --git a/src/video_core/renderer_vulkan/blit_image.h b/src/video_core/renderer_vulkan/blit_image.h
index 43fd3d737..0d81a06ed 100644
--- a/src/video_core/renderer_vulkan/blit_image.h
+++ b/src/video_core/renderer_vulkan/blit_image.h
@@ -13,7 +13,7 @@
13 13
14namespace Vulkan { 14namespace Vulkan {
15 15
16using VideoCommon::Offset2D; 16using VideoCommon::Region2D;
17 17
18class Device; 18class Device;
19class Framebuffer; 19class Framebuffer;
@@ -35,15 +35,13 @@ public:
35 ~BlitImageHelper(); 35 ~BlitImageHelper();
36 36
37 void BlitColor(const Framebuffer* dst_framebuffer, const ImageView& src_image_view, 37 void BlitColor(const Framebuffer* dst_framebuffer, const ImageView& src_image_view,
38 const std::array<Offset2D, 2>& dst_region, 38 const Region2D& dst_region, const Region2D& src_region,
39 const std::array<Offset2D, 2>& src_region,
40 Tegra::Engines::Fermi2D::Filter filter, 39 Tegra::Engines::Fermi2D::Filter filter,
41 Tegra::Engines::Fermi2D::Operation operation); 40 Tegra::Engines::Fermi2D::Operation operation);
42 41
43 void BlitDepthStencil(const Framebuffer* dst_framebuffer, VkImageView src_depth_view, 42 void BlitDepthStencil(const Framebuffer* dst_framebuffer, VkImageView src_depth_view,
44 VkImageView src_stencil_view, const std::array<Offset2D, 2>& dst_region, 43 VkImageView src_stencil_view, const Region2D& dst_region,
45 const std::array<Offset2D, 2>& src_region, 44 const Region2D& src_region, Tegra::Engines::Fermi2D::Filter filter,
46 Tegra::Engines::Fermi2D::Filter filter,
47 Tegra::Engines::Fermi2D::Operation operation); 45 Tegra::Engines::Fermi2D::Operation operation);
48 46
49 void ConvertD32ToR32(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); 47 void ConvertD32ToR32(const Framebuffer* dst_framebuffer, const ImageView& src_image_view);
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
index 017348e05..bdd0ce8bc 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
@@ -490,8 +490,7 @@ void CopyBufferToImage(vk::CommandBuffer cmdbuf, VkBuffer src_buffer, VkImage im
490 write_barrier); 490 write_barrier);
491} 491}
492 492
493[[nodiscard]] VkImageBlit MakeImageBlit(const std::array<Offset2D, 2>& dst_region, 493[[nodiscard]] VkImageBlit MakeImageBlit(const Region2D& dst_region, const Region2D& src_region,
494 const std::array<Offset2D, 2>& src_region,
495 const VkImageSubresourceLayers& dst_layers, 494 const VkImageSubresourceLayers& dst_layers,
496 const VkImageSubresourceLayers& src_layers) { 495 const VkImageSubresourceLayers& src_layers) {
497 return VkImageBlit{ 496 return VkImageBlit{
@@ -499,13 +498,13 @@ void CopyBufferToImage(vk::CommandBuffer cmdbuf, VkBuffer src_buffer, VkImage im
499 .srcOffsets = 498 .srcOffsets =
500 { 499 {
501 { 500 {
502 .x = src_region[0].x, 501 .x = src_region.start.x,
503 .y = src_region[0].y, 502 .y = src_region.start.y,
504 .z = 0, 503 .z = 0,
505 }, 504 },
506 { 505 {
507 .x = src_region[1].x, 506 .x = src_region.end.x,
508 .y = src_region[1].y, 507 .y = src_region.end.y,
509 .z = 1, 508 .z = 1,
510 }, 509 },
511 }, 510 },
@@ -513,42 +512,42 @@ void CopyBufferToImage(vk::CommandBuffer cmdbuf, VkBuffer src_buffer, VkImage im
513 .dstOffsets = 512 .dstOffsets =
514 { 513 {
515 { 514 {
516 .x = dst_region[0].x, 515 .x = dst_region.start.x,
517 .y = dst_region[0].y, 516 .y = dst_region.start.y,
518 .z = 0, 517 .z = 0,
519 }, 518 },
520 { 519 {
521 .x = dst_region[1].x, 520 .x = dst_region.end.x,
522 .y = dst_region[1].y, 521 .y = dst_region.end.y,
523 .z = 1, 522 .z = 1,
524 }, 523 },
525 }, 524 },
526 }; 525 };
527} 526}
528 527
529[[nodiscard]] VkImageResolve MakeImageResolve(const std::array<Offset2D, 2>& dst_region, 528[[nodiscard]] VkImageResolve MakeImageResolve(const Region2D& dst_region,
530 const std::array<Offset2D, 2>& src_region, 529 const Region2D& src_region,
531 const VkImageSubresourceLayers& dst_layers, 530 const VkImageSubresourceLayers& dst_layers,
532 const VkImageSubresourceLayers& src_layers) { 531 const VkImageSubresourceLayers& src_layers) {
533 return VkImageResolve{ 532 return VkImageResolve{
534 .srcSubresource = src_layers, 533 .srcSubresource = src_layers,
535 .srcOffset = 534 .srcOffset =
536 { 535 {
537 .x = src_region[0].x, 536 .x = src_region.start.x,
538 .y = src_region[0].y, 537 .y = src_region.start.y,
539 .z = 0, 538 .z = 0,
540 }, 539 },
541 .dstSubresource = dst_layers, 540 .dstSubresource = dst_layers,
542 .dstOffset = 541 .dstOffset =
543 { 542 {
544 .x = dst_region[0].x, 543 .x = dst_region.start.x,
545 .y = dst_region[0].y, 544 .y = dst_region.start.y,
546 .z = 0, 545 .z = 0,
547 }, 546 },
548 .extent = 547 .extent =
549 { 548 {
550 .width = static_cast<u32>(dst_region[1].x - dst_region[0].x), 549 .width = static_cast<u32>(dst_region.end.x - dst_region.start.x),
551 .height = static_cast<u32>(dst_region[1].y - dst_region[0].y), 550 .height = static_cast<u32>(dst_region.end.y - dst_region.start.y),
552 .depth = 1, 551 .depth = 1,
553 }, 552 },
554 }; 553 };
@@ -602,8 +601,7 @@ StagingBufferRef TextureCacheRuntime::DownloadStagingBuffer(size_t size) {
602} 601}
603 602
604void TextureCacheRuntime::BlitImage(Framebuffer* dst_framebuffer, ImageView& dst, ImageView& src, 603void TextureCacheRuntime::BlitImage(Framebuffer* dst_framebuffer, ImageView& dst, ImageView& src,
605 const std::array<Offset2D, 2>& dst_region, 604 const Region2D& dst_region, const Region2D& src_region,
606 const std::array<Offset2D, 2>& src_region,
607 Tegra::Engines::Fermi2D::Filter filter, 605 Tegra::Engines::Fermi2D::Filter filter,
608 Tegra::Engines::Fermi2D::Operation operation) { 606 Tegra::Engines::Fermi2D::Operation operation) {
609 const VkImageAspectFlags aspect_mask = ImageAspectMask(src.format); 607 const VkImageAspectFlags aspect_mask = ImageAspectMask(src.format);
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h
index 628785d5e..4a57d378b 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.h
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.h
@@ -16,7 +16,7 @@ namespace Vulkan {
16 16
17using VideoCommon::ImageId; 17using VideoCommon::ImageId;
18using VideoCommon::NUM_RT; 18using VideoCommon::NUM_RT;
19using VideoCommon::Offset2D; 19using VideoCommon::Region2D;
20using VideoCommon::RenderTargets; 20using VideoCommon::RenderTargets;
21using VideoCore::Surface::PixelFormat; 21using VideoCore::Surface::PixelFormat;
22 22
@@ -71,8 +71,7 @@ struct TextureCacheRuntime {
71 [[nodiscard]] StagingBufferRef DownloadStagingBuffer(size_t size); 71 [[nodiscard]] StagingBufferRef DownloadStagingBuffer(size_t size);
72 72
73 void BlitImage(Framebuffer* dst_framebuffer, ImageView& dst, ImageView& src, 73 void BlitImage(Framebuffer* dst_framebuffer, ImageView& dst, ImageView& src,
74 const std::array<Offset2D, 2>& dst_region, 74 const Region2D& dst_region, const Region2D& src_region,
75 const std::array<Offset2D, 2>& src_region,
76 Tegra::Engines::Fermi2D::Filter filter, 75 Tegra::Engines::Fermi2D::Filter filter,
77 Tegra::Engines::Fermi2D::Operation operation); 76 Tegra::Engines::Fermi2D::Operation operation);
78 77