mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 22:06:59 +01:00
Support tiled storage readback
This commit is contained in:
@@ -56,23 +56,15 @@ private:
|
|||||||
TrackingSpinLock& m_mutex;
|
TrackingSpinLock& m_mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool Overlaps(uint64_t left, uint64_t left_size, uint64_t right, uint64_t right_size) {
|
|
||||||
return left < right + right_size && right < left + left_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PageOverlaps(uint64_t left, uint64_t left_size, uint64_t right, uint64_t right_size) {
|
|
||||||
return ImagePageRangesOverlap(left, left_size, right, right_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
enum class ImageRangeOverlap : uint8_t { None, PageOnly, Bytes };
|
enum class ImageRangeOverlap : uint8_t { None, PageOnly, Bytes };
|
||||||
|
|
||||||
ImageRangeOverlap ClassifyImageRangeOverlap(uint64_t left, uint64_t left_size, uint64_t right,
|
ImageRangeOverlap ClassifyImageRangeOverlap(uint64_t left, uint64_t left_size, uint64_t right,
|
||||||
uint64_t right_size) {
|
uint64_t right_size) {
|
||||||
if (Overlaps(left, left_size, right, right_size)) {
|
if (ImageRangeOverlaps(left, left_size, right, right_size)) {
|
||||||
return ImageRangeOverlap::Bytes;
|
return ImageRangeOverlap::Bytes;
|
||||||
}
|
}
|
||||||
return PageOverlaps(left, left_size, right, right_size) ? ImageRangeOverlap::PageOnly
|
return ImagePageRangesOverlap(left, left_size, right, right_size) ? ImageRangeOverlap::PageOnly
|
||||||
: ImageRangeOverlap::None;
|
: ImageRangeOverlap::None;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
@@ -176,8 +168,8 @@ struct TextureCache::CachedImage {
|
|||||||
}
|
}
|
||||||
[[nodiscard]] bool OverlapsRange(uint64_t address, uint64_t size, bool page) const {
|
[[nodiscard]] bool OverlapsRange(uint64_t address, uint64_t size, bool page) const {
|
||||||
for (uint32_t i = 0; i < RangeCount(); i++) {
|
for (uint32_t i = 0; i < RangeCount(); i++) {
|
||||||
if (page ? PageOverlaps(address, size, Address(i), Size(i))
|
if (page ? ImagePageRangesOverlap(address, size, Address(i), Size(i))
|
||||||
: Overlaps(address, size, Address(i), Size(i))) {
|
: ImageRangeOverlaps(address, size, Address(i), Size(i))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -417,8 +409,10 @@ struct TextureCache::ReadbackWorker {
|
|||||||
Prospero::NumBytesPerElement(cached.info.format))
|
Prospero::NumBytesPerElement(cached.info.format))
|
||||||
: MakeColorImageTransferInfo(cached.target);
|
: MakeColorImageTransferInfo(cached.target);
|
||||||
const bool linear = info.tile_mode == Prospero::GpuEnumValue(Prospero::TileMode::kLinear);
|
const bool linear = info.tile_mode == Prospero::GpuEnumValue(Prospero::TileMode::kLinear);
|
||||||
const bool tiled = target && IsTiledRenderTarget(cached.target);
|
const bool tiled_target = target && IsTiledRenderTarget(cached.target);
|
||||||
bool single_layer_storage = false;
|
const bool tiled_storage =
|
||||||
|
storage && info.tile_mode == Prospero::GpuEnumValue(Prospero::TileMode::kRenderTarget);
|
||||||
|
bool single_layer_storage = false;
|
||||||
if (storage) {
|
if (storage) {
|
||||||
switch (static_cast<Prospero::ImageType>(cached.info.type)) {
|
switch (static_cast<Prospero::ImageType>(cached.info.type)) {
|
||||||
case Prospero::ImageType::kColor2D:
|
case Prospero::ImageType::kColor2D:
|
||||||
@@ -429,10 +423,12 @@ struct TextureCache::ReadbackWorker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const bool basic_storage =
|
const bool basic_storage =
|
||||||
!storage || (single_layer_storage && cached.info.base_level == 0 &&
|
!storage ||
|
||||||
cached.info.levels == 1 && cached.info.base_array == 0 && linear);
|
(single_layer_storage && cached.info.base_level == 0 && cached.info.levels == 1 &&
|
||||||
|
cached.info.base_array == 0 && (linear || tiled_storage));
|
||||||
const auto layers = target ? cached.target.layers : 1u;
|
const auto layers = target ? cached.target.layers : 1u;
|
||||||
if ((!linear && !tiled) || !basic_storage || info.levels != 1 || info.size > UINT32_MAX) {
|
if ((!linear && !tiled_target && !tiled_storage) || !basic_storage || info.levels != 1 ||
|
||||||
|
info.size > UINT32_MAX) {
|
||||||
EXIT("TextureCache: unsupported color-image readback layout, addr=0x%016" PRIx64
|
EXIT("TextureCache: unsupported color-image readback layout, addr=0x%016" PRIx64
|
||||||
" size=0x%016" PRIx64 " extent=%ux%u pitch=%u bpe=%u levels=%u tile=%u kind=%u\n",
|
" size=0x%016" PRIx64 " extent=%ux%u pitch=%u bpe=%u levels=%u tile=%u kind=%u\n",
|
||||||
info.address, info.size, info.width, info.height, info.pitch,
|
info.address, info.size, info.width, info.height, info.pitch,
|
||||||
@@ -454,9 +450,20 @@ struct TextureCache::ReadbackWorker {
|
|||||||
MakeLayeredImageBufferCopies(layers, slice_size, info.pitch, info.width, info.height);
|
MakeLayeredImageBufferCopies(layers, slice_size, info.pitch, info.width, info.height);
|
||||||
UtilFillBuffer(cached.ctx, download.data(), info.size, regions, cached.image,
|
UtilFillBuffer(cached.ctx, download.data(), info.size, regions, cached.image,
|
||||||
cached.image->layout);
|
cached.image->layout);
|
||||||
if (tiled) {
|
if (tiled_target || tiled_storage) {
|
||||||
guest.resize(info.size);
|
guest.resize(info.size);
|
||||||
cache.m_tiler.TileImage(guest.data(), download.data(), cached.target);
|
const RenderTargetInfo layout =
|
||||||
|
target ? cached.target : RenderTargetInfo {info.address,
|
||||||
|
info.size,
|
||||||
|
info.format,
|
||||||
|
info.width,
|
||||||
|
info.height,
|
||||||
|
info.pitch,
|
||||||
|
info.bytes_per_element,
|
||||||
|
info.tile_mode,
|
||||||
|
info.levels,
|
||||||
|
1};
|
||||||
|
cache.m_tiler.TileImage(guest.data(), download.data(), layout);
|
||||||
Libs::LibKernel::Memory::WriteBacking(info.address, guest.data(), info.size);
|
Libs::LibKernel::Memory::WriteBacking(info.address, guest.data(), info.size);
|
||||||
} else {
|
} else {
|
||||||
Libs::LibKernel::Memory::WriteBacking(info.address, download.data(), info.size);
|
Libs::LibKernel::Memory::WriteBacking(info.address, download.data(), info.size);
|
||||||
@@ -602,7 +609,8 @@ void TextureCache::RetireImages(const std::vector<CachedImage*>& retire,
|
|||||||
}
|
}
|
||||||
const bool sampled = (*it)->kind == CachedImage::Kind::Texture;
|
const bool sampled = (*it)->kind == CachedImage::Kind::Texture;
|
||||||
const bool storage = (*it)->kind == CachedImage::Kind::StorageTexture;
|
const bool storage = (*it)->kind == CachedImage::Kind::StorageTexture;
|
||||||
const bool target = (*it)->kind == CachedImage::Kind::RenderTarget;
|
const bool target = (*it)->kind == CachedImage::Kind::RenderTarget ||
|
||||||
|
(*it)->kind == CachedImage::Kind::DepthTarget;
|
||||||
const bool native_image = it->get() == native_image_source;
|
const bool native_image = it->get() == native_image_source;
|
||||||
if (native_image) {
|
if (native_image) {
|
||||||
bool source_valid = (*it)->gpu_modified && !(*it)->buffer_modified;
|
bool source_valid = (*it)->gpu_modified && !(*it)->buffer_modified;
|
||||||
@@ -1664,6 +1672,37 @@ void TextureCache::RetireSampledTargetAliases(GraphicContext* ctx, const ImageIn
|
|||||||
cached->ctx == ctx, cached->gpu_modified, cached->buffer_modified);
|
cached->ctx == ctx, cached->gpu_modified, cached->buffer_modified);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (const auto& cached: m_images) {
|
||||||
|
if (cached->kind != CachedImage::Kind::DepthTarget) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const auto overlap = ClassifyImageRangeOverlap(requested.address, requested.size,
|
||||||
|
cached->depth.address, cached->depth.size);
|
||||||
|
if (overlap == ImageRangeOverlap::None) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const auto delta = cached->depth.address >= requested.address
|
||||||
|
? cached->depth.address - requested.address
|
||||||
|
: UINT64_MAX;
|
||||||
|
const bool contained =
|
||||||
|
delta <= requested.size && cached->depth.size <= requested.size - delta;
|
||||||
|
const bool supported = cached->ctx == ctx && !cached->buffer_modified &&
|
||||||
|
cached->depth.stencil_address == 0 &&
|
||||||
|
cached->depth.stencil_size == 0 && cached->depth.layers == 1 &&
|
||||||
|
(overlap == ImageRangeOverlap::PageOnly || contained);
|
||||||
|
if (!supported) {
|
||||||
|
EXIT("TextureCache: unsupported sampled/depth-target alias, sampled=0x%016" PRIx64
|
||||||
|
"+0x%016" PRIx64 " depth=0x%016" PRIx64 "+0x%016" PRIx64
|
||||||
|
" overlap=%u contained=%d same_context=%d gpu=%d buffer=%d stencil=0x%016" PRIx64
|
||||||
|
"+0x%016" PRIx64 " layers=%u\n",
|
||||||
|
requested.address, requested.size, cached->depth.address, cached->depth.size,
|
||||||
|
static_cast<uint32_t>(overlap), contained, cached->ctx == ctx,
|
||||||
|
cached->gpu_modified, cached->buffer_modified, cached->depth.stencil_address,
|
||||||
|
cached->depth.stencil_size, cached->depth.layers);
|
||||||
|
}
|
||||||
|
wait_idle |= cached->gpu_modified;
|
||||||
|
retire.push_back(cached.get());
|
||||||
|
}
|
||||||
if (retire.empty()) {
|
if (retire.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1675,11 +1714,51 @@ void TextureCache::RetireSampledTargetAliases(GraphicContext* ctx, const ImageIn
|
|||||||
if (!cached->gpu_modified) {
|
if (!cached->gpu_modified) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const auto transfer = m_readback->DownloadColorImage(*cached);
|
const auto transfer = cached->kind == CachedImage::Kind::DepthTarget
|
||||||
|
? m_readback->DownloadDepthTarget(*cached)
|
||||||
|
: m_readback->DownloadColorImage(*cached);
|
||||||
m_memory_tracker.ForEachDownloadRange<true>(transfer.address, transfer.size,
|
m_memory_tracker.ForEachDownloadRange<true>(transfer.address, transfer.size,
|
||||||
[](uint64_t, uint64_t) noexcept {});
|
[](uint64_t, uint64_t) noexcept {});
|
||||||
cached->gpu_modified = false;
|
cached->gpu_modified = false;
|
||||||
}
|
}
|
||||||
|
std::vector<uint64_t> retire_depth_metadata;
|
||||||
|
for (auto* cached: retire) {
|
||||||
|
if (cached->kind != CachedImage::Kind::DepthTarget || cached->depth.htile_address == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const bool retained_owner =
|
||||||
|
std::any_of(m_images.begin(), m_images.end(), [&](const auto& other) {
|
||||||
|
return std::find(retire.begin(), retire.end(), other.get()) == retire.end() &&
|
||||||
|
other->kind == CachedImage::Kind::DepthTarget &&
|
||||||
|
other->depth.htile_address == cached->depth.htile_address &&
|
||||||
|
other->depth.htile_size == cached->depth.htile_size;
|
||||||
|
});
|
||||||
|
if (!retained_owner &&
|
||||||
|
std::find(retire_depth_metadata.begin(), retire_depth_metadata.end(),
|
||||||
|
cached->depth.htile_address) == retire_depth_metadata.end()) {
|
||||||
|
retire_depth_metadata.push_back(cached->depth.htile_address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const auto address: retire_depth_metadata) {
|
||||||
|
auto metadata = m_surface_metas.find(address);
|
||||||
|
auto owner = std::find_if(retire.begin(), retire.end(), [&](const auto* cached) {
|
||||||
|
return cached->kind == CachedImage::Kind::DepthTarget &&
|
||||||
|
cached->depth.htile_address == address;
|
||||||
|
});
|
||||||
|
if (metadata == m_surface_metas.end() || owner == retire.end() ||
|
||||||
|
metadata->second.size != (*owner)->depth.htile_size) {
|
||||||
|
EXIT(
|
||||||
|
"TextureCache: retiring depth target has invalid HTile metadata, addr=0x%016" PRIx64
|
||||||
|
" size=0x%016" PRIx64 "\n",
|
||||||
|
address, owner != retire.end() ? (*owner)->depth.htile_size : 0);
|
||||||
|
}
|
||||||
|
if (metadata->second.gpu_modified) {
|
||||||
|
m_metadata_tracker.ForEachDownloadRange<true>(metadata->first, metadata->second.size,
|
||||||
|
[](uint64_t, uint64_t) noexcept {});
|
||||||
|
}
|
||||||
|
m_metadata_tracker.UntrackMemory(metadata->first, metadata->second.size);
|
||||||
|
m_surface_metas.erase(metadata);
|
||||||
|
}
|
||||||
RetireImages(retire);
|
RetireImages(retire);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1895,9 +1974,13 @@ VulkanImage* TextureCache::FindTexture(CommandBuffer* command, GraphicContext* c
|
|||||||
if (!cached->OverlapsRange(info.address, info.size, true)) {
|
if (!cached->OverlapsRange(info.address, info.size, true)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
EXIT("TextureCache: sampled image shares pages with GPU target, addr=0x%016" PRIx64
|
EXIT("TextureCache: sampled image overlaps GPU target, requested=0x%016" PRIx64
|
||||||
" size=0x%016" PRIx64 " target_kind=%u\n",
|
"+0x%016" PRIx64 " target=0x%016" PRIx64 "+0x%016" PRIx64
|
||||||
info.address, info.size, static_cast<uint32_t>(cached->kind));
|
" target_kind=%u requested_info={format=%u extent=%ux%ux%u pitch=%u levels=%u"
|
||||||
|
" tile=%u type=%u}\n",
|
||||||
|
info.address, info.size, cached->Address(), cached->Size(),
|
||||||
|
static_cast<uint32_t>(cached->kind), info.format, info.width, info.height,
|
||||||
|
info.depth, info.pitch, info.levels, info.tile, info.type);
|
||||||
}
|
}
|
||||||
const auto overlap =
|
const auto overlap =
|
||||||
ClassifySampledOverlap(info, cached->info, cached->gpu_modified, cached->ctx == ctx);
|
ClassifySampledOverlap(info, cached->info, cached->gpu_modified, cached->ctx == ctx);
|
||||||
@@ -2291,15 +2374,16 @@ DepthStencilVulkanImage* TextureCache::FindDepthTarget(CommandBuffer* command, G
|
|||||||
info.stencil_size % info.layers != 0 || info.stencil_address >= TRACKER_ADDRESS_SIZE ||
|
info.stencil_size % info.layers != 0 || info.stencil_address >= TRACKER_ADDRESS_SIZE ||
|
||||||
info.stencil_size > TRACKER_ADDRESS_SIZE - info.stencil_address ||
|
info.stencil_size > TRACKER_ADDRESS_SIZE - info.stencil_address ||
|
||||||
(info.stencil_address & 0xffffu) != 0 ||
|
(info.stencil_address & 0xffffu) != 0 ||
|
||||||
PageOverlaps(info.address, info.size, info.stencil_address, info.stencil_size))) ||
|
ImagePageRangesOverlap(info.address, info.size, info.stencil_address,
|
||||||
|
info.stencil_size))) ||
|
||||||
((info.htile_address == 0) != (info.htile_size == 0)) ||
|
((info.htile_address == 0) != (info.htile_size == 0)) ||
|
||||||
(has_htile &&
|
(has_htile &&
|
||||||
(info.htile_size % info.layers != 0 || info.htile_address >= TRACKER_ADDRESS_SIZE ||
|
(info.htile_size % info.layers != 0 || info.htile_address >= TRACKER_ADDRESS_SIZE ||
|
||||||
info.htile_size > TRACKER_ADDRESS_SIZE - info.htile_address ||
|
info.htile_size > TRACKER_ADDRESS_SIZE - info.htile_address ||
|
||||||
(info.htile_address & 0x7fffu) != 0 ||
|
(info.htile_address & 0x7fffu) != 0 ||
|
||||||
PageOverlaps(info.address, info.size, info.htile_address, info.htile_size) ||
|
ImagePageRangesOverlap(info.address, info.size, info.htile_address, info.htile_size) ||
|
||||||
(has_stencil && PageOverlaps(info.stencil_address, info.stencil_size, info.htile_address,
|
(has_stencil && ImagePageRangesOverlap(info.stencil_address, info.stencil_size,
|
||||||
info.htile_size)))) ||
|
info.htile_address, info.htile_size)))) ||
|
||||||
(info.stencil_htile_compressed && (!has_stencil || !has_htile)) ||
|
(info.stencil_htile_compressed && (!has_stencil || !has_htile)) ||
|
||||||
!IsSupportedDepthTargetFormat(info)) {
|
!IsSupportedDepthTargetFormat(info)) {
|
||||||
EXIT("TextureCache: unsupported depth target, command=%p ctx=%p depth=0x%016" PRIx64
|
EXIT("TextureCache: unsupported depth target, command=%p ctx=%p depth=0x%016" PRIx64
|
||||||
@@ -2579,7 +2663,8 @@ TextureCache::RegisterVideoOutSurfaces(GraphicContext* ctx,
|
|||||||
}
|
}
|
||||||
for (size_t i = 0; i < infos.size(); i++) {
|
for (size_t i = 0; i < infos.size(); i++) {
|
||||||
for (size_t j = i + 1; j < infos.size(); j++) {
|
for (size_t j = i + 1; j < infos.size(); j++) {
|
||||||
if (PageOverlaps(infos[i].address, infos[i].size, infos[j].address, infos[j].size)) {
|
if (ImagePageRangesOverlap(infos[i].address, infos[i].size, infos[j].address,
|
||||||
|
infos[j].size)) {
|
||||||
EXIT("TextureCache: video-out surfaces share pages, first=%zu second=%zu\n", i, j);
|
EXIT("TextureCache: video-out surfaces share pages, first=%zu second=%zu\n", i, j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3277,7 +3362,7 @@ RenderTextureVulkanImage* TextureCache::FindRenderTargetByRange(CommandBuffer* c
|
|||||||
std::shared_ptr<CachedImage> found;
|
std::shared_ptr<CachedImage> found;
|
||||||
for (auto& cached: m_images) {
|
for (auto& cached: m_images) {
|
||||||
if (cached->kind != CachedImage::Kind::RenderTarget ||
|
if (cached->kind != CachedImage::Kind::RenderTarget ||
|
||||||
!Overlaps(vaddr, size, cached->Address(), cached->Size())) {
|
!ImageRangeOverlaps(vaddr, size, cached->Address(), cached->Size())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const auto slice_size =
|
const auto slice_size =
|
||||||
@@ -3407,7 +3492,8 @@ void TextureCache::RegisterMeta(uint64_t vaddr, uint64_t size, uint32_t layers)
|
|||||||
range_size -= existing->second.size;
|
range_size -= existing->second.size;
|
||||||
}
|
}
|
||||||
for (const auto& [address, meta]: m_surface_metas) {
|
for (const auto& [address, meta]: m_surface_metas) {
|
||||||
if (address != vaddr && PageOverlaps(range_vaddr, range_size, address, meta.size)) {
|
if (address != vaddr &&
|
||||||
|
ImagePageRangesOverlap(range_vaddr, range_size, address, meta.size)) {
|
||||||
LOGF("TextureCache: registering overlapping metadata views, requested=0x%016" PRIx64
|
LOGF("TextureCache: registering overlapping metadata views, requested=0x%016" PRIx64
|
||||||
"+0x%016" PRIx64 " existing=0x%016" PRIx64 "+0x%016" PRIx64 "\n",
|
"+0x%016" PRIx64 " existing=0x%016" PRIx64 "+0x%016" PRIx64 "\n",
|
||||||
range_vaddr, range_size, address, meta.size);
|
range_vaddr, range_size, address, meta.size);
|
||||||
@@ -3479,7 +3565,7 @@ bool TextureCache::HasMetaRangeOverlap(uint64_t vaddr, uint64_t size) {
|
|||||||
}
|
}
|
||||||
FaultSafeTextureLock lock(this, m_lock);
|
FaultSafeTextureLock lock(this, m_lock);
|
||||||
return std::any_of(m_surface_metas.begin(), m_surface_metas.end(), [&](const auto& entry) {
|
return std::any_of(m_surface_metas.begin(), m_surface_metas.end(), [&](const auto& entry) {
|
||||||
return Overlaps(vaddr, size, entry.first, entry.second.size);
|
return ImageRangeOverlaps(vaddr, size, entry.first, entry.second.size);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3492,7 +3578,7 @@ bool TextureCache::HasMetaOverlap(uint64_t vaddr, uint64_t size) {
|
|||||||
}
|
}
|
||||||
FaultSafeTextureLock lock(this, m_lock);
|
FaultSafeTextureLock lock(this, m_lock);
|
||||||
for (const auto& [address, meta]: m_surface_metas) {
|
for (const auto& [address, meta]: m_surface_metas) {
|
||||||
if (PageOverlaps(vaddr, size, address, meta.size)) {
|
if (ImagePageRangesOverlap(vaddr, size, address, meta.size)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3508,7 +3594,7 @@ bool TextureCache::IsMetaGpuModified(uint64_t vaddr, uint64_t size) {
|
|||||||
}
|
}
|
||||||
FaultSafeTextureLock lock(this, m_lock);
|
FaultSafeTextureLock lock(this, m_lock);
|
||||||
for (const auto& [address, meta]: m_surface_metas) {
|
for (const auto& [address, meta]: m_surface_metas) {
|
||||||
if (Overlaps(vaddr, size, address, meta.size) &&
|
if (ImageRangeOverlaps(vaddr, size, address, meta.size) &&
|
||||||
m_metadata_tracker.IsRegionGpuModified(vaddr, size)) {
|
m_metadata_tracker.IsRegionGpuModified(vaddr, size)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -3518,7 +3604,7 @@ bool TextureCache::IsMetaGpuModified(uint64_t vaddr, uint64_t size) {
|
|||||||
|
|
||||||
bool TextureCache::HasMetaOverlapLocked(uint64_t vaddr, uint64_t size) const {
|
bool TextureCache::HasMetaOverlapLocked(uint64_t vaddr, uint64_t size) const {
|
||||||
for (const auto& [address, meta]: m_surface_metas) {
|
for (const auto& [address, meta]: m_surface_metas) {
|
||||||
if (PageOverlaps(vaddr, size, address, meta.size)) {
|
if (ImagePageRangesOverlap(vaddr, size, address, meta.size)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3686,7 +3772,7 @@ void TextureCache::UnmapMemory(uint64_t vaddr, uint64_t size) {
|
|||||||
FaultSafeTextureLock lock(this, m_lock);
|
FaultSafeTextureLock lock(this, m_lock);
|
||||||
const auto end = vaddr + size;
|
const auto end = vaddr + size;
|
||||||
for (const auto& [address, meta]: m_surface_metas) {
|
for (const auto& [address, meta]: m_surface_metas) {
|
||||||
if (PageOverlaps(vaddr, size, address, meta.size) &&
|
if (ImagePageRangesOverlap(vaddr, size, address, meta.size) &&
|
||||||
(vaddr > address || end < address + meta.size)) {
|
(vaddr > address || end < address + meta.size)) {
|
||||||
EXIT("TextureCache: partial metadata unmap is unsupported, unmap=0x%016" PRIx64
|
EXIT("TextureCache: partial metadata unmap is unsupported, unmap=0x%016" PRIx64
|
||||||
"+0x%016" PRIx64 " metadata=0x%016" PRIx64 "+0x%016" PRIx64 "\n",
|
"+0x%016" PRIx64 " metadata=0x%016" PRIx64 "+0x%016" PRIx64 "\n",
|
||||||
@@ -3695,7 +3781,7 @@ void TextureCache::UnmapMemory(uint64_t vaddr, uint64_t size) {
|
|||||||
}
|
}
|
||||||
for (const auto& cached: m_images) {
|
for (const auto& cached: m_images) {
|
||||||
for (uint32_t i = 0; i < cached->RangeCount(); i++) {
|
for (uint32_t i = 0; i < cached->RangeCount(); i++) {
|
||||||
if (PageOverlaps(vaddr, size, cached->Address(i), cached->Size(i)) &&
|
if (ImagePageRangesOverlap(vaddr, size, cached->Address(i), cached->Size(i)) &&
|
||||||
(vaddr > cached->Address(i) || end < cached->Address(i) + cached->Size(i))) {
|
(vaddr > cached->Address(i) || end < cached->Address(i) + cached->Size(i))) {
|
||||||
EXIT("TextureCache: partial image unmap is unsupported, unmap=0x%016" PRIx64
|
EXIT("TextureCache: partial image unmap is unsupported, unmap=0x%016" PRIx64
|
||||||
"+0x%016" PRIx64 " image=0x%016" PRIx64 "+0x%016" PRIx64 "\n",
|
"+0x%016" PRIx64 " image=0x%016" PRIx64 "+0x%016" PRIx64 "\n",
|
||||||
@@ -3749,7 +3835,7 @@ void TextureCache::UnmapMemory(uint64_t vaddr, uint64_t size) {
|
|||||||
std::vector<ImageRetirementRange> metadata_ranges;
|
std::vector<ImageRetirementRange> metadata_ranges;
|
||||||
metadata_ranges.reserve(m_surface_metas.size());
|
metadata_ranges.reserve(m_surface_metas.size());
|
||||||
for (const auto& [address, meta]: m_surface_metas) {
|
for (const auto& [address, meta]: m_surface_metas) {
|
||||||
const bool retiring = Overlaps(vaddr, size, address, meta.size) ||
|
const bool retiring = ImageRangeOverlaps(vaddr, size, address, meta.size) ||
|
||||||
std::find(retire_depth_metadata.begin(), retire_depth_metadata.end(),
|
std::find(retire_depth_metadata.begin(), retire_depth_metadata.end(),
|
||||||
address) != retire_depth_metadata.end();
|
address) != retire_depth_metadata.end();
|
||||||
metadata_ranges.push_back({address, meta.size, retiring});
|
metadata_ranges.push_back({address, meta.size, retiring});
|
||||||
@@ -3794,7 +3880,8 @@ void TextureCache::UnmapMemory(uint64_t vaddr, uint64_t size) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto it = m_surface_metas.begin(); it != m_surface_metas.end();) {
|
for (auto it = m_surface_metas.begin(); it != m_surface_metas.end();) {
|
||||||
const bool allocation_unmapped = Overlaps(vaddr, size, it->first, it->second.size);
|
const bool allocation_unmapped =
|
||||||
|
ImageRangeOverlaps(vaddr, size, it->first, it->second.size);
|
||||||
const bool depth_owner_retired =
|
const bool depth_owner_retired =
|
||||||
std::find(retire_depth_metadata.begin(), retire_depth_metadata.end(), it->first) !=
|
std::find(retire_depth_metadata.begin(), retire_depth_metadata.end(), it->first) !=
|
||||||
retire_depth_metadata.end();
|
retire_depth_metadata.end();
|
||||||
|
|||||||
Reference in New Issue
Block a user