early-access version 3552

This commit is contained in:
pineappleEA
2023-05-04 16:44:44 +02:00
parent 87bd2b0bdd
commit bab2c14888
48 changed files with 508 additions and 482 deletions

View File

@@ -39,6 +39,8 @@ struct ImageInfo {
u32 tile_width_spacing = 0;
bool rescaleable = false;
bool downscaleable = false;
bool forced_flushed = false;
bool dma_downloaded = false;
};
} // namespace VideoCommon

View File

@@ -26,8 +26,9 @@ 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) {
const bool preemptive =
!Settings::values.use_reactive_flushing.GetValue() && image_info.type == ImageType::Linear;
if (image_info.forced_flushed || preemptive) {
flags |= ImageViewFlagBits::PreemtiveDownload;
}
if (image_info.type == ImageType::e3D && info.type != ImageViewType::e3D) {

View File

@@ -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;
@@ -683,18 +709,43 @@ void TextureCache<P>::CommitAsyncFlushes() {
download_info.async_buffer_id = last_async_buffer_id;
}
}
if (any_none_dma) {
bool all_pre_sync = true;
auto download_map = runtime.DownloadStagingBuffer(total_size_bytes, true);
for (const PendingDownload& download_info : download_ids) {
if (download_info.is_swizzle) {
Image& image = slot_images[download_info.object_id];
all_pre_sync &= image.info.dma_downloaded;
image.info.dma_downloaded = true;
const auto copies = FullDownloadCopies(image.info);
image.DownloadMemory(download_map, copies);
download_map.offset += Common::AlignUp(image.unswizzled_size_bytes, 64);
}
}
uncommitted_async_buffers.emplace_back(download_map);
if (!all_pre_sync) {
runtime.Finish();
auto it = download_ids.begin();
while (it != download_ids.end()) {
const PendingDownload& download_info = *it;
if (download_info.is_swizzle) {
const ImageBase& image = slot_images[download_info.object_id];
const auto copies = FullDownloadCopies(image.info);
download_map.offset -= Common::AlignUp(image.unswizzled_size_bytes, 64);
std::span<u8> download_span =
download_map.mapped_span.subspan(download_map.offset);
SwizzleImage(*gpu_memory, image.gpu_addr, image.info, copies, download_span,
swizzle_data_buffer);
it = download_ids.erase(it);
} else {
it++;
}
}
} else {
uncommitted_async_buffers.emplace_back(download_map);
}
}
async_buffers.emplace_back(std::move(uncommitted_async_buffers));
uncommitted_async_buffers.clear();
}
@@ -789,11 +840,16 @@ 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.dma_downloaded) {
// Force a full sync.
image.info.dma_downloaded = true;
return NULL_IMAGE_ID;
}
const auto base = image.TryFindBase(operand.address);
if (!base) {
return NULL_IMAGE_ID;

View File

@@ -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);