Texture Cache: More rescaling fixes.
This commit is contained in:
parent
10e5065a5c
commit
84f2aea896
4 changed files with 102 additions and 90 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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++) {
|
||||||
|
|
|
@ -204,75 +204,68 @@ 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;
|
||||||
}
|
}
|
||||||
flags[Dirty::RenderTargets] = false;
|
|
||||||
|
|
||||||
// Render target control is used on all render targets, so force look ups when this one is up
|
do {
|
||||||
const bool force = flags[Dirty::RenderTargetControl];
|
flags[Dirty::RenderTargets] = false;
|
||||||
flags[Dirty::RenderTargetControl] = false;
|
|
||||||
|
|
||||||
bool can_rescale = true;
|
has_deleted_images = false;
|
||||||
std::array<ImageId, NUM_RT> tmp_color_images{};
|
// Render target control is used on all render targets, so force look ups when this one is
|
||||||
ImageId tmp_depth_image{};
|
// up
|
||||||
const auto check_rescale = [&](ImageViewId view_id, ImageId& id_save) {
|
const bool force = flags[Dirty::RenderTargetControl];
|
||||||
if (view_id) {
|
flags[Dirty::RenderTargetControl] = false;
|
||||||
const auto& view = slot_image_views[view_id];
|
|
||||||
const auto image_id = view.image_id;
|
bool can_rescale = true;
|
||||||
id_save = image_id;
|
std::array<ImageId, NUM_RT> tmp_color_images{};
|
||||||
auto& image = slot_images[image_id];
|
ImageId tmp_depth_image{};
|
||||||
can_rescale &= ImageCanRescale(image);
|
const auto check_rescale = [&](ImageViewId view_id, ImageId& id_save) {
|
||||||
|
if (view_id) {
|
||||||
|
const auto& view = slot_image_views[view_id];
|
||||||
|
const auto image_id = view.image_id;
|
||||||
|
id_save = image_id;
|
||||||
|
auto& image = slot_images[image_id];
|
||||||
|
can_rescale &= ImageCanRescale(image);
|
||||||
|
} else {
|
||||||
|
id_save = CORRUPT_ID;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
for (size_t index = 0; index < NUM_RT; ++index) {
|
||||||
|
ImageViewId& color_buffer_id = render_targets.color_buffer_ids[index];
|
||||||
|
if (flags[Dirty::ColorBuffer0 + index] || force) {
|
||||||
|
flags[Dirty::ColorBuffer0 + index] = false;
|
||||||
|
BindRenderTarget(&color_buffer_id, FindColorBuffer(index, is_clear));
|
||||||
|
}
|
||||||
|
check_rescale(color_buffer_id, tmp_color_images[index]);
|
||||||
|
}
|
||||||
|
if (flags[Dirty::ZetaBuffer] || force) {
|
||||||
|
flags[Dirty::ZetaBuffer] = false;
|
||||||
|
BindRenderTarget(&render_targets.depth_buffer_id, FindDepthBuffer(is_clear));
|
||||||
|
}
|
||||||
|
check_rescale(render_targets.depth_buffer_id, tmp_depth_image);
|
||||||
|
|
||||||
|
if (can_rescale) {
|
||||||
|
const auto scale_up = [this](ImageId image_id) {
|
||||||
|
if (image_id != CORRUPT_ID) {
|
||||||
|
Image& image = slot_images[image_id];
|
||||||
|
ScaleUp(image);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
for (size_t index = 0; index < NUM_RT; ++index) {
|
||||||
|
scale_up(tmp_color_images[index]);
|
||||||
|
}
|
||||||
|
scale_up(tmp_depth_image);
|
||||||
} else {
|
} else {
|
||||||
id_save = CORRUPT_ID;
|
const auto scale_down = [this](ImageId image_id) {
|
||||||
}
|
if (image_id != CORRUPT_ID) {
|
||||||
};
|
Image& image = slot_images[image_id];
|
||||||
for (size_t index = 0; index < NUM_RT; ++index) {
|
ScaleDown(image);
|
||||||
ImageViewId& color_buffer_id = render_targets.color_buffer_ids[index];
|
}
|
||||||
if (flags[Dirty::ColorBuffer0 + index] || force) {
|
};
|
||||||
flags[Dirty::ColorBuffer0 + index] = false;
|
for (size_t index = 0; index < NUM_RT; ++index) {
|
||||||
BindRenderTarget(&color_buffer_id, FindColorBuffer(index, is_clear));
|
scale_down(tmp_color_images[index]);
|
||||||
}
|
|
||||||
check_rescale(color_buffer_id, tmp_color_images[index]);
|
|
||||||
}
|
|
||||||
if (flags[Dirty::ZetaBuffer] || force) {
|
|
||||||
flags[Dirty::ZetaBuffer] = false;
|
|
||||||
BindRenderTarget(&render_targets.depth_buffer_id, FindDepthBuffer(is_clear));
|
|
||||||
}
|
|
||||||
check_rescale(render_targets.depth_buffer_id, tmp_depth_image);
|
|
||||||
|
|
||||||
if (can_rescale) {
|
|
||||||
const auto scale_up = [this](ImageId image_id) {
|
|
||||||
if (image_id != CORRUPT_ID) {
|
|
||||||
Image& image = slot_images[image_id];
|
|
||||||
return ScaleUp(image);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
for (size_t index = 0; index < NUM_RT; ++index) {
|
|
||||||
if (scale_up(tmp_color_images[index])) {
|
|
||||||
BindRenderTarget(&render_targets.color_buffer_ids[index],
|
|
||||||
FindColorBuffer(index, is_clear));
|
|
||||||
}
|
}
|
||||||
|
scale_down(tmp_depth_image);
|
||||||
}
|
}
|
||||||
if (scale_up(tmp_depth_image)) {
|
} while (has_deleted_images);
|
||||||
BindRenderTarget(&render_targets.depth_buffer_id, FindDepthBuffer(is_clear));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const auto scale_down = [this](ImageId image_id) {
|
|
||||||
if (image_id != CORRUPT_ID) {
|
|
||||||
Image& image = slot_images[image_id];
|
|
||||||
return ScaleDown(image);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
for (size_t index = 0; index < NUM_RT; ++index) {
|
|
||||||
if (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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Rescale End
|
// Rescale End
|
||||||
|
|
||||||
for (size_t index = 0; index < NUM_RT; ++index) {
|
for (size_t index = 0; index < NUM_RT; ++index) {
|
||||||
|
@ -708,43 +701,54 @@ 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;
|
for (size_t rt = 0; rt < NUM_RT; ++rt) {
|
||||||
for (size_t rt = 0; rt < NUM_RT; ++rt) {
|
dirty[Dirty::ColorBuffer0 + rt] = true;
|
||||||
dirty[Dirty::ColorBuffer0 + rt] = true;
|
}
|
||||||
}
|
for (const ImageViewId image_view_id : image_view_ids) {
|
||||||
for (const ImageViewId image_view_id : image_view_ids) {
|
std::ranges::replace(render_targets.color_buffer_ids, image_view_id, ImageViewId{});
|
||||||
std::ranges::replace(render_targets.color_buffer_ids, image_view_id, ImageViewId{});
|
if (render_targets.depth_buffer_id == image_view_id) {
|
||||||
if (render_targets.depth_buffer_id == image_view_id) {
|
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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue