mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-11-05 13:20:11 +00:00
Merge pull request #7802 from ionut27001/fix/agc-kept-set-weak-textures
fix(agc): let a kept descriptor set's table record hold its textures weakly
This commit is contained in:
3 files changed
+28
-6
No files matched your search
@@ -72,7 +72,7 @@ struct TableDescriptors {
|
||||
std::uint32_t binding = 0;
|
||||
std::vector<std::pair<std::uint32_t, std::uint32_t>> runs;
|
||||
std::vector<VkDescriptorImageInfo> images;
|
||||
std::shared_ptr<const std::vector<std::shared_ptr<Texture>>> textures;
|
||||
std::shared_ptr<const std::vector<std::weak_ptr<Texture>>> textures;
|
||||
};
|
||||
|
||||
class DescriptorCache {
|
||||
@@ -570,7 +570,7 @@ private:
|
||||
std::vector<std::pair<std::uint32_t, std::uint32_t>> runs;
|
||||
};
|
||||
std::array<TableWrites, 2> tableWrites;
|
||||
std::shared_ptr<const TableDescriptors> keptTable(std::size_t set, std::shared_ptr<const std::vector<std::shared_ptr<Texture>>>& held) noexcept;
|
||||
std::shared_ptr<const TableDescriptors> keptTable(std::size_t set, std::shared_ptr<const std::vector<std::weak_ptr<Texture>>>& held) noexcept;
|
||||
std::uint32_t setOf(const Binding& binding) const;
|
||||
std::vector<Allocation> allocations;
|
||||
std::vector<VkDescriptorBufferInfo> descriptorBuffers;
|
||||
|
||||
@@ -2267,7 +2267,8 @@ void ShaderResources::buildComplete() {
|
||||
if (!recorded) continue;
|
||||
const auto& held = allocation.table;
|
||||
auto& counters = TextureCounts();
|
||||
if (held != nullptr && held->binding == binding.layout.binding && held->runs == runs && std::equal(held->images.begin(), held->images.end(), images.begin() + static_cast<std::ptrdiff_t>(firstImage), images.end(), [](const VkDescriptorImageInfo& a, const VkDescriptorImageInfo& b) { return a.sampler == b.sampler && a.imageView == b.imageView && a.imageLayout == b.imageLayout; })) {
|
||||
const bool heldAlive = held != nullptr && held->textures != nullptr && std::none_of(held->textures->begin(), held->textures->end(), [](const std::weak_ptr<Texture>& texture) { return texture.expired(); });
|
||||
if (heldAlive && held->binding == binding.layout.binding && held->runs == runs && std::equal(held->images.begin(), held->images.end(), images.begin() + static_cast<std::ptrdiff_t>(firstImage), images.end(), [](const VkDescriptorImageInfo& a, const VkDescriptorImageInfo& b) { return a.sampler == b.sampler && a.imageView == b.imageView && a.imageLayout == b.imageLayout; })) {
|
||||
keptWrites.emplace_back(firstWrite, writes.size());
|
||||
counters.tableWritesKept.fetch_add(1, std::memory_order_relaxed);
|
||||
} else {
|
||||
@@ -5044,11 +5045,18 @@ ShaderResources::~ShaderResources() {
|
||||
release();
|
||||
}
|
||||
|
||||
std::shared_ptr<const TableDescriptors> ShaderResources::keptTable(std::size_t set, std::shared_ptr<const std::vector<std::shared_ptr<Texture>>>& held) noexcept {
|
||||
std::shared_ptr<const TableDescriptors> ShaderResources::keptTable(std::size_t set, std::shared_ptr<const std::vector<std::weak_ptr<Texture>>>& held) noexcept {
|
||||
const auto& table = tableWrites[set];
|
||||
if (!table.written || KeptSets() == 0u || table.firstImage + table.images > descriptorImages.size()) return nullptr;
|
||||
try {
|
||||
if (held == nullptr) held = std::make_shared<const std::vector<std::shared_ptr<Texture>>>(std::move(textures));
|
||||
if (held == nullptr) {
|
||||
std::vector<std::weak_ptr<Texture>> weak;
|
||||
weak.reserve(textures.size());
|
||||
for (const auto& texture : textures) {
|
||||
if (texture != nullptr) weak.push_back(texture);
|
||||
}
|
||||
held = std::make_shared<const std::vector<std::weak_ptr<Texture>>>(std::move(weak));
|
||||
}
|
||||
auto kept = std::make_shared<TableDescriptors>();
|
||||
kept->binding = table.binding;
|
||||
kept->runs = table.runs;
|
||||
@@ -5062,7 +5070,7 @@ std::shared_ptr<const TableDescriptors> ShaderResources::keptTable(std::size_t s
|
||||
|
||||
void ShaderResources::release() noexcept {
|
||||
// A set from the cache's pool chain goes back to it; a dedicated pool dies with its set.
|
||||
std::shared_ptr<const std::vector<std::shared_ptr<Texture>>> held;
|
||||
std::shared_ptr<const std::vector<std::weak_ptr<Texture>>> held;
|
||||
if (cacheAllocation.pool && context.descriptorCache != nullptr) context.descriptorCache->Free(cacheAllocation, keptTable(0, held));
|
||||
if (pool) context.Function<PFN_vkDestroyDescriptorPool>("vkDestroyDescriptorPool")(context.device, pool, nullptr);
|
||||
if (_layout && ownsLayout) context.Function<PFN_vkDestroyDescriptorSetLayout>("vkDestroyDescriptorSetLayout")(context.device, _layout, nullptr);
|
||||
|
||||
@@ -330,6 +330,20 @@ void RunTests(AgcDriver::VulkanDevice& device, const GuestBlock& block, const Gu
|
||||
Require(Dispatch(device, result, 15) == Row(block.Texels(15)), "image table reuse: the table after a dispatch wrote an entry sampled the wrong entry");
|
||||
|
||||
RunImageStore(device, stores);
|
||||
|
||||
AgcDriver::Graphics::ReleaseTextureCaches(~std::uint64_t{0});
|
||||
Require(AgcDriver::Graphics::SampledTextureMemory() == 0u, "image table reuse: " + std::to_string(AgcDriver::Graphics::SampledTextureMemory()) + " bytes of sampled textures outlived a full release of the texture caches after the kept-table steps");
|
||||
|
||||
AgcDriver::GuestMemory::BumpCollectEpoch();
|
||||
Require(Dispatch(device, result, 29) == Row(block.Texels(29)), "image table reuse: the table before its textures were destroyed sampled the wrong entry");
|
||||
before = AgcDriver::Graphics::ImageTableReuses();
|
||||
Require(Dispatch(device, result, 29) == Row(block.Texels(29)), "image table reuse: the table built again before its textures were destroyed sampled the wrong entry");
|
||||
ExpectWrites(before, 1, 0, "a kept table built again before its textures were destroyed");
|
||||
AgcDriver::Graphics::ReleaseTextureCaches(~std::uint64_t{0});
|
||||
Require(AgcDriver::Graphics::SampledTextureMemory() == 0u, "image table reuse: " + std::to_string(AgcDriver::Graphics::SampledTextureMemory()) + " bytes of sampled textures outlived a full release of the texture caches after a table's set was kept");
|
||||
before = AgcDriver::Graphics::ImageTableReuses();
|
||||
Require(Dispatch(device, result, 29) == Row(block.Texels(29)), "image table reuse: a kept table whose textures were destroyed sampled the wrong entry");
|
||||
ExpectWrites(before, 0, 1, "a kept table whose textures were destroyed");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user