summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ameerj2021-12-23 20:55:48 -0500
committerGravatar ameerj2021-12-23 20:55:48 -0500
commit481b210c0d035d3de36dc7845802135d90d25a8b (patch)
tree40fb9593457a28b9389140a2e649b9423a414a5b /src
parentMerge pull request #7614 from liushuyu/fix-linux-inhibit (diff)
downloadyuzu-481b210c0d035d3de36dc7845802135d90d25a8b.tar.gz
yuzu-481b210c0d035d3de36dc7845802135d90d25a8b.tar.xz
yuzu-481b210c0d035d3de36dc7845802135d90d25a8b.zip
vk_texture_cache: Fix invalidated pointer access
The vulkan ImageView held a reference to its source image for rescale status checking. This pointer is sometimes invalidated when the texture cache slot_images container is resized. To avoid an invalid pointer dereference, the ImageView now holds a reference to the container itself.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.h4
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.cpp15
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.h5
-rw-r--r--src/video_core/texture_cache/texture_cache.h3
5 files changed, 21 insertions, 8 deletions
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp
index 14e6522f2..3c1f79a27 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp
@@ -1047,7 +1047,7 @@ bool Image::ScaleDown(bool ignore) {
1047} 1047}
1048 1048
1049ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info, 1049ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info,
1050 ImageId image_id_, Image& image) 1050 ImageId image_id_, Image& image, const SlotVector<Image>&)
1051 : VideoCommon::ImageViewBase{info, image.info, image_id_}, views{runtime.null_image_views} { 1051 : VideoCommon::ImageViewBase{info, image.info, image_id_}, views{runtime.null_image_views} {
1052 const Device& device = runtime.device; 1052 const Device& device = runtime.device;
1053 if (True(image.flags & ImageFlagBits::Converted)) { 1053 if (True(image.flags & ImageFlagBits::Converted)) {
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h
index dbf1df79c..7f425631f 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.h
+++ b/src/video_core/renderer_opengl/gl_texture_cache.h
@@ -36,6 +36,7 @@ using VideoCommon::ImageViewType;
36using VideoCommon::NUM_RT; 36using VideoCommon::NUM_RT;
37using VideoCommon::Region2D; 37using VideoCommon::Region2D;
38using VideoCommon::RenderTargets; 38using VideoCommon::RenderTargets;
39using VideoCommon::SlotVector;
39 40
40struct ImageBufferMap { 41struct ImageBufferMap {
41 ~ImageBufferMap(); 42 ~ImageBufferMap();
@@ -234,7 +235,8 @@ class ImageView : public VideoCommon::ImageViewBase {
234 friend Image; 235 friend Image;
235 236
236public: 237public:
237 explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageViewInfo&, ImageId, Image&); 238 explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageViewInfo&, ImageId, Image&,
239 const SlotVector<Image>&);
238 explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo&, 240 explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo&,
239 const VideoCommon::ImageViewInfo&, GPUVAddr); 241 const VideoCommon::ImageViewInfo&, GPUVAddr);
240 explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo& info, 242 explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo& info,
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
index 1941170cb..c3050887c 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
@@ -1473,8 +1473,7 @@ bool Image::BlitScaleHelper(bool scale_up) {
1473ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info, 1473ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info,
1474 ImageId image_id_, Image& image) 1474 ImageId image_id_, Image& image)
1475 : VideoCommon::ImageViewBase{info, image.info, image_id_}, device{&runtime.device}, 1475 : VideoCommon::ImageViewBase{info, image.info, image_id_}, device{&runtime.device},
1476 src_image{&image}, image_handle{image.Handle()}, 1476 image_handle{image.Handle()}, samples(ConvertSampleCount(image.info.num_samples)) {
1477 samples(ConvertSampleCount(image.info.num_samples)) {
1478 using Shader::TextureType; 1477 using Shader::TextureType;
1479 1478
1480 const VkImageAspectFlags aspect_mask = ImageViewAspectMask(info); 1479 const VkImageAspectFlags aspect_mask = ImageViewAspectMask(info);
@@ -1557,6 +1556,12 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI
1557 } 1556 }
1558} 1557}
1559 1558
1559ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info,
1560 ImageId image_id_, Image& image, const SlotVector<Image>& slot_imgs)
1561 : ImageView{runtime, info, image_id_, image} {
1562 slot_images = &slot_imgs;
1563}
1564
1560ImageView::ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo& info, 1565ImageView::ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo& info,
1561 const VideoCommon::ImageViewInfo& view_info, GPUVAddr gpu_addr_) 1566 const VideoCommon::ImageViewInfo& view_info, GPUVAddr gpu_addr_)
1562 : VideoCommon::ImageViewBase{info, view_info}, gpu_addr{gpu_addr_}, 1567 : VideoCommon::ImageViewBase{info, view_info}, gpu_addr{gpu_addr_},
@@ -1613,10 +1618,12 @@ VkImageView ImageView::StorageView(Shader::TextureType texture_type,
1613} 1618}
1614 1619
1615bool ImageView::IsRescaled() const noexcept { 1620bool ImageView::IsRescaled() const noexcept {
1616 if (!src_image) { 1621 if (!slot_images) {
1617 return false; 1622 return false;
1618 } 1623 }
1619 return src_image->IsRescaled(); 1624 const auto& slots = *slot_images;
1625 const auto& src_image = slots[image_id];
1626 return src_image.IsRescaled();
1620} 1627}
1621 1628
1622vk::ImageView ImageView::MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask) { 1629vk::ImageView ImageView::MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask) {
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h
index c592f2666..2f12be78b 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.h
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.h
@@ -23,6 +23,7 @@ using VideoCommon::ImageId;
23using VideoCommon::NUM_RT; 23using VideoCommon::NUM_RT;
24using VideoCommon::Region2D; 24using VideoCommon::Region2D;
25using VideoCommon::RenderTargets; 25using VideoCommon::RenderTargets;
26using VideoCommon::SlotVector;
26using VideoCore::Surface::PixelFormat; 27using VideoCore::Surface::PixelFormat;
27 28
28class ASTCDecoderPass; 29class ASTCDecoderPass;
@@ -170,6 +171,8 @@ private:
170class ImageView : public VideoCommon::ImageViewBase { 171class ImageView : public VideoCommon::ImageViewBase {
171public: 172public:
172 explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageViewInfo&, ImageId, Image&); 173 explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageViewInfo&, ImageId, Image&);
174 explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageViewInfo&, ImageId, Image&,
175 const SlotVector<Image>&);
173 explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo&, 176 explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo&,
174 const VideoCommon::ImageViewInfo&, GPUVAddr); 177 const VideoCommon::ImageViewInfo&, GPUVAddr);
175 explicit ImageView(TextureCacheRuntime&, const VideoCommon::NullImageViewParams&); 178 explicit ImageView(TextureCacheRuntime&, const VideoCommon::NullImageViewParams&);
@@ -226,7 +229,7 @@ private:
226 [[nodiscard]] vk::ImageView MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask); 229 [[nodiscard]] vk::ImageView MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask);
227 230
228 const Device* device = nullptr; 231 const Device* device = nullptr;
229 const Image* src_image{}; 232 const SlotVector<Image>* slot_images = nullptr;
230 233
231 std::array<vk::ImageView, Shader::NUM_TEXTURE_TYPES> image_views; 234 std::array<vk::ImageView, Shader::NUM_TEXTURE_TYPES> image_views;
232 std::unique_ptr<StorageViews> storage_views; 235 std::unique_ptr<StorageViews> storage_views;
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 2e19fced2..b494152b8 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -1397,7 +1397,8 @@ ImageViewId TextureCache<P>::FindOrEmplaceImageView(ImageId image_id, const Imag
1397 if (const ImageViewId image_view_id = image.FindView(info); image_view_id) { 1397 if (const ImageViewId image_view_id = image.FindView(info); image_view_id) {
1398 return image_view_id; 1398 return image_view_id;
1399 } 1399 }
1400 const ImageViewId image_view_id = slot_image_views.insert(runtime, info, image_id, image); 1400 const ImageViewId image_view_id =
1401 slot_image_views.insert(runtime, info, image_id, image, slot_images);
1401 image.InsertView(info, image_view_id); 1402 image.InsertView(info, image_view_id);
1402 return image_view_id; 1403 return image_view_id;
1403} 1404}