Merge pull request #1865 from fisherjoey/perf/texture-key-ignore-feedback

perf(agc): key sampled textures without the streaming-feedback fields
This commit is contained in:
Dean 2026-10-10 17:16:09 +13:00 committed by GitHub
commit ecc2c8b486
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 32 additions and 0 deletions

View File

@ -37,6 +37,7 @@ struct TextureCacheUse {
TextureCacheUse TextureCacheUsage();
std::uint64_t SampledTextureCacheBudget(const Context& context);
std::shared_ptr<Texture> CachedSampledTexture(const Context& context, std::span<const std::uint32_t> words);
bool SampledTexturesShareEntry(std::span<const std::uint32_t> first, std::span<const std::uint32_t> second);
// The cached storage image of a surface (render targets use it as their resident image); brought up
// to date with guest memory before it is returned.

View File

@ -83,6 +83,8 @@ TextureKey MakeTextureKey(VkDevice device, std::span<const std::uint32_t> words,
TextureKey key{device, {}, {static_cast<std::uint32_t>(components.r), static_cast<std::uint32_t>(components.g), static_cast<std::uint32_t>(components.b), static_cast<std::uint32_t>(components.a)}};
key.depthCompare = depthCompare;
std::copy(words.begin(), words.end(), key.words.begin());
key.words[5] &= ~((0xfffu << 8u) | (1u << 25u));
key.words[6] &= ~0xffu;
return key;
}
@ -778,6 +780,14 @@ std::shared_ptr<Texture> CachedSampledTexture(const Context& context, std::span<
return cachedTexture(context, words, resource, ViewComponents(resource));
}
bool SampledTexturesShareEntry(std::span<const std::uint32_t> first, std::span<const std::uint32_t> second) {
Require(first.size() == 8 && second.size() == 8, "sampled texture keys take eight descriptor words");
const VkComponentMapping components{VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
const auto firstKey = MakeTextureKey(VK_NULL_HANDLE, first, components);
const auto secondKey = MakeTextureKey(VK_NULL_HANDLE, second, components);
return firstKey == secondKey && TextureKeyHash{}(firstKey) == TextureKeyHash{}(secondKey);
}
void FlushCachedTextures(VkDevice device) {
Require(device != VK_NULL_HANDLE, "cannot flush textures without a Vulkan device");
GuestMemory::AssertGpuLockHeld("FlushCachedTextures");

View File

@ -1,6 +1,7 @@
#include "GraphicsTests.hpp"
#include "prx/libSceAgcDriver/Graphics/include/DccMetadata.hpp"
#include "prx/libSceAgcDriver/Graphics/include/GuestTextureResource.hpp"
#include "prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp"
#include "prx/libSceAgcDriver/Graphics/include/TextureTiling.hpp"
#include <algorithm>
#include <array>
@ -408,4 +409,24 @@ void RunGuestTextureResourceTests() {
Require(!MatchesGuestDimension(Shape::Image3D, TextureDimension::k2D), "3D shape must never match a guest dimension");
Require(!MatchesGuestDimension(Shape::Image3D, TextureDimension::k2DArray), "3D shape must never match a guest dimension");
Require(!MatchesGuestDimension(Shape::Image3D, TextureDimension::kCube), "3D shape must never match a guest dimension");
Fields streamed = base;
streamed.minLodWarn = 0xabc;
streamed.mipStatsCntEn = true;
streamed.mipStatsCntId = 0x5a;
Require(SampledTexturesShareEntry(pack(base), pack(streamed)), "T#s differing only in MIN_LOD_WARN, MIP_STATS_COUNTER_EN and MIP_STATS_COUNTER_ID must share a sampled texture entry");
for (const auto& field : {&Fields::minLodWarn, &Fields::mipStatsCntId}) {
Fields one = base;
one.*field = 1;
Require(SampledTexturesShareEntry(pack(base), pack(one)), "a T# differing in one streaming-feedback field must share a sampled texture entry");
}
Fields moved = streamed;
moved.base40 = base.base40 + 1;
Require(!SampledTexturesShareEntry(pack(base), pack(moved)), "T#s with different base addresses must not share a sampled texture entry");
Fields reformatted = streamed;
reformatted.format = 57;
Require(!SampledTexturesShareEntry(pack(base), pack(reformatted)), "T#s with different formats must not share a sampled texture entry");
Fields cornered = base;
cornered.cornerSample = true;
Require(!SampledTexturesShareEntry(pack(base), pack(cornered)), "T#s differing in a field next to the feedback fields must not share a sampled texture entry");
}