fix: fix texture caching

feat: wip multi version on dbcman
This commit is contained in:
Ran-j
2026-09-14 02:11:06 -03:00
parent 590b884ba4
commit 78ecbae377
25 changed files with 1778 additions and 117 deletions
@@ -1,9 +1,9 @@
#pragma once
#include "runtime/gs/gs_backend.h"
#include "runtime/gs/gs_texture_page_cache.h"
#include <array>
#include <functional>
#include <mutex>
#include <vector>
@@ -61,8 +61,8 @@ private:
uint32_t sourceOriginX,
uint32_t sourceOriginY) const;
using WriteVramFunc = std::function<void(uint8_t *, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t)>;
using ReadVramFunc = std::function<uint32_t(uint8_t *, uint32_t, uint32_t, uint32_t, uint32_t)>;
using WriteVramFunc = void (*)(uint8_t *, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t);
using ReadVramFunc = uint32_t (*)(uint8_t *, uint32_t, uint32_t, uint32_t, uint32_t);
static constexpr size_t kPsmHandlerCount = 1u << 6u;
mutable std::mutex m_mutex;
@@ -72,8 +72,7 @@ private:
std::array<WriteVramFunc, kPsmHandlerCount> m_writeVramFuncs{};
std::array<uint16_t, 512> m_clut{};
std::array<uint32_t, 2> m_clutCbp{};
std::vector<uint8_t> m_texturePageBuffer;
uint32_t m_texturePageIndex = UINT32_MAX;
GSMem::TexturePageCache m_texturePageCache;
GSTransferCommand m_transfer{};
GSTransferSnapshot m_transferState{};
@@ -0,0 +1,37 @@
#pragma once
#include <array>
#include <cstddef>
#include <cstdint>
#include <cstring>
namespace GSMem
{
class TexturePageCache
{
public:
static constexpr uint32_t kPageSize = 8192u;
void Invalidate() noexcept
{
m_pageBase = UINT32_MAX;
}
// byteAddress is the wrapped, swizzled VRAM address. The returned
// pointer is valid only until the next miss or invalidation.
const uint8_t* Resolve(const uint8_t* vram, uint32_t byteAddress) noexcept
{
const uint32_t pageBase = byteAddress & ~(kPageSize - 1u);
if (m_pageBase != pageBase)
{
std::memcpy(m_bytes.data(), vram + pageBase, kPageSize);
m_pageBase = pageBase;
}
return m_bytes.data() + (byteAddress & (kPageSize - 1u));
}
private:
alignas(64) std::array<uint8_t, kPageSize> m_bytes{};
uint32_t m_pageBase = UINT32_MAX;
};
}
+10 -5
View File
@@ -7,11 +7,12 @@
#include <span>
#include "types.h"
#include "runtime/gs/gs_texture_page_cache.h"
namespace GSMem
{
constexpr usz MEMORY_SIZE = 4_mb;
constexpr usz GS_PAGE_SIZE = 8_kb;
constexpr usz GS_PAGE_SIZE = TexturePageCache::kPageSize;
// these are all the same regardless of storage mode
constexpr usz BLOCKS_PER_PAGE = 32;
@@ -261,7 +262,7 @@ namespace GSMem
static constexpr void Write(const PageLookupTableT& table, u8* data, u32 block, u32 bw, u32 x, u32 y, PackedT value);
// reads the pixel
static constexpr auto Read(const PageLookupTableT& table, u8* data, u32 block, u32 bw, u32 x, u32 y) -> PackedT;
static constexpr auto Read(const PageLookupTableT& table, const u8* data, u32 block, u32 bw, u32 x, u32 y, TexturePageCache* cache = nullptr) -> PackedT;
static_assert(BlocksPerPage() == BLOCKS_PER_PAGE);
static_assert(IsValidPsm(psm));
@@ -501,15 +502,16 @@ namespace GSMem
}
template<PixelStorageMode psm>
constexpr auto PixelStorageTraits<psm>::Read(const PageLookupTableT& table, u8* data, u32 block, u32 bw, u32 x, u32 y) -> PackedT
constexpr auto PixelStorageTraits<psm>::Read(const PageLookupTableT& table, const u8* data, u32 block, u32 bw, u32 x, u32 y, TexturePageCache* cache) -> PackedT
{
const u32 pixel_addr = Address(table, block, bw, x, y);
const u32 bits = pixel_addr * UnpackedBitWidth(psm) + BitOffset();
const u32 byte_addr = (bits / 8) & (MEMORY_SIZE - sizeof(PackedT));
const u32 shift = bits % 8;
const u8* source = cache ? cache->Resolve(data, byte_addr) : data + byte_addr;
PackedT v;
std::memcpy(&v, &data[byte_addr], sizeof(PackedT));
std::memcpy(&v, source, sizeof(PackedT));
switch (psm)
{
@@ -533,11 +535,14 @@ namespace GSMem
break;
}
return 0xFFFF00FFu;
return static_cast<PackedT>(0xFFFF00FFu);
}
void InitLookupTables();
// Shares swizzle, VRAM wrapping, and lane extraction with the direct reads.
u32 ReadTexture(TexturePageCache& cache, const u8* data, u32 psm, u32 bp, u32 bw, u32 x, u32 y);
void WriteCT32(u8* data, u32 bp, u32 bw, u32 x, u32 y, u32 value);
void WriteZ32(u8* data, u32 bp, u32 bw, u32 x, u32 y, u32 value);