From d781802eb05d961519540b42d9314ff7b4800c44 Mon Sep 17 00:00:00 2001 From: Wunkolo Date: Thu, 24 Aug 2023 10:39:53 -0700 Subject: [PATCH] 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 --- include/renderer_vk/renderer_vk.hpp | 3 --- src/core/renderer_vk/renderer_vk.cpp | 29 ++++++++++++++-------------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/include/renderer_vk/renderer_vk.hpp b/include/renderer_vk/renderer_vk.hpp index bae27f3c..51b84971 100644 --- a/include/renderer_vk/renderer_vk.hpp +++ b/include/renderer_vk/renderer_vk.hpp @@ -76,9 +76,6 @@ class RendererVK final : public Renderer { // Hash(loc, size, format) -> Texture std::map 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& getColorRenderTexture(u32 addr, PICA::ColorFmt format, u32 width, u32 height); Texture& getDepthRenderTexture(u32 addr, PICA::DepthFmt format, u32 width, u32 height); diff --git a/src/core/renderer_vk/renderer_vk.cpp b/src/core/renderer_vk/renderer_vk.cpp index 1fc39f7d..ed7fc41e 100644 --- a/src/core/renderer_vk/renderer_vk.cpp +++ b/src/core/renderer_vk/renderer_vk.cpp @@ -224,30 +224,29 @@ static s32 findQueueFamily( 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)); } -u32 RendererVK::colorBufferHash(u32 loc, u32 size, PICA::ColorFmt format) { - return loc | (static_cast(ror32(size, 23) ^ (static_cast(format))) << 32); +// Lower 32 bits is the format + size, upper 32-bits is the address +static u64 colorBufferHash(u32 loc, u32 size, PICA::ColorFmt format) { + return (static_cast(loc) << 32) | (ror32(size, 23) ^ static_cast(format)); } -u32 RendererVK::depthBufferHash(u32 loc, u32 size, PICA::DepthFmt format) { - return loc | (static_cast(ror32(size, 29) ^ (static_cast(format))) << 32); +static u64 depthBufferHash(u32 loc, u32 size, PICA::DepthFmt format) { + return (static_cast(loc) << 32) | (ror32(size, 29) ^ static_cast(format)); } 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(addr) << 32); - if (lower == textureCache.end()) { + if (match == textureCache.end()) { // Not found return nullptr; } - if (lower == textureCache.begin()) { - return &lower->second; - } - - Texture* texture = &lower->second; + Texture* texture = &match->second; 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; } @@ -672,7 +671,7 @@ void RendererVK::display() { const u32 bottomScreenAddr = 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 renderScreenScopeColor = {{1.0f, 0.0f, 1.0f, 1.0f}}; @@ -688,7 +687,7 @@ void RendererVK::display() { getCurrentCommandBuffer().beginRenderPass(renderPassBeginInfo, vk::SubpassContents::eInline); // Render top screen - if (Texture* topScreen = findColorRenderTexture(topScreenAddr); topScreen) { + if (const Texture* topScreen = findColorRenderTexture(topScreenAddr); topScreen) { descriptorUpdateBatch->addImageSampler( topDisplayPipelineDescriptorSet[frameBufferingIndex], 0, topScreen->imageView.get(), samplerCache->getSampler(sampler2D()) ); @@ -702,7 +701,7 @@ void RendererVK::display() { } // Render bottom screen - if (Texture* bottomScreen = findColorRenderTexture(bottomScreenAddr); bottomScreen) { + if (const Texture* bottomScreen = findColorRenderTexture(bottomScreenAddr); bottomScreen) { descriptorUpdateBatch->addImageSampler( bottomDisplayPipelineDescriptorSet[frameBufferingIndex], 0, bottomScreen->imageView.get(), samplerCache->getSampler(sampler2D()) );