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.
This commit is contained in:
parent
516325eba8
commit
481b210c0d
@ -1047,7 +1047,7 @@ bool Image::ScaleDown(bool ignore) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info,
|
ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info,
|
||||||
ImageId image_id_, Image& image)
|
ImageId image_id_, Image& image, const SlotVector<Image>&)
|
||||||
: VideoCommon::ImageViewBase{info, image.info, image_id_}, views{runtime.null_image_views} {
|
: VideoCommon::ImageViewBase{info, image.info, image_id_}, views{runtime.null_image_views} {
|
||||||
const Device& device = runtime.device;
|
const Device& device = runtime.device;
|
||||||
if (True(image.flags & ImageFlagBits::Converted)) {
|
if (True(image.flags & ImageFlagBits::Converted)) {
|
||||||
|
@ -36,6 +36,7 @@ using VideoCommon::ImageViewType;
|
|||||||
using VideoCommon::NUM_RT;
|
using VideoCommon::NUM_RT;
|
||||||
using VideoCommon::Region2D;
|
using VideoCommon::Region2D;
|
||||||
using VideoCommon::RenderTargets;
|
using VideoCommon::RenderTargets;
|
||||||
|
using VideoCommon::SlotVector;
|
||||||
|
|
||||||
struct ImageBufferMap {
|
struct ImageBufferMap {
|
||||||
~ImageBufferMap();
|
~ImageBufferMap();
|
||||||
@ -234,7 +235,8 @@ class ImageView : public VideoCommon::ImageViewBase {
|
|||||||
friend Image;
|
friend Image;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageViewInfo&, ImageId, Image&);
|
explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageViewInfo&, ImageId, Image&,
|
||||||
|
const SlotVector<Image>&);
|
||||||
explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo&,
|
explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo&,
|
||||||
const VideoCommon::ImageViewInfo&, GPUVAddr);
|
const VideoCommon::ImageViewInfo&, GPUVAddr);
|
||||||
explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo& info,
|
explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo& info,
|
||||||
|
@ -1473,8 +1473,7 @@ bool Image::BlitScaleHelper(bool scale_up) {
|
|||||||
ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info,
|
ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info,
|
||||||
ImageId image_id_, Image& image)
|
ImageId image_id_, Image& image)
|
||||||
: VideoCommon::ImageViewBase{info, image.info, image_id_}, device{&runtime.device},
|
: VideoCommon::ImageViewBase{info, image.info, image_id_}, device{&runtime.device},
|
||||||
src_image{&image}, image_handle{image.Handle()},
|
image_handle{image.Handle()}, samples(ConvertSampleCount(image.info.num_samples)) {
|
||||||
samples(ConvertSampleCount(image.info.num_samples)) {
|
|
||||||
using Shader::TextureType;
|
using Shader::TextureType;
|
||||||
|
|
||||||
const VkImageAspectFlags aspect_mask = ImageViewAspectMask(info);
|
const VkImageAspectFlags aspect_mask = ImageViewAspectMask(info);
|
||||||
@ -1557,6 +1556,12 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info,
|
||||||
|
ImageId image_id_, Image& image, const SlotVector<Image>& slot_imgs)
|
||||||
|
: ImageView{runtime, info, image_id_, image} {
|
||||||
|
slot_images = &slot_imgs;
|
||||||
|
}
|
||||||
|
|
||||||
ImageView::ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo& info,
|
ImageView::ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo& info,
|
||||||
const VideoCommon::ImageViewInfo& view_info, GPUVAddr gpu_addr_)
|
const VideoCommon::ImageViewInfo& view_info, GPUVAddr gpu_addr_)
|
||||||
: VideoCommon::ImageViewBase{info, view_info}, gpu_addr{gpu_addr_},
|
: VideoCommon::ImageViewBase{info, view_info}, gpu_addr{gpu_addr_},
|
||||||
@ -1613,10 +1618,12 @@ VkImageView ImageView::StorageView(Shader::TextureType texture_type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ImageView::IsRescaled() const noexcept {
|
bool ImageView::IsRescaled() const noexcept {
|
||||||
if (!src_image) {
|
if (!slot_images) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return src_image->IsRescaled();
|
const auto& slots = *slot_images;
|
||||||
|
const auto& src_image = slots[image_id];
|
||||||
|
return src_image.IsRescaled();
|
||||||
}
|
}
|
||||||
|
|
||||||
vk::ImageView ImageView::MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask) {
|
vk::ImageView ImageView::MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask) {
|
||||||
|
@ -23,6 +23,7 @@ using VideoCommon::ImageId;
|
|||||||
using VideoCommon::NUM_RT;
|
using VideoCommon::NUM_RT;
|
||||||
using VideoCommon::Region2D;
|
using VideoCommon::Region2D;
|
||||||
using VideoCommon::RenderTargets;
|
using VideoCommon::RenderTargets;
|
||||||
|
using VideoCommon::SlotVector;
|
||||||
using VideoCore::Surface::PixelFormat;
|
using VideoCore::Surface::PixelFormat;
|
||||||
|
|
||||||
class ASTCDecoderPass;
|
class ASTCDecoderPass;
|
||||||
@ -170,6 +171,8 @@ private:
|
|||||||
class ImageView : public VideoCommon::ImageViewBase {
|
class ImageView : public VideoCommon::ImageViewBase {
|
||||||
public:
|
public:
|
||||||
explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageViewInfo&, ImageId, Image&);
|
explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageViewInfo&, ImageId, Image&);
|
||||||
|
explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageViewInfo&, ImageId, Image&,
|
||||||
|
const SlotVector<Image>&);
|
||||||
explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo&,
|
explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo&,
|
||||||
const VideoCommon::ImageViewInfo&, GPUVAddr);
|
const VideoCommon::ImageViewInfo&, GPUVAddr);
|
||||||
explicit ImageView(TextureCacheRuntime&, const VideoCommon::NullImageViewParams&);
|
explicit ImageView(TextureCacheRuntime&, const VideoCommon::NullImageViewParams&);
|
||||||
@ -226,7 +229,7 @@ private:
|
|||||||
[[nodiscard]] vk::ImageView MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask);
|
[[nodiscard]] vk::ImageView MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask);
|
||||||
|
|
||||||
const Device* device = nullptr;
|
const Device* device = nullptr;
|
||||||
const Image* src_image{};
|
const SlotVector<Image>* slot_images = nullptr;
|
||||||
|
|
||||||
std::array<vk::ImageView, Shader::NUM_TEXTURE_TYPES> image_views;
|
std::array<vk::ImageView, Shader::NUM_TEXTURE_TYPES> image_views;
|
||||||
std::unique_ptr<StorageViews> storage_views;
|
std::unique_ptr<StorageViews> storage_views;
|
||||||
|
@ -1397,7 +1397,8 @@ ImageViewId TextureCache<P>::FindOrEmplaceImageView(ImageId image_id, const Imag
|
|||||||
if (const ImageViewId image_view_id = image.FindView(info); image_view_id) {
|
if (const ImageViewId image_view_id = image.FindView(info); image_view_id) {
|
||||||
return image_view_id;
|
return image_view_id;
|
||||||
}
|
}
|
||||||
const ImageViewId image_view_id = slot_image_views.insert(runtime, info, image_id, image);
|
const ImageViewId image_view_id =
|
||||||
|
slot_image_views.insert(runtime, info, image_id, image, slot_images);
|
||||||
image.InsertView(info, image_view_id);
|
image.InsertView(info, image_view_id);
|
||||||
return image_view_id;
|
return image_view_id;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user