Fix render-texture cache lookups

`[32bit loc | 32bit attributes]`
Use `std::map::lower_bound(loc << 32)` to find the first address that matches the key in O(logn) time, finer grained searchs can happen after the fact in O(n) time.

Fixes render-texture cache lookups
This commit is contained in:
Wunkolo 2023-08-24 10:39:53 -07:00
parent be5ebeefed
commit d781802eb0
2 changed files with 14 additions and 18 deletions

View file

@ -76,9 +76,6 @@ class RendererVK final : public Renderer {
// Hash(loc, size, format) -> Texture // Hash(loc, size, format) -> Texture
std::map<u64, Texture> textureCache; std::map<u64, Texture> textureCache;
static u32 colorBufferHash(u32 loc, u32 size, PICA::ColorFmt format);
static u32 depthBufferHash(u32 loc, u32 size, PICA::DepthFmt format);
Texture* findColorRenderTexture(u32 addr); Texture* findColorRenderTexture(u32 addr);
Texture& getColorRenderTexture(u32 addr, PICA::ColorFmt format, u32 width, u32 height); Texture& getColorRenderTexture(u32 addr, PICA::ColorFmt format, u32 width, u32 height);
Texture& getDepthRenderTexture(u32 addr, PICA::DepthFmt format, u32 width, u32 height); Texture& getDepthRenderTexture(u32 addr, PICA::DepthFmt format, u32 width, u32 height);

View file

@ -224,30 +224,29 @@ static s32 findQueueFamily(
static u32 rotl32(u32 x, u32 n) { return (x << n) | (x >> (32 - n)); } static u32 rotl32(u32 x, u32 n) { return (x << n) | (x >> (32 - n)); }
static u32 ror32(u32 x, u32 n) { return (x >> n) | (x << (32 - n)); } static u32 ror32(u32 x, u32 n) { return (x >> n) | (x << (32 - n)); }
u32 RendererVK::colorBufferHash(u32 loc, u32 size, PICA::ColorFmt format) { // Lower 32 bits is the format + size, upper 32-bits is the address
return loc | (static_cast<u64>(ror32(size, 23) ^ (static_cast<u32>(format))) << 32); static u64 colorBufferHash(u32 loc, u32 size, PICA::ColorFmt format) {
return (static_cast<u64>(loc) << 32) | (ror32(size, 23) ^ static_cast<u32>(format));
} }
u32 RendererVK::depthBufferHash(u32 loc, u32 size, PICA::DepthFmt format) { static u64 depthBufferHash(u32 loc, u32 size, PICA::DepthFmt format) {
return loc | (static_cast<u64>(ror32(size, 29) ^ (static_cast<u32>(format))) << 32); return (static_cast<u64>(loc) << 32) | (ror32(size, 29) ^ static_cast<u32>(format));
} }
RendererVK::Texture* RendererVK::findColorRenderTexture(u32 addr) { RendererVK::Texture* RendererVK::findColorRenderTexture(u32 addr) {
const auto lower = textureCache.lower_bound(addr); // Find first render-texture hash that is >= to addr
auto match = textureCache.lower_bound(static_cast<u64>(addr) << 32);
if (lower == textureCache.end()) { if (match == textureCache.end()) {
// Not found // Not found
return nullptr; return nullptr;
} }
if (lower == textureCache.begin()) { Texture* texture = &match->second;
return &lower->second;
}
Texture* texture = &lower->second;
const usize sizeInBytes = texture->size[0] * texture->size[1] * texture->sizePerPixel; const usize sizeInBytes = texture->size[0] * texture->size[1] * texture->sizePerPixel;
if ((addr - lower->second.loc) <= sizeInBytes) { // Ensure this address is within the span of the texture
if ((addr - match->second.loc) <= sizeInBytes) {
return texture; return texture;
} }
@ -672,7 +671,7 @@ void RendererVK::display() {
const u32 bottomScreenAddr = const u32 bottomScreenAddr =
externalRegs[bottomActiveFb ? PICA::ExternalRegs::Framebuffer1AFirstAddr : PICA::ExternalRegs::Framebuffer1ASecondAddr]; externalRegs[bottomActiveFb ? PICA::ExternalRegs::Framebuffer1AFirstAddr : PICA::ExternalRegs::Framebuffer1ASecondAddr];
//// Render Frame(Simulated - just clear the images to different colors for now) //// Render Display
{ {
static const std::array<float, 4> renderScreenScopeColor = {{1.0f, 0.0f, 1.0f, 1.0f}}; static const std::array<float, 4> renderScreenScopeColor = {{1.0f, 0.0f, 1.0f, 1.0f}};
@ -688,7 +687,7 @@ void RendererVK::display() {
getCurrentCommandBuffer().beginRenderPass(renderPassBeginInfo, vk::SubpassContents::eInline); getCurrentCommandBuffer().beginRenderPass(renderPassBeginInfo, vk::SubpassContents::eInline);
// Render top screen // Render top screen
if (Texture* topScreen = findColorRenderTexture(topScreenAddr); topScreen) { if (const Texture* topScreen = findColorRenderTexture(topScreenAddr); topScreen) {
descriptorUpdateBatch->addImageSampler( descriptorUpdateBatch->addImageSampler(
topDisplayPipelineDescriptorSet[frameBufferingIndex], 0, topScreen->imageView.get(), samplerCache->getSampler(sampler2D()) topDisplayPipelineDescriptorSet[frameBufferingIndex], 0, topScreen->imageView.get(), samplerCache->getSampler(sampler2D())
); );
@ -702,7 +701,7 @@ void RendererVK::display() {
} }
// Render bottom screen // Render bottom screen
if (Texture* bottomScreen = findColorRenderTexture(bottomScreenAddr); bottomScreen) { if (const Texture* bottomScreen = findColorRenderTexture(bottomScreenAddr); bottomScreen) {
descriptorUpdateBatch->addImageSampler( descriptorUpdateBatch->addImageSampler(
bottomDisplayPipelineDescriptorSet[frameBufferingIndex], 0, bottomScreen->imageView.get(), samplerCache->getSampler(sampler2D()) bottomDisplayPipelineDescriptorSet[frameBufferingIndex], 0, bottomScreen->imageView.get(), samplerCache->getSampler(sampler2D())
); );