Unify the GLES LoadTextureLevel with the D3D ones.

This commit is contained in:
Henrik Rydgård 2022-07-30 19:04:12 +02:00
parent c6d7423368
commit 6a5a232777
8 changed files with 54 additions and 92 deletions

View file

@ -107,7 +107,7 @@ void ParallelRangeLoop(ThreadManager *threadMan, const std::function<void(int, i
// NOTE: Supports a max of 2GB.
void ParallelMemcpy(ThreadManager *threadMan, void *dst, const void *src, size_t bytes) {
// This threshold can probably be a lot bigger.
if (bytes < 512) {
if (true || bytes < 512) {
memcpy(dst, src, bytes);
return;
}

View file

@ -2143,10 +2143,12 @@ bool TextureCacheCommon::PrepareBuildTexture(BuildTexturePlan &plan, TexCacheEnt
return true;
}
void TextureCacheCommon::LoadTextureLevel(TexCacheEntry &entry, uint8_t *data, int stride, ReplacedTexture &replaced, int srcLevel, int scaleFactor, Draw::DataFormat dstFmt) {
void TextureCacheCommon::LoadTextureLevel(TexCacheEntry &entry, uint8_t *data, int stride, ReplacedTexture &replaced, int srcLevel, int scaleFactor, Draw::DataFormat dstFmt, bool reverseColors) {
int w = gstate.getTextureWidth(srcLevel);
int h = gstate.getTextureHeight(srcLevel);
PROFILE_THIS_SCOPE("decodetex");
if (replaced.GetSize(srcLevel, w, h)) {
double replaceStart = time_now_d();
replaced.Load(srcLevel, data, stride);
@ -2170,7 +2172,7 @@ void TextureCacheCommon::LoadTextureLevel(TexCacheEntry &entry, uint8_t *data, i
bool expand32 = !gstate_c.Supports(GPU_SUPPORTS_16BIT_FORMATS) || scaleFactor > 1;
CheckAlphaResult alphaResult = DecodeTextureLevel((u8 *)pixelData, decPitch, tfmt, clutformat, texaddr, srcLevel, bufw, false, expand32);
CheckAlphaResult alphaResult = DecodeTextureLevel((u8 *)pixelData, decPitch, tfmt, clutformat, texaddr, srcLevel, bufw, reverseColors, expand32);
entry.SetAlphaStatus(alphaResult, srcLevel);
if (scaleFactor > 1) {

View file

@ -330,7 +330,7 @@ protected:
ReplacedTexture &FindReplacement(TexCacheEntry *entry, int &w, int &h);
// Return value is mapData normally, but could be another buffer allocated with AllocateAlignedMemory.
void LoadTextureLevel(TexCacheEntry &entry, uint8_t *mapData, int mapRowPitch, ReplacedTexture &replaced, int srcLevel, int scaleFactor, Draw::DataFormat dstFmt);
void LoadTextureLevel(TexCacheEntry &entry, uint8_t *mapData, int mapRowPitch, ReplacedTexture &replaced, int srcLevel, int scaleFactor, Draw::DataFormat dstFmt, bool reverseColors);
template <typename T>
inline const T *GetCurrentClut() {

View file

@ -458,17 +458,12 @@ void TextureCacheD3D11::BuildTexture(TexCacheEntry *const entry) {
int th = plan.h;
DXGI_FORMAT dstFmt = GetDestFormat(GETextureFormat(entry->format), gstate.getClutPaletteFormat());
ID3D11ShaderResourceView *view;
ID3D11Texture2D *texture = DxTex(entry);
_assert_(texture == nullptr);
if (plan.replaced->GetSize(plan.baseLevelSrc, tw, th)) {
dstFmt = ToDXGIFormat(plan.replaced->Format(plan.baseLevelSrc));
} else {
} else if (plan.scaleFactor > 1) {
tw *= plan.scaleFactor;
th *= plan.scaleFactor;
if (plan.scaleFactor > 1) {
dstFmt = DXGI_FORMAT_B8G8R8A8_UNORM;
}
dstFmt = DXGI_FORMAT_B8G8R8A8_UNORM;
}
// We don't yet have mip generation, so clamp the number of levels to the ones we can load directly.
@ -485,6 +480,10 @@ void TextureCacheD3D11::BuildTexture(TexCacheEntry *const entry) {
desc.MipLevels = levels;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
ID3D11ShaderResourceView *view;
ID3D11Texture2D *texture = DxTex(entry);
_assert_(texture == nullptr);
ASSERT_SUCCESS(device_->CreateTexture2D(&desc, nullptr, &texture));
ASSERT_SUCCESS(device_->CreateShaderResourceView(texture, nullptr, &view));
entry->texturePtr = texture;
@ -524,7 +523,7 @@ void TextureCacheD3D11::BuildTexture(TexCacheEntry *const entry) {
return;
}
LoadTextureLevel(*entry, data, stride, *plan.replaced, srcLevel, plan.scaleFactor, texFmt);
LoadTextureLevel(*entry, data, stride, *plan.replaced, srcLevel, plan.scaleFactor, texFmt, false);
ID3D11Texture2D *texture = DxTex(entry);
context_->UpdateSubresource(texture, i, nullptr, data, stride, 0);

View file

@ -413,23 +413,21 @@ void TextureCacheDX9::BuildTexture(TexCacheEntry *const entry) {
int tw = plan.w;
int th = plan.h;
LPDIRECT3DTEXTURE9 &texture = DxTex(entry);
D3DFORMAT dstFmt = GetDestFormat(GETextureFormat(entry->format), gstate.getClutPaletteFormat());
D3DPOOL pool = D3DPOOL_DEFAULT;
int usage = D3DUSAGE_DYNAMIC;
if (plan.replaced->GetSize(plan.baseLevelSrc, tw, th)) {
dstFmt = ToD3D9Format(plan.replaced->Format(plan.baseLevelSrc));
} else {
} else if (plan.scaleFactor > 1) {
tw *= plan.scaleFactor;
th *= plan.scaleFactor;
if (plan.scaleFactor > 1) {
dstFmt = D3DFMT_A8R8G8B8;
}
dstFmt = D3DFMT_A8R8G8B8;
}
// We don't yet have mip generation, so clamp the number of levels to the ones we can load directly.
int levels = std::min(plan.levelsToCreate, plan.levelsToLoad);
LPDIRECT3DTEXTURE9 &texture = DxTex(entry);
D3DPOOL pool = D3DPOOL_DEFAULT;
int usage = D3DUSAGE_DYNAMIC;
HRESULT hr = device_->CreateTexture(tw, th, levels, usage, dstFmt, pool, &texture, NULL);
if (FAILED(hr)) {
@ -460,7 +458,7 @@ void TextureCacheDX9::BuildTexture(TexCacheEntry *const entry) {
uint8_t *data = (uint8_t *)rect.pBits;
int stride = rect.Pitch;
LoadTextureLevel(*entry, data, stride, *plan.replaced, (i == 0) ? plan.baseLevelSrc : i, plan.scaleFactor, texFmt);
LoadTextureLevel(*entry, data, stride, *plan.replaced, (i == 0) ? plan.baseLevelSrc : i, plan.scaleFactor, texFmt, false);
texture->UnlockRect(dstLevel);
}

View file

@ -445,12 +445,10 @@ void TextureCacheGLES::BuildTexture(TexCacheEntry *const entry) {
Draw::DataFormat dstFmt = GetDestFormat(GETextureFormat(entry->format), gstate.getClutPaletteFormat());
if (plan.replaced->GetSize(plan.baseLevelSrc, tw, th)) {
dstFmt = plan.replaced->Format(plan.baseLevelSrc);
} else {
} else if (plan.scaleFactor > 1) {
tw *= plan.scaleFactor;
th *= plan.scaleFactor;
if (plan.scaleFactor > 1) {
dstFmt = Draw::DataFormat::R8G8B8A8_UNORM;
}
dstFmt = Draw::DataFormat::R8G8B8A8_UNORM;
}
entry->textureName = render_->CreateTexture(GL_TEXTURE_2D, tw, tw, plan.levelsToCreate);
@ -471,18 +469,45 @@ void TextureCacheGLES::BuildTexture(TexCacheEntry *const entry) {
}
for (int i = 0; i < plan.levelsToLoad; i++) {
LoadTextureLevel(*entry, *plan.replaced, i == 0 ? plan.baseLevelSrc : i, i, plan.scaleFactor, dstFmt);
int srcLevel = i == 0 ? plan.baseLevelSrc : i;
int w = gstate.getTextureWidth(srcLevel);
int h = gstate.getTextureHeight(srcLevel);
u8 *data = nullptr;
int stride = 0;
if (plan.replaced->GetSize(srcLevel, w, h)) {
int bpp = (int)Draw::DataFormatSizeInBytes(plan.replaced->Format(srcLevel));
stride = w * bpp;
data = (u8 *)AllocateAlignedMemory(stride * h, 16);
} else {
if (plan.scaleFactor > 1) {
data = (u8 *)AllocateAlignedMemory(4 * (w * plan.scaleFactor) * (h * plan.scaleFactor), 16);
stride = w * plan.scaleFactor * 4;
} else {
int bpp = dstFmt == Draw::DataFormat::R8G8B8A8_UNORM ? 4 : 2;
stride = std::max(w * bpp, 4);
data = (u8 *)AllocateAlignedMemory(stride * h, 16);
}
}
if (!data) {
ERROR_LOG(G3D, "Ran out of RAM trying to allocate a temporary texture upload buffer (%dx%d)", w, h);
return;
}
LoadTextureLevel(*entry, data, stride, *plan.replaced, srcLevel, plan.scaleFactor, dstFmt, true);
// NOTE: TextureImage takes ownership of data, so we don't free it afterwards.
render_->TextureImage(entry->textureName, i, w * plan.scaleFactor, h * plan.scaleFactor, dstFmt, data, GLRAllocType::ALIGNED);
}
bool genMips = plan.levelsToCreate > plan.levelsToLoad;
render_->FinalizeTexture(entry->textureName, plan.levelsToLoad, genMips);
if (plan.levelsToLoad == 1) {
entry->status |= TexCacheEntry::STATUS_NO_MIPS;
} else {
entry->status &= ~TexCacheEntry::STATUS_NO_MIPS;
}
if (plan.replaced->Valid()) {
entry->SetAlphaStatus(TexCacheEntry::TexStatus(plan.replaced->AlphaStatus()));
}
@ -524,65 +549,6 @@ CheckAlphaResult TextureCacheGLES::CheckAlpha(const uint8_t *pixelData, Draw::Da
}
}
void TextureCacheGLES::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &replaced, int srcLevel, int dstLevel, int scaleFactor, Draw::DataFormat dstFmt) {
int w = gstate.getTextureWidth(srcLevel);
int h = gstate.getTextureHeight(srcLevel);
uint8_t *pixelData;
int decPitch = 0;
if (replaced.GetSize(srcLevel, w, h)) {
int bpp = (int)DataFormatSizeInBytes(replaced.Format(srcLevel));
decPitch = w * bpp;
uint8_t *rearrange = (uint8_t *)AllocateAlignedMemory(decPitch * h, 16);
double replaceStart = time_now_d();
replaced.Load(srcLevel, rearrange, decPitch);
replacementTimeThisFrame_ += time_now_d() - replaceStart;
pixelData = rearrange;
dstFmt = replaced.Format(srcLevel);
} else {
GEPaletteFormat clutformat = gstate.getClutPaletteFormat();
u32 texaddr = gstate.getTextureAddress(srcLevel);
int bufw = GetTextureBufw(srcLevel, texaddr, GETextureFormat(entry.format));
int pixelSize = dstFmt == Draw::DataFormat::R8G8B8A8_UNORM ? 4 : 2;
// We leave GL_UNPACK_ALIGNMENT at 4, so this must be at least 4.
decPitch = std::max(w * pixelSize, 4);
pixelData = (uint8_t *)AllocateAlignedMemory(decPitch * h * pixelSize, 16);
bool expand32 = scaleFactor > 1;
CheckAlphaResult alphaStatus = DecodeTextureLevel(pixelData, decPitch, GETextureFormat(entry.format), clutformat, texaddr, srcLevel, bufw, true, expand32);
entry.SetAlphaStatus(alphaStatus, srcLevel);
if (scaleFactor > 1) {
uint8_t *rearrange = (uint8_t *)AllocateAlignedMemory(w * scaleFactor * h * scaleFactor * 4, 16);
scaler_.ScaleAlways((u32 *)rearrange, (u32 *)pixelData, w, h, scaleFactor);
FreeAlignedMemory(pixelData);
pixelData = rearrange;
decPitch = w * 4;
}
if (replacer_.Enabled()) {
ReplacedTextureDecodeInfo replacedInfo;
replacedInfo.cachekey = entry.CacheKey();
replacedInfo.hash = entry.fullhash;
replacedInfo.addr = entry.addr;
replacedInfo.isVideo = IsVideo(entry.addr);
replacedInfo.isFinal = (entry.status & TexCacheEntry::STATUS_TO_SCALE) == 0;
replacedInfo.scaleFactor = scaleFactor;
replacedInfo.fmt = dstFmt;
replacer_.NotifyTextureDecoded(replacedInfo, pixelData, decPitch, srcLevel, w, h);
}
}
render_->TextureImage(entry.textureName, dstLevel, w, h, dstFmt, pixelData, GLRAllocType::ALIGNED);
}
bool TextureCacheGLES::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) {
GPUgstate saved;
if (level != 0) {

View file

@ -69,7 +69,6 @@ protected:
private:
void ApplySamplingParams(const SamplerCacheKey &key);
void LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &replaced, int srcLevel, int dstLevel, int scaleFactor, Draw::DataFormat dstFmt);
Draw::DataFormat GetDestFormat(GETextureFormat format, GEPaletteFormat clutFormat) const;
static CheckAlphaResult CheckAlpha(const uint8_t *pixelData, Draw::DataFormat dstFmt, int w);

View file

@ -845,8 +845,6 @@ void TextureCacheVulkan::LoadTextureLevel(TexCacheEntry &entry, uint8_t *writePt
int w = gstate.getTextureWidth(level);
int h = gstate.getTextureHeight(level);
PROFILE_THIS_SCOPE("decodetex");
GETextureFormat tfmt = (GETextureFormat)entry.format;
GEPaletteFormat clutformat = gstate.getClutPaletteFormat();
u32 texaddr = gstate.getTextureAddress(level);