mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-07-11 01:25:07 +02:00
Unify UpdateCurrentClut between D3D11 and Vulkan (GLES is still different)
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "ext/xxhash.h"
|
||||
#include "Common/Common.h"
|
||||
#include "Common/Data/Convert/ColorConv.h"
|
||||
#include "Common/Data/Collections/TinySet.h"
|
||||
@@ -369,6 +370,43 @@ SamplerCacheKey TextureCacheCommon::GetFramebufferSamplingParams(u16 bufferWidth
|
||||
return key;
|
||||
}
|
||||
|
||||
// NOTE: this is overridden in TextureCacheGLES, with some extra color conversion.
|
||||
void TextureCacheCommon::UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase, bool clutIndexIsSimple) {
|
||||
const u32 clutBaseBytes = clutFormat == GE_CMODE_32BIT_ABGR8888 ? (clutBase * sizeof(u32)) : (clutBase * sizeof(u16));
|
||||
// Technically, these extra bytes weren't loaded, but hopefully it was loaded earlier.
|
||||
// If not, we're going to hash random data, which hopefully doesn't cause a performance issue.
|
||||
//
|
||||
// TODO: Actually, this seems like a hack. The game can upload part of a CLUT and reference other data.
|
||||
// clutTotalBytes_ is the last amount uploaded. We should hash clutMaxBytes_, but this will often hash
|
||||
// unrelated old entries for small palettes.
|
||||
// Adding clutBaseBytes may just be mitigating this for some usage patterns.
|
||||
const u32 clutExtendedBytes = std::min(clutTotalBytes_ + clutBaseBytes, clutMaxBytes_);
|
||||
|
||||
if (replacer_.Enabled())
|
||||
clutHash_ = XXH32((const char *)clutBufRaw_, clutExtendedBytes, 0xC0108888);
|
||||
else
|
||||
clutHash_ = XXH3_64bits((const char *)clutBufRaw_, clutExtendedBytes) & 0xFFFFFFFF;
|
||||
clutBuf_ = clutBufRaw_;
|
||||
|
||||
// Special optimization: fonts typically draw clut4 with just alpha values in a single color.
|
||||
clutAlphaLinear_ = false;
|
||||
clutAlphaLinearColor_ = 0;
|
||||
if (clutFormat == GE_CMODE_16BIT_ABGR4444 && clutIndexIsSimple) {
|
||||
const u16_le *clut = GetCurrentClut<u16_le>();
|
||||
clutAlphaLinear_ = true;
|
||||
clutAlphaLinearColor_ = clut[15] & 0x0FFF;
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
u16 step = clutAlphaLinearColor_ | (i << 12);
|
||||
if (clut[i] != step) {
|
||||
clutAlphaLinear_ = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clutLastFormat_ = gstate.clutformat;
|
||||
}
|
||||
|
||||
// TODO: This should be called from the through mode bbox check.
|
||||
void TextureCacheCommon::UpdateMaxSeenV(TexCacheEntry *entry, bool throughMode) {
|
||||
// If the texture is >= 512 pixels tall...
|
||||
|
||||
@@ -400,7 +400,7 @@ protected:
|
||||
|
||||
void HandleTextureChange(TexCacheEntry *const entry, const char *reason, bool initialMatch, bool doDelete);
|
||||
virtual void BuildTexture(TexCacheEntry *const entry) = 0;
|
||||
virtual void UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase, bool clutIndexIsSimple) = 0;
|
||||
virtual void UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase, bool clutIndexIsSimple); // only overridden in GLES
|
||||
bool CheckFullHash(TexCacheEntry *entry, bool &doDelete);
|
||||
|
||||
virtual void BindAsClutTexture(Draw::Texture *tex, bool smooth) {}
|
||||
|
||||
@@ -209,42 +209,6 @@ void TextureCacheD3D11::ForgetLastTexture() {
|
||||
context_->PSSetShaderResources(0, 4, nullTex);
|
||||
}
|
||||
|
||||
void TextureCacheD3D11::UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase, bool clutIndexIsSimple) {
|
||||
const u32 clutBaseBytes = clutBase * (clutFormat == GE_CMODE_32BIT_ABGR8888 ? sizeof(u32) : sizeof(u16));
|
||||
// Technically, these extra bytes weren't loaded, but hopefully it was loaded earlier.
|
||||
// If not, we're going to hash random data, which hopefully doesn't cause a performance issue.
|
||||
//
|
||||
// TODO: Actually, this seems like a hack. The game can upload part of a CLUT and reference other data.
|
||||
// clutTotalBytes_ is the last amount uploaded. We should hash clutMaxBytes_, but this will often hash
|
||||
// unrelated old entries for small palettes.
|
||||
// Adding clutBaseBytes may just be mitigating this for some usage patterns.
|
||||
const u32 clutExtendedBytes = std::min(clutTotalBytes_ + clutBaseBytes, clutMaxBytes_);
|
||||
|
||||
if (replacer_.Enabled())
|
||||
clutHash_ = XXH32((const char *)clutBufRaw_, clutExtendedBytes, 0xC0108888);
|
||||
else
|
||||
clutHash_ = XXH3_64bits((const char *)clutBufRaw_, clutExtendedBytes) & 0xFFFFFFFF;
|
||||
clutBuf_ = clutBufRaw_;
|
||||
|
||||
// Special optimization: fonts typically draw clut4 with just alpha values in a single color.
|
||||
clutAlphaLinear_ = false;
|
||||
clutAlphaLinearColor_ = 0;
|
||||
if (clutFormat == GE_CMODE_16BIT_ABGR4444 && clutIndexIsSimple) {
|
||||
const u16_le *clut = GetCurrentClut<u16_le>();
|
||||
clutAlphaLinear_ = true;
|
||||
clutAlphaLinearColor_ = clut[15] & 0x0FFF;
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
u16 step = clutAlphaLinearColor_ | (i << 12);
|
||||
if (clut[i] != step) {
|
||||
clutAlphaLinear_ = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clutLastFormat_ = gstate.clutformat;
|
||||
}
|
||||
|
||||
void TextureCacheD3D11::BindTexture(TexCacheEntry *entry, bool flatZ) {
|
||||
if (!entry) {
|
||||
ID3D11ShaderResourceView *textureView = nullptr;
|
||||
|
||||
@@ -73,7 +73,6 @@ protected:
|
||||
|
||||
private:
|
||||
DXGI_FORMAT GetDestFormat(GETextureFormat format, GEPaletteFormat clutFormat) const;
|
||||
void UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase, bool clutIndexIsSimple) override;
|
||||
|
||||
void BuildTexture(TexCacheEntry *const entry) override;
|
||||
|
||||
|
||||
@@ -147,6 +147,7 @@ void TextureCacheGLES::StartFrame() {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: This is almost the same as the Common one, just with some extra color conversion. Should merge.
|
||||
void TextureCacheGLES::UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase, bool clutIndexIsSimple) {
|
||||
const u32 clutBaseBytes = clutFormat == GE_CMODE_32BIT_ABGR8888 ? (clutBase * sizeof(u32)) : (clutBase * sizeof(u16));
|
||||
// Technically, these extra bytes weren't loaded, but hopefully it was loaded earlier.
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
|
||||
#include "ext/xxhash.h"
|
||||
|
||||
#include "Common/File/VFS/VFS.h"
|
||||
#include "Common/Data/Text/I18n.h"
|
||||
#include "Common/LogReporting.h"
|
||||
@@ -582,42 +580,6 @@ void TextureCacheVulkan::StartFrame() {
|
||||
computeShaderManager_.BeginFrame();
|
||||
}
|
||||
|
||||
void TextureCacheVulkan::UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase, bool clutIndexIsSimple) {
|
||||
const u32 clutBaseBytes = clutFormat == GE_CMODE_32BIT_ABGR8888 ? (clutBase * sizeof(u32)) : (clutBase * sizeof(u16));
|
||||
// Technically, these extra bytes weren't loaded, but hopefully it was loaded earlier.
|
||||
// If not, we're going to hash random data, which hopefully doesn't cause a performance issue.
|
||||
//
|
||||
// TODO: Actually, this seems like a hack. The game can upload part of a CLUT and reference other data.
|
||||
// clutTotalBytes_ is the last amount uploaded. We should hash clutMaxBytes_, but this will often hash
|
||||
// unrelated old entries for small palettes.
|
||||
// Adding clutBaseBytes may just be mitigating this for some usage patterns.
|
||||
const u32 clutExtendedBytes = std::min(clutTotalBytes_ + clutBaseBytes, clutMaxBytes_);
|
||||
|
||||
if (replacer_.Enabled())
|
||||
clutHash_ = XXH32((const char *)clutBufRaw_, clutExtendedBytes, 0xC0108888);
|
||||
else
|
||||
clutHash_ = XXH3_64bits((const char *)clutBufRaw_, clutExtendedBytes) & 0xFFFFFFFF;
|
||||
clutBuf_ = clutBufRaw_;
|
||||
|
||||
// Special optimization: fonts typically draw clut4 with just alpha values in a single color.
|
||||
clutAlphaLinear_ = false;
|
||||
clutAlphaLinearColor_ = 0;
|
||||
if (clutFormat == GE_CMODE_16BIT_ABGR4444 && clutIndexIsSimple) {
|
||||
const u16_le *clut = GetCurrentClut<u16_le>();
|
||||
clutAlphaLinear_ = true;
|
||||
clutAlphaLinearColor_ = clut[15] & 0x0FFF;
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
u16 step = clutAlphaLinearColor_ | (i << 12);
|
||||
if (clut[i] != step) {
|
||||
clutAlphaLinear_ = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clutLastFormat_ = gstate.clutformat;
|
||||
}
|
||||
|
||||
void TextureCacheVulkan::BindTexture(TexCacheEntry *entry, bool flatZ) {
|
||||
if (!entry || !entry->vkTex) {
|
||||
Unbind();
|
||||
|
||||
@@ -118,7 +118,6 @@ private:
|
||||
|
||||
void LoadVulkanTextureLevel(TexCacheEntry &entry, uint8_t *writePtr, int rowPitch, int level, int scaleFactor, VkFormat dstFmt);
|
||||
static VkFormat GetDestFormat(GETextureFormat format, GEPaletteFormat clutFormat) ;
|
||||
void UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase, bool clutIndexIsSimple) override;
|
||||
|
||||
void BuildTexture(TexCacheEntry *const entry) override;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user