graphics: upload streamed texture mips from sparse reservations

This commit is contained in:
nmzik
2026-09-29 20:25:39 +04:00
parent 59a1760427
commit 650dc1e0af
5 changed files with 54 additions and 48 deletions
+1 -2
View File
@@ -491,8 +491,7 @@ std::pair<Buffer*, uint64_t> BufferCache::ObtainBufferForImage(uint64_t vaddr, u
}
auto [staging, stage_offset] = m_staging_buffer.Map(size, 16);
if (staging == nullptr || (!Libs::LibKernel::Memory::TryReadBacking(vaddr, staging, size) &&
!Libs::LibKernel::Memory::TryReadPrtBacking(vaddr, staging, size))) {
if (staging == nullptr || !Libs::LibKernel::Memory::TryReadSparseBacking(vaddr, staging, size)) {
EXIT("BufferCache: failed to read mapped guest image backing\n");
}
m_staging_buffer.Commit();
+2 -3
View File
@@ -963,10 +963,9 @@ static bool IsInPrtAperture(uint64_t address, uint64_t size = 1) {
return false;
}
bool TryReadPrtBacking(uint64_t vaddr, void* data, uint64_t size) {
bool TryReadSparseBacking(uint64_t vaddr, void* data, uint64_t size) {
std::vector<VirtualRanges::Range> ranges;
if (g_guest_address_space == nullptr || g_virtual_ranges == nullptr ||
!IsInPrtAperture(vaddr, size) || !g_virtual_ranges->QuerySpan(vaddr, size, &ranges)) {
if (!g_virtual_ranges->QuerySpan(vaddr, size, &ranges)) {
return false;
}
if (std::any_of(ranges.begin(), ranges.end(), [](const auto& range) {
+1 -1
View File
@@ -115,7 +115,7 @@ int MapAutomaticMemory(uint64_t vaddr, size_t size, int type, int prot);
bool TryWriteBacking(uint64_t vaddr, const void* data, uint64_t size);
bool TryReadBacking(uint64_t vaddr, void* data, uint64_t size);
bool TryReadGpuCleanBacking(uint64_t vaddr, void* data, uint64_t size);
bool TryReadPrtBacking(uint64_t vaddr, void* data, uint64_t size);
bool TryReadSparseBacking(uint64_t vaddr, void* data, uint64_t size);
[[nodiscard]] uint64_t ClampRangeSize(uint64_t vaddr, uint64_t size);
void WriteBacking(uint64_t vaddr, const void* data, uint64_t size) noexcept;
void InvalidateMemory(uint64_t vaddr, uint64_t size);
+8 -1
View File
@@ -212,14 +212,21 @@ public:
}
auto* destination = static_cast<uint8_t*>(data);
std::memset(destination, 0, size);
auto cursor = vaddr;
for (auto mapping = first; mapping != m_maps.end() && mapping->second.vaddr < end;
++mapping) {
const auto& entry = mapping->second;
const auto start = std::max(vaddr, entry.vaddr);
const auto bytes = std::min(end, entry.vaddr + entry.size) - start;
const auto offset = entry.backing_offset + start - entry.vaddr;
if (cursor < start) {
std::memset(destination + cursor - vaddr, 0, start - cursor);
}
std::memcpy(destination + start - vaddr, m_backing_base + offset, bytes);
cursor = start + bytes;
}
if (cursor < end) {
std::memset(destination + cursor - vaddr, 0, end - cursor);
}
return true;
}