mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2026-07-09 17:25:37 -06:00
Refactor texture cache image download handling (#4593)
* Add rasterizer image processing in event handling * Implement ProcessDownloadImages method Added a new method to process downloaded images in the rasterizer. * Add ProcessDownloadImages method to vk_rasterizer.h * Modify DownloadImageMemory to include sync parameter Added optional sync parameter to DownloadImageMemory. * Refactor texture cache image download handling Updated DownloadImageMemory to support synchronous downloads and adjusted image extent calculations. * Refactor image download condition and format code Fix conditional logic for downloading images and add newline at end of file. * Removed redundant check for volume in FindTexture function. * Add readback_linear_images check in FindTexture
This commit is contained in:
parent
64d198190f
commit
16d5f9c54c
@ -691,6 +691,9 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
||||
}
|
||||
case PM4ItOpcode::EventWriteEos: {
|
||||
const auto* event_eos = reinterpret_cast<const PM4CmdEventWriteEos*>(header);
|
||||
if (rasterizer) {
|
||||
rasterizer->ProcessDownloadImages();
|
||||
}
|
||||
event_eos->SignalFence([](void* address, u64 data, u32 num_bytes) {
|
||||
auto* memory = Core::Memory::Instance();
|
||||
if (!memory->TryWriteBacking(address, &data, num_bytes)) {
|
||||
@ -709,6 +712,9 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
||||
}
|
||||
case PM4ItOpcode::EventWriteEop: {
|
||||
const auto* event_eop = reinterpret_cast<const PM4CmdEventWriteEop*>(header);
|
||||
if (rasterizer) {
|
||||
rasterizer->ProcessDownloadImages();
|
||||
}
|
||||
event_eop->SignalFence(
|
||||
[](void* address, u64 data, u32 num_bytes) {
|
||||
auto* memory = Core::Memory::Instance();
|
||||
@ -1137,6 +1143,9 @@ Liverpool::Task Liverpool::ProcessCompute(std::span<const u32> acb, u32 vqid) {
|
||||
}
|
||||
case PM4ItOpcode::ReleaseMem: {
|
||||
const auto* release_mem = reinterpret_cast<const PM4CmdReleaseMem*>(header);
|
||||
if (rasterizer) {
|
||||
rasterizer->ProcessDownloadImages();
|
||||
}
|
||||
release_mem->SignalFence(
|
||||
[pipe_id = queue.pipe_id] {
|
||||
Platform::IrqC::Instance()->Signal(static_cast<Platform::InterruptId>(pipe_id));
|
||||
|
||||
@ -1068,6 +1068,10 @@ bool Rasterizer::ReadMemory(VAddr addr, u64 size) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void Rasterizer::ProcessDownloadImages() {
|
||||
texture_cache.ProcessDownloadImages();
|
||||
}
|
||||
|
||||
bool Rasterizer::IsMapped(VAddr addr, u64 size) {
|
||||
if (size == 0) {
|
||||
// There is no memory, so not mapped.
|
||||
|
||||
@ -60,6 +60,7 @@ public:
|
||||
u32 ReadDataFromGds(u32 gsd_offset);
|
||||
bool InvalidateMemory(VAddr addr, u64 size);
|
||||
bool ReadMemory(VAddr addr, u64 size);
|
||||
void ProcessDownloadImages();
|
||||
bool IsMapped(VAddr addr, u64 size);
|
||||
void MapMemory(VAddr addr, u64 size);
|
||||
void UnmapMemory(VAddr addr, u64 size);
|
||||
|
||||
@ -87,18 +87,18 @@ ImageId TextureCache::GetNullImage(const vk::Format format) {
|
||||
|
||||
void TextureCache::ProcessDownloadImages() {
|
||||
for (const ImageId image_id : download_images) {
|
||||
DownloadImageMemory(image_id);
|
||||
DownloadImageMemory(image_id, true);
|
||||
}
|
||||
download_images.clear();
|
||||
}
|
||||
|
||||
void TextureCache::DownloadImageMemory(ImageId image_id) {
|
||||
void TextureCache::DownloadImageMemory(ImageId image_id, bool sync) {
|
||||
Image& image = slot_images[image_id];
|
||||
if (False(image.flags & ImageFlagBits::GpuModified)) {
|
||||
return;
|
||||
}
|
||||
auto& download_buffer = buffer_cache.GetUtilityBuffer(MemoryUsage::Download);
|
||||
const u32 download_size = image.info.pitch * image.info.size.height *
|
||||
const u32 download_size = image.info.pitch * image.info.size.height * image.info.size.depth *
|
||||
image.info.resources.layers * (image.info.num_bits / 8);
|
||||
ASSERT(download_size <= image.info.guest_size);
|
||||
const auto [download, offset] = download_buffer.Map(download_size);
|
||||
@ -116,7 +116,7 @@ void TextureCache::DownloadImageMemory(ImageId image_id) {
|
||||
.layerCount = image.info.resources.layers,
|
||||
},
|
||||
.imageOffset = {0, 0, 0},
|
||||
.imageExtent = {image.info.size.width, image.info.size.height, 1},
|
||||
.imageExtent = {image.info.size.width, image.info.size.height, image.info.size.depth},
|
||||
};
|
||||
scheduler.EndRendering();
|
||||
const auto cmdbuf = scheduler.CommandBuffer();
|
||||
@ -124,11 +124,17 @@ void TextureCache::DownloadImageMemory(ImageId image_id) {
|
||||
cmdbuf.copyImageToBuffer(image.GetImage(), vk::ImageLayout::eTransferSrcOptimal,
|
||||
download_buffer.Handle(), image_download);
|
||||
|
||||
scheduler.DeferPriorityOperation(
|
||||
[this, device_addr = image.info.guest_address, download, download_size] {
|
||||
Core::Memory::Instance()->TryWriteBacking(std::bit_cast<u8*>(device_addr), download,
|
||||
download_size);
|
||||
});
|
||||
const auto write_data = [this, device_addr = image.info.guest_address, download,
|
||||
download_size] {
|
||||
Core::Memory::Instance()->TryWriteBacking(std::bit_cast<u8*>(device_addr), download,
|
||||
download_size);
|
||||
};
|
||||
if (sync) {
|
||||
scheduler.Finish();
|
||||
write_data();
|
||||
} else {
|
||||
scheduler.DeferPriorityOperation(write_data);
|
||||
}
|
||||
}
|
||||
|
||||
void TextureCache::MarkAsMaybeDirty(ImageId image_id, Image& image) {
|
||||
|
||||
@ -272,7 +272,7 @@ private:
|
||||
ImageId GetNullImage(vk::Format format);
|
||||
|
||||
/// Copies image memory back to CPU.
|
||||
void DownloadImageMemory(ImageId image_id);
|
||||
void DownloadImageMemory(ImageId image_id, bool sync = false);
|
||||
|
||||
/// Thread function for copying downloaded images out to CPU memory.
|
||||
void DownloadedImagesThread(const std::stop_token& token);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user