|
|
@ -711,16 +711,12 @@ void TextureCache<P>::DownloadMemory(DAddr cpu_addr, size_t size) { |
|
|
runtime.Finish(); |
|
|
runtime.Finish(); |
|
|
SwizzleImage(*gpu_memory, image.gpu_addr, image.info, copies, map.mapped_span, |
|
|
SwizzleImage(*gpu_memory, image.gpu_addr, image.info, copies, map.mapped_span, |
|
|
swizzle_data_buffer); |
|
|
swizzle_data_buffer); |
|
|
RebuildGpuModifiedPagesInRange(image.cpu_addr, image.cpu_addr_end - image.cpu_addr); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
template <class P> |
|
|
template <class P> |
|
|
std::optional<VideoCore::RasterizerDownloadArea> TextureCache<P>::GetFlushArea(DAddr cpu_addr, |
|
|
std::optional<VideoCore::RasterizerDownloadArea> TextureCache<P>::GetFlushArea(DAddr cpu_addr, |
|
|
u64 size) { |
|
|
u64 size) { |
|
|
if (!HasGpuModifiedPagesInRange(cpu_addr, size)) { |
|
|
|
|
|
return std::nullopt; |
|
|
|
|
|
} |
|
|
|
|
|
std::optional<VideoCore::RasterizerDownloadArea> area{}; |
|
|
std::optional<VideoCore::RasterizerDownloadArea> area{}; |
|
|
ForEachImageInRegion(cpu_addr, size, [&](ImageId, ImageBase& image) { |
|
|
ForEachImageInRegion(cpu_addr, size, [&](ImageId, ImageBase& image) { |
|
|
if (False(image.flags & ImageFlagBits::GpuModified)) { |
|
|
if (False(image.flags & ImageFlagBits::GpuModified)) { |
|
|
@ -1111,9 +1107,6 @@ bool TextureCache<P>::IsRescaling(const ImageViewBase& image_view) const noexcep |
|
|
|
|
|
|
|
|
template <class P> |
|
|
template <class P> |
|
|
bool TextureCache<P>::IsRegionGpuModified(DAddr addr, size_t size) { |
|
|
bool TextureCache<P>::IsRegionGpuModified(DAddr addr, size_t size) { |
|
|
if (!HasGpuModifiedPagesInRange(addr, size)) { |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
bool is_modified = false; |
|
|
bool is_modified = false; |
|
|
ForEachImageInRegion(addr, size, [&is_modified](ImageId, ImageBase& image) { |
|
|
ForEachImageInRegion(addr, size, [&is_modified](ImageId, ImageBase& image) { |
|
|
if (False(image.flags & ImageFlagBits::GpuModified)) { |
|
|
if (False(image.flags & ImageFlagBits::GpuModified)) { |
|
|
@ -1125,24 +1118,6 @@ bool TextureCache<P>::IsRegionGpuModified(DAddr addr, size_t size) { |
|
|
return is_modified; |
|
|
return is_modified; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
template <class P> |
|
|
|
|
|
bool TextureCache<P>::HasGpuModifiedPagesInRange(DAddr addr, size_t size) const { |
|
|
|
|
|
bool has_dirty_page = false; |
|
|
|
|
|
gpu_modified_pages.ForEachInRange(addr, size, [&](DAddr, DAddr) { has_dirty_page = true; }); |
|
|
|
|
|
return has_dirty_page; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
template <class P> |
|
|
|
|
|
void TextureCache<P>::RebuildGpuModifiedPagesInRange(DAddr addr, size_t size) { |
|
|
|
|
|
gpu_modified_pages.Subtract(addr, size); |
|
|
|
|
|
ForEachImageInRegion(addr, size, [this](ImageId, ImageBase& image) { |
|
|
|
|
|
if (False(image.flags & ImageFlagBits::GpuModified)) { |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
gpu_modified_pages.Add(image.cpu_addr, image.cpu_addr_end - image.cpu_addr); |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
template <class P> |
|
|
template <class P> |
|
|
std::pair<typename TextureCache<P>::Image*, BufferImageCopy> TextureCache<P>::DmaBufferImageCopy( |
|
|
std::pair<typename TextureCache<P>::Image*, BufferImageCopy> TextureCache<P>::DmaBufferImageCopy( |
|
|
const Tegra::DMA::ImageCopy& copy_info, const Tegra::DMA::BufferOperand& buffer_operand, |
|
|
const Tegra::DMA::ImageCopy& copy_info, const Tegra::DMA::BufferOperand& buffer_operand, |
|
|
@ -1897,7 +1872,6 @@ ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, DA |
|
|
} |
|
|
} |
|
|
if (True(overlap.flags & ImageFlagBits::GpuModified)) { |
|
|
if (True(overlap.flags & ImageFlagBits::GpuModified)) { |
|
|
new_image.flags |= ImageFlagBits::GpuModified; |
|
|
new_image.flags |= ImageFlagBits::GpuModified; |
|
|
gpu_modified_pages.Add(new_image.cpu_addr, new_image.cpu_addr_end - new_image.cpu_addr); |
|
|
|
|
|
const auto& resolution = Settings::values.resolution_info; |
|
|
const auto& resolution = Settings::values.resolution_info; |
|
|
const SubresourceBase base = new_image.TryFindBase(overlap.gpu_addr).value(); |
|
|
const SubresourceBase base = new_image.TryFindBase(overlap.gpu_addr).value(); |
|
|
const u32 up_scale = can_rescale ? resolution.up_scale : 1; |
|
|
const u32 up_scale = can_rescale ? resolution.up_scale : 1; |
|
|
@ -2569,9 +2543,6 @@ void TextureCache<P>::UntrackImage(ImageBase& image, ImageId image_id) { |
|
|
template <class P> |
|
|
template <class P> |
|
|
void TextureCache<P>::DeleteImage(ImageId image_id, bool immediate_delete) { |
|
|
void TextureCache<P>::DeleteImage(ImageId image_id, bool immediate_delete) { |
|
|
ImageBase& image = slot_images[image_id]; |
|
|
ImageBase& image = slot_images[image_id]; |
|
|
const bool was_gpu_modified = True(image.flags & ImageFlagBits::GpuModified); |
|
|
|
|
|
const DAddr image_cpu_addr = image.cpu_addr; |
|
|
|
|
|
const size_t image_cpu_size = image.cpu_addr_end - image.cpu_addr; |
|
|
|
|
|
if (image.HasScaled()) { |
|
|
if (image.HasScaled()) { |
|
|
total_used_memory -= GetScaledImageSizeBytes(image); |
|
|
total_used_memory -= GetScaledImageSizeBytes(image); |
|
|
} |
|
|
} |
|
|
@ -2660,9 +2631,6 @@ void TextureCache<P>::DeleteImage(ImageId image_id, bool immediate_delete) { |
|
|
channel_info.compute_image_table.Invalidate(); |
|
|
channel_info.compute_image_table.Invalidate(); |
|
|
} |
|
|
} |
|
|
has_deleted_images = true; |
|
|
has_deleted_images = true; |
|
|
if (was_gpu_modified) { |
|
|
|
|
|
RebuildGpuModifiedPagesInRange(image_cpu_addr, image_cpu_size); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
template <class P> |
|
|
template <class P> |
|
|
@ -2703,7 +2671,6 @@ void TextureCache<P>::RemoveFramebuffers(std::span<const ImageViewId> removed_vi |
|
|
template <class P> |
|
|
template <class P> |
|
|
void TextureCache<P>::MarkModification(ImageBase& image) noexcept { |
|
|
void TextureCache<P>::MarkModification(ImageBase& image) noexcept { |
|
|
image.flags |= ImageFlagBits::GpuModified; |
|
|
image.flags |= ImageFlagBits::GpuModified; |
|
|
gpu_modified_pages.Add(image.cpu_addr, image.cpu_addr_end - image.cpu_addr); |
|
|
|
|
|
image.modification_tick = ++modification_tick; |
|
|
image.modification_tick = ++modification_tick; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -2737,7 +2704,6 @@ void TextureCache<P>::SynchronizeAliases(ImageId image_id) { |
|
|
image.modification_tick = most_recent_tick; |
|
|
image.modification_tick = most_recent_tick; |
|
|
if (any_modified) { |
|
|
if (any_modified) { |
|
|
image.flags |= ImageFlagBits::GpuModified; |
|
|
image.flags |= ImageFlagBits::GpuModified; |
|
|
gpu_modified_pages.Add(image.cpu_addr, image.cpu_addr_end - image.cpu_addr); |
|
|
|
|
|
} |
|
|
} |
|
|
std::ranges::sort(aliased_images, [this](const AliasedImage* lhs, const AliasedImage* rhs) { |
|
|
std::ranges::sort(aliased_images, [this](const AliasedImage* lhs, const AliasedImage* rhs) { |
|
|
const ImageBase& lhs_image = slot_images[lhs->id]; |
|
|
const ImageBase& lhs_image = slot_images[lhs->id]; |
|
|
@ -2765,11 +2731,7 @@ template <class P> |
|
|
void TextureCache<P>::PrepareImage(ImageId image_id, bool is_modification, bool invalidate) { |
|
|
void TextureCache<P>::PrepareImage(ImageId image_id, bool is_modification, bool invalidate) { |
|
|
Image& image = slot_images[image_id]; |
|
|
Image& image = slot_images[image_id]; |
|
|
if (invalidate) { |
|
|
if (invalidate) { |
|
|
const bool was_gpu_modified = True(image.flags & ImageFlagBits::GpuModified); |
|
|
|
|
|
image.flags &= ~(ImageFlagBits::CpuModified | ImageFlagBits::GpuModified); |
|
|
image.flags &= ~(ImageFlagBits::CpuModified | ImageFlagBits::GpuModified); |
|
|
if (was_gpu_modified) { |
|
|
|
|
|
RebuildGpuModifiedPagesInRange(image.cpu_addr, image.cpu_addr_end - image.cpu_addr); |
|
|
|
|
|
} |
|
|
|
|
|
if (False(image.flags & ImageFlagBits::Tracked)) { |
|
|
if (False(image.flags & ImageFlagBits::Tracked)) { |
|
|
TrackImage(image, image_id); |
|
|
TrackImage(image, image_id); |
|
|
} |
|
|
} |
|
|
|