mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-13 01:29:41 +01:00
Merge pull request #15939 from hrydgard/texture-dumping-fix
Texture dumping fix
This commit is contained in:
8 files changed
+44
-28
No files matched your search
@@ -258,8 +258,13 @@ std::wstring Path::ToWString() const {
|
||||
std::string Path::ToVisualString() const {
|
||||
if (type_ == PathType::CONTENT_URI) {
|
||||
return AndroidContentURI(path_).ToVisualString();
|
||||
#if PPSSPP_PLATFORM(WINDOWS)
|
||||
} else if (type_ == PathType::NATIVE) {
|
||||
return ReplaceAll(path_, "/", "\\");
|
||||
#endif
|
||||
} else {
|
||||
return path_;
|
||||
}
|
||||
return path_;
|
||||
}
|
||||
|
||||
bool Path::CanNavigateUp() const {
|
||||
|
||||
@@ -573,7 +573,7 @@ public:
|
||||
if (png.warning_or_error >= 2) {
|
||||
ERROR_LOG(COMMON, "Saving screenshot to PNG produced errors.");
|
||||
} else if (success) {
|
||||
NOTICE_LOG(G3D, "Saving texture for replacement: %08x / %dx%d", replacedInfoHash, w, h);
|
||||
NOTICE_LOG(G3D, "Saving texture for replacement: %08x / %dx%d in '%s'", replacedInfoHash, w, h, saveFilename.ToVisualString().c_str());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2388,6 +2388,7 @@ bool TextureCacheCommon::PrepareBuildTexture(BuildTexturePlan &plan, TexCacheEnt
|
||||
plan.replaceValid = plan.replaced->Valid();
|
||||
}
|
||||
|
||||
plan.saveTexture = false;
|
||||
if (plan.replaceValid) {
|
||||
// We're replacing, so we won't scale.
|
||||
plan.scaleFactor = 1;
|
||||
@@ -2397,6 +2398,18 @@ bool TextureCacheCommon::PrepareBuildTexture(BuildTexturePlan &plan, TexCacheEnt
|
||||
// But, we still need to create the texture at a larger size.
|
||||
plan.replaced->GetSize(0, plan.createW, plan.createH);
|
||||
} else {
|
||||
if (replacer_.Enabled() && !plan.replaceValid && plan.depth == 1) {
|
||||
ReplacedTextureDecodeInfo replacedInfo;
|
||||
// TODO: Do we handle the race where a replacement becomes valid AFTER this but before we save?
|
||||
replacedInfo.cachekey = entry->CacheKey();
|
||||
replacedInfo.hash = entry->fullhash;
|
||||
replacedInfo.addr = entry->addr;
|
||||
replacedInfo.isVideo = plan.isVideo;
|
||||
replacedInfo.isFinal = (entry->status & TexCacheEntry::STATUS_TO_SCALE) == 0;
|
||||
replacedInfo.scaleFactor = plan.scaleFactor;
|
||||
replacedInfo.fmt = Draw::DataFormat::R8G8B8A8_UNORM;
|
||||
plan.saveTexture = replacer_.WillSave(replacedInfo);
|
||||
}
|
||||
plan.createW = plan.w * plan.scaleFactor;
|
||||
plan.createH = plan.h * plan.scaleFactor;
|
||||
}
|
||||
@@ -2454,7 +2467,7 @@ void TextureCacheCommon::LoadTextureLevel(TexCacheEntry &entry, uint8_t *data, i
|
||||
decPitch = stride;
|
||||
}
|
||||
|
||||
bool expand32 = !gstate_c.Supports(GPU_SUPPORTS_16BIT_FORMATS) || scaleFactor > 1;
|
||||
bool expand32 = !gstate_c.Supports(GPU_SUPPORTS_16BIT_FORMATS) || dstFmt == Draw::DataFormat::R8G8B8A8_UNORM;
|
||||
|
||||
CheckAlphaResult alphaResult = DecodeTextureLevel((u8 *)pixelData, decPitch, tfmt, clutformat, texaddr, srcLevel, bufw, reverseColors, expand32);
|
||||
entry.SetAlphaStatus(alphaResult, srcLevel);
|
||||
|
||||
@@ -272,6 +272,7 @@ struct BuildTexturePlan {
|
||||
ReplacedTexture *replaced;
|
||||
// Need to only check once since it can change during the load!
|
||||
bool replaceValid;
|
||||
bool saveTexture;
|
||||
|
||||
void GetMipSize(int level, int *w, int *h) const {
|
||||
if (replaceValid) {
|
||||
|
||||
@@ -279,7 +279,7 @@ void TextureCacheD3D11::BuildTexture(TexCacheEntry *const entry) {
|
||||
DXGI_FORMAT dstFmt = GetDestFormat(GETextureFormat(entry->format), gstate.getClutPaletteFormat());
|
||||
if (plan.replaceValid) {
|
||||
dstFmt = ToDXGIFormat(plan.replaced->Format(plan.baseLevelSrc));
|
||||
} else if (plan.scaleFactor > 1) {
|
||||
} else if (plan.scaleFactor > 1 || plan.saveTexture) {
|
||||
dstFmt = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
}
|
||||
|
||||
|
||||
@@ -241,7 +241,7 @@ void TextureCacheDX9::BuildTexture(TexCacheEntry *const entry) {
|
||||
D3DFORMAT dstFmt = GetDestFormat(GETextureFormat(entry->format), gstate.getClutPaletteFormat());
|
||||
if (plan.replaceValid) {
|
||||
dstFmt = ToD3D9Format(plan.replaced->Format(plan.baseLevelSrc));
|
||||
} else if (plan.scaleFactor > 1) {
|
||||
} else if (plan.scaleFactor > 1 || plan.saveTexture) {
|
||||
dstFmt = D3DFMT_A8R8G8B8;
|
||||
}
|
||||
|
||||
|
||||
@@ -258,15 +258,13 @@ void TextureCacheGLES::BuildTexture(TexCacheEntry *const entry) {
|
||||
// the bottom few levels or rely on OpenGL's autogen mipmaps instead, which might not
|
||||
// be as good quality as the game's own (might even be better in some cases though).
|
||||
|
||||
int tw = plan.w;
|
||||
int th = plan.h;
|
||||
int tw = plan.createW;
|
||||
int th = plan.createH;
|
||||
|
||||
Draw::DataFormat dstFmt = GetDestFormat(GETextureFormat(entry->format), gstate.getClutPaletteFormat());
|
||||
if (plan.replaced->GetSize(plan.baseLevelSrc, tw, th)) {
|
||||
dstFmt = plan.replaced->Format(plan.baseLevelSrc);
|
||||
} else if (plan.scaleFactor > 1) {
|
||||
tw *= plan.scaleFactor;
|
||||
th *= plan.scaleFactor;
|
||||
} else if (plan.scaleFactor > 1 || plan.saveTexture) {
|
||||
dstFmt = Draw::DataFormat::R8G8B8A8_UNORM;
|
||||
}
|
||||
|
||||
|
||||
@@ -499,12 +499,16 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) {
|
||||
imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
}
|
||||
|
||||
if (plan.saveTexture) {
|
||||
actualFmt = VULKAN_8888_FORMAT;
|
||||
}
|
||||
|
||||
char texName[128]{};
|
||||
snprintf(texName, sizeof(texName), "tex_%08x_%s", entry->addr, GeTextureFormatToString((GETextureFormat)entry->format, gstate.getClutPaletteFormat()));
|
||||
image->SetTag(texName);
|
||||
|
||||
bool allocSuccess = image->CreateDirect(cmdInit, plan.createW, plan.createH, plan.depth, plan.levelsToCreate, actualFmt, imageLayout, usage, mapping);
|
||||
if (!allocSuccess && !lowMemoryMode_) {
|
||||
if (!allocSuccess && !lowMemoryMode_ && !replacer_.Enabled()) {
|
||||
WARN_LOG_REPORT(G3D, "Texture cache ran out of GPU memory; switching to low memory mode");
|
||||
lowMemoryMode_ = true;
|
||||
decimationCounter_ = 0;
|
||||
@@ -540,20 +544,6 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) {
|
||||
return;
|
||||
}
|
||||
|
||||
ReplacedTextureDecodeInfo replacedInfo;
|
||||
bool willSaveTex = false;
|
||||
if (replacer_.Enabled() && !plan.replaceValid && plan.depth == 1) {
|
||||
// TODO: Do we handle the race where a replacement becomes valid AFTER this but before we save?
|
||||
replacedInfo.cachekey = entry->CacheKey();
|
||||
replacedInfo.hash = entry->fullhash;
|
||||
replacedInfo.addr = entry->addr;
|
||||
replacedInfo.isVideo = plan.isVideo;
|
||||
replacedInfo.isFinal = (entry->status & TexCacheEntry::STATUS_TO_SCALE) == 0;
|
||||
replacedInfo.scaleFactor = plan.scaleFactor;
|
||||
replacedInfo.fmt = FromVulkanFormat(actualFmt);
|
||||
willSaveTex = replacer_.WillSave(replacedInfo);
|
||||
}
|
||||
|
||||
VK_PROFILE_BEGIN(vulkan, cmdInit, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
"Texture Upload (%08x) video=%d", entry->addr, plan.isVideo);
|
||||
|
||||
@@ -585,14 +575,14 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) {
|
||||
std::vector<uint8_t> saveData;
|
||||
|
||||
auto loadLevel = [&](int sz, int srcLevel, int lstride, int lfactor) {
|
||||
if (willSaveTex) {
|
||||
if (plan.saveTexture) {
|
||||
saveData.resize(sz);
|
||||
data = &saveData[0];
|
||||
} else {
|
||||
data = drawEngine_->GetPushBufferForTextureData()->PushAligned(sz, &bufferOffset, &texBuf, pushAlignment);
|
||||
}
|
||||
LoadTextureLevel(*entry, (uint8_t *)data, lstride, srcLevel, lfactor, dstFmt);
|
||||
if (willSaveTex)
|
||||
LoadTextureLevel(*entry, (uint8_t *)data, lstride, srcLevel, lfactor, actualFmt);
|
||||
if (plan.saveTexture)
|
||||
bufferOffset = drawEngine_->GetPushBufferForTextureData()->PushAligned(&saveData[0], sz, pushAlignment, &texBuf);
|
||||
};
|
||||
|
||||
@@ -643,6 +633,15 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) {
|
||||
int w = dataScaled ? mipWidth : mipUnscaledWidth;
|
||||
int h = dataScaled ? mipHeight : mipUnscaledHeight;
|
||||
// At this point, data should be saveData, and not slow.
|
||||
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 = plan.scaleFactor;
|
||||
replacedInfo.fmt = FromVulkanFormat(actualFmt);
|
||||
|
||||
replacer_.NotifyTextureDecoded(replacedInfo, data, stride, plan.baseLevelSrc + i, w, h);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user