GPU: Add Reactive flushing
This commit is contained in:
parent
e58090c9c7
commit
c6cac2ffaa
24 changed files with 240 additions and 30 deletions
|
@ -39,6 +39,7 @@ struct ImageInfo {
|
|||
u32 tile_width_spacing = 0;
|
||||
bool rescaleable = false;
|
||||
bool downscaleable = false;
|
||||
bool forced_flushed = false;
|
||||
};
|
||||
|
||||
} // namespace VideoCommon
|
||||
|
|
|
@ -26,8 +26,7 @@ ImageViewBase::ImageViewBase(const ImageViewInfo& info, const ImageInfo& image_i
|
|||
ASSERT_MSG(VideoCore::Surface::IsViewCompatible(image_info.format, info.format, false, true),
|
||||
"Image view format {} is incompatible with image format {}", info.format,
|
||||
image_info.format);
|
||||
const bool is_async = Settings::values.use_asynchronous_gpu_emulation.GetValue();
|
||||
if (image_info.type == ImageType::Linear && is_async) {
|
||||
if (image_info.forced_flushed) {
|
||||
flags |= ImageViewFlagBits::PreemtiveDownload;
|
||||
}
|
||||
if (image_info.type == ImageType::e3D && info.type != ImageViewType::e3D) {
|
||||
|
|
|
@ -490,6 +490,32 @@ void TextureCache<P>::DownloadMemory(VAddr cpu_addr, size_t size) {
|
|||
}
|
||||
}
|
||||
|
||||
template <class P>
|
||||
std::optional<VideoCore::RasterizerDownloadArea> TextureCache<P>::GetFlushArea(VAddr cpu_addr,
|
||||
u64 size) {
|
||||
std::optional<VideoCore::RasterizerDownloadArea> area{};
|
||||
ForEachImageInRegion(cpu_addr, size, [&](ImageId, ImageBase& image) {
|
||||
if (False(image.flags & ImageFlagBits::GpuModified)) {
|
||||
return;
|
||||
}
|
||||
if (!area) {
|
||||
area.emplace();
|
||||
area->start_address = cpu_addr;
|
||||
area->end_address = cpu_addr + size;
|
||||
area->preemtive = true;
|
||||
}
|
||||
area->start_address = std::min(area->start_address, image.cpu_addr);
|
||||
area->end_address = std::max(area->end_address, image.cpu_addr_end);
|
||||
for (auto image_view_id : image.image_view_ids) {
|
||||
auto& image_view = slot_image_views[image_view_id];
|
||||
image_view.flags |= ImageViewFlagBits::PreemtiveDownload;
|
||||
}
|
||||
area->preemtive &= image.info.forced_flushed;
|
||||
image.info.forced_flushed = true;
|
||||
});
|
||||
return area;
|
||||
}
|
||||
|
||||
template <class P>
|
||||
void TextureCache<P>::UnmapMemory(VAddr cpu_addr, size_t size) {
|
||||
std::vector<ImageId> deleted_images;
|
||||
|
@ -789,11 +815,15 @@ ImageId TextureCache<P>::DmaImageId(const Tegra::DMA::ImageOperand& operand) {
|
|||
if (!dst_id) {
|
||||
return NULL_IMAGE_ID;
|
||||
}
|
||||
const auto& image = slot_images[dst_id];
|
||||
auto& image = slot_images[dst_id];
|
||||
if (False(image.flags & ImageFlagBits::GpuModified)) {
|
||||
// No need to waste time on an image that's synced with guest
|
||||
return NULL_IMAGE_ID;
|
||||
}
|
||||
if (!image.info.forced_flushed) {
|
||||
image.info.forced_flushed = true;
|
||||
return NULL_IMAGE_ID;
|
||||
}
|
||||
const auto base = image.TryFindBase(operand.address);
|
||||
if (!base) {
|
||||
return NULL_IMAGE_ID;
|
||||
|
|
|
@ -179,6 +179,8 @@ public:
|
|||
/// Download contents of host images to guest memory in a region
|
||||
void DownloadMemory(VAddr cpu_addr, size_t size);
|
||||
|
||||
std::optional<VideoCore::RasterizerDownloadArea> GetFlushArea(VAddr cpu_addr, u64 size);
|
||||
|
||||
/// Remove images in a region
|
||||
void UnmapMemory(VAddr cpu_addr, size_t size);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue