mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Unify the GLES LoadTextureLevel with the D3D ones.
This commit is contained in:
parent
c6d7423368
commit
6a5a232777
8 changed files with 54 additions and 92 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue