Texture Cache: More rescaling fixes.

This commit is contained in:
Fernando Sahmkow 2021-07-20 07:40:05 +02:00
parent 10e5065a5c
commit 84f2aea896
4 changed files with 102 additions and 90 deletions

View file

@ -918,7 +918,7 @@ bool Image::ScaleUp() {
return false; return false;
} }
flags |= ImageFlagBits::Rescaled; flags |= ImageFlagBits::Rescaled;
Scale(); //Scale();
return true; return true;
} }
@ -927,7 +927,7 @@ bool Image::ScaleDown() {
return false; return false;
} }
flags &= ~ImageFlagBits::Rescaled; flags &= ~ImageFlagBits::Rescaled;
Scale(); //Scale();
return true; return true;
} }

View file

@ -1078,6 +1078,10 @@ bool Image::ScaleUp(bool save_as_backup) {
MemoryCommit new_commit( MemoryCommit new_commit(
runtime->memory_allocator.Commit(rescaled_image, MemoryUsage::DeviceLocal)); runtime->memory_allocator.Commit(rescaled_image, MemoryUsage::DeviceLocal));
if (aspect_mask == 0) {
aspect_mask = ImageAspectMask(info.format);
}
const auto scale_up = [&](u32 value) { const auto scale_up = [&](u32 value) {
return (value * resolution.up_scale) >> resolution.down_shift; return (value * resolution.up_scale) >> resolution.down_shift;
}; };
@ -1170,6 +1174,10 @@ bool Image::ScaleDown(bool save_as_backup) {
return (value * resolution.up_scale) >> resolution.down_shift; return (value * resolution.up_scale) >> resolution.down_shift;
}; };
if (aspect_mask == 0) {
aspect_mask = ImageAspectMask(info.format);
}
const bool is_2d = info.type == ImageType::e2D; const bool is_2d = info.type == ImageType::e2D;
boost::container::small_vector<VkImageBlit, 4> vkRegions(info.resources.levels); boost::container::small_vector<VkImageBlit, 4> vkRegions(info.resources.levels);
for (s32 level = 0; level < info.resources.levels; level++) { for (s32 level = 0; level < info.resources.levels; level++) {

View file

@ -204,9 +204,13 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) {
PrepareImageView(depth_buffer_id, true, is_clear && IsFullClear(depth_buffer_id)); PrepareImageView(depth_buffer_id, true, is_clear && IsFullClear(depth_buffer_id));
return; return;
} }
do {
flags[Dirty::RenderTargets] = false; flags[Dirty::RenderTargets] = false;
// Render target control is used on all render targets, so force look ups when this one is up has_deleted_images = false;
// Render target control is used on all render targets, so force look ups when this one is
// up
const bool force = flags[Dirty::RenderTargetControl]; const bool force = flags[Dirty::RenderTargetControl];
flags[Dirty::RenderTargetControl] = false; flags[Dirty::RenderTargetControl] = false;
@ -242,37 +246,26 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) {
const auto scale_up = [this](ImageId image_id) { const auto scale_up = [this](ImageId image_id) {
if (image_id != CORRUPT_ID) { if (image_id != CORRUPT_ID) {
Image& image = slot_images[image_id]; Image& image = slot_images[image_id];
return ScaleUp(image); ScaleUp(image);
} }
return false;
}; };
for (size_t index = 0; index < NUM_RT; ++index) { for (size_t index = 0; index < NUM_RT; ++index) {
if (scale_up(tmp_color_images[index])) { scale_up(tmp_color_images[index]);
BindRenderTarget(&render_targets.color_buffer_ids[index],
FindColorBuffer(index, is_clear));
}
}
if (scale_up(tmp_depth_image)) {
BindRenderTarget(&render_targets.depth_buffer_id, FindDepthBuffer(is_clear));
} }
scale_up(tmp_depth_image);
} else { } else {
const auto scale_down = [this](ImageId image_id) { const auto scale_down = [this](ImageId image_id) {
if (image_id != CORRUPT_ID) { if (image_id != CORRUPT_ID) {
Image& image = slot_images[image_id]; Image& image = slot_images[image_id];
return ScaleDown(image); ScaleDown(image);
} }
return false;
}; };
for (size_t index = 0; index < NUM_RT; ++index) { for (size_t index = 0; index < NUM_RT; ++index) {
if (scale_down(tmp_color_images[index])) { scale_down(tmp_color_images[index]);
BindRenderTarget(&render_targets.color_buffer_ids[index],
FindColorBuffer(index, is_clear));
}
}
if (scale_down(tmp_depth_image)) {
BindRenderTarget(&render_targets.depth_buffer_id, FindDepthBuffer(is_clear));
} }
scale_down(tmp_depth_image);
} }
} while (has_deleted_images);
// Rescale End // Rescale End
for (size_t index = 0; index < NUM_RT; ++index) { for (size_t index = 0; index < NUM_RT; ++index) {
@ -708,9 +701,8 @@ bool TextureCache<P>::ImageCanRescale(Image& image) {
} }
template <class P> template <class P>
void TextureCache<P>::InvalidateScale(Image& image, bool invalidate_rt) { void TextureCache<P>::InvalidateScale(Image& image) {
const std::span<const ImageViewId> image_view_ids = image.image_view_ids; const std::span<const ImageViewId> image_view_ids = image.image_view_ids;
if (invalidate_rt) {
auto& dirty = maxwell3d.dirty.flags; auto& dirty = maxwell3d.dirty.flags;
dirty[Dirty::RenderTargets] = true; dirty[Dirty::RenderTargets] = true;
dirty[Dirty::ZetaBuffer] = true; dirty[Dirty::ZetaBuffer] = true;
@ -723,28 +715,40 @@ void TextureCache<P>::InvalidateScale(Image& image, bool invalidate_rt) {
render_targets.depth_buffer_id = ImageViewId{}; render_targets.depth_buffer_id = ImageViewId{};
} }
} }
}
RemoveImageViewReferences(image_view_ids); RemoveImageViewReferences(image_view_ids);
RemoveFramebuffers(image_view_ids); RemoveFramebuffers(image_view_ids);
for (const ImageViewId image_view_id : image_view_ids) {
sentenced_image_view.Push(std::move(slot_image_views[image_view_id]));
slot_image_views.erase(image_view_id);
}
image.image_view_ids.clear();
image.image_view_infos.clear();
if constexpr (ENABLE_VALIDATION) {
std::ranges::fill(graphics_image_view_ids, CORRUPT_ID);
std::ranges::fill(compute_image_view_ids, CORRUPT_ID);
}
graphics_image_table.Invalidate();
compute_image_table.Invalidate();
has_deleted_images = true;
} }
template <class P> template <class P>
bool TextureCache<P>::ScaleUp(Image& image, bool invalidate_rt) { bool TextureCache<P>::ScaleUp(Image& image) {
const bool rescaled = image.ScaleUp(); const bool rescaled = image.ScaleUp();
if (!rescaled) { if (!rescaled) {
return false; return false;
} }
InvalidateScale(image, invalidate_rt); InvalidateScale(image);
return true; return true;
} }
template <class P> template <class P>
bool TextureCache<P>::ScaleDown(Image& image, bool invalidate_rt) { bool TextureCache<P>::ScaleDown(Image& image) {
const bool rescaled = image.ScaleDown(); const bool rescaled = image.ScaleDown();
if (!rescaled) { if (!rescaled) {
return false; return false;
} }
InvalidateScale(image, invalidate_rt); InvalidateScale(image);
return true; return true;
} }
@ -861,12 +865,12 @@ ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
if (can_rescale) { if (can_rescale) {
for (const ImageId sibling_id : all_siblings) { for (const ImageId sibling_id : all_siblings) {
Image& sibling = slot_images[sibling_id]; Image& sibling = slot_images[sibling_id];
ScaleUp(sibling, true); ScaleUp(sibling);
} }
} else { } else {
for (const ImageId sibling_id : all_siblings) { for (const ImageId sibling_id : all_siblings) {
Image& sibling = slot_images[sibling_id]; Image& sibling = slot_images[sibling_id];
ScaleDown(sibling, true); ScaleDown(sibling);
} }
} }
@ -893,9 +897,9 @@ ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
RefreshContents(new_image, new_image_id); RefreshContents(new_image, new_image_id);
if (can_rescale) { if (can_rescale) {
new_image.ScaleUp(); ScaleUp(new_image);
} else { } else {
new_image.ScaleDown(); ScaleDown(new_image);
} }
for (const ImageId overlap_id : overlap_ids) { for (const ImageId overlap_id : overlap_ids) {

View file

@ -327,9 +327,9 @@ private:
[[nodiscard]] bool IsFullClear(ImageViewId id); [[nodiscard]] bool IsFullClear(ImageViewId id);
bool ImageCanRescale(Image& image); bool ImageCanRescale(Image& image);
void InvalidateScale(Image& image, bool invalidate_rt = false); void InvalidateScale(Image& image);
bool ScaleUp(Image& image, bool invalidate_rt = false); bool ScaleUp(Image& image);
bool ScaleDown(Image& image, bool invalidate_rt = false); bool ScaleDown(Image& image);
Runtime& runtime; Runtime& runtime;
VideoCore::RasterizerInterface& rasterizer; VideoCore::RasterizerInterface& rasterizer;