Merge pull request #14344 from unknownbrackets/debugger-mem

Include more memory info in debugger tags
This commit is contained in:
Henrik Rydgård 2021-04-04 11:20:33 +02:00 committed by GitHub
commit e86e3cc7cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 323 additions and 224 deletions

View File

@ -46,7 +46,7 @@ private:
uint64_t ticks = 0;
uint32_t pc = 0;
bool allocated = false;
char tag[32]{};
char tag[128]{};
Slab *prev = nullptr;
Slab *next = nullptr;
@ -77,7 +77,7 @@ struct PendingNotifyMem {
uint32_t size;
uint64_t ticks;
uint32_t pc;
char tag[32];
char tag[128];
};
static constexpr size_t MAX_PENDING_NOTIFIES = 512;
@ -199,7 +199,7 @@ void MemSlabMap::DoState(PointerWrap &p) {
}
void MemSlabMap::Slab::DoState(PointerWrap &p) {
auto s = p.Section("MemSlabMapSlab", 1, 2);
auto s = p.Section("MemSlabMapSlab", 1, 3);
if (!s)
return;
@ -208,8 +208,12 @@ void MemSlabMap::Slab::DoState(PointerWrap &p) {
Do(p, ticks);
Do(p, pc);
Do(p, allocated);
if (s >= 2) {
if (s >= 3) {
Do(p, tag);
} else if (s >= 2) {
char shortTag[32];
Do(p, shortTag);
memcpy(tag, shortTag, sizeof(shortTag));
} else {
std::string stringTag;
Do(p, stringTag);
@ -429,6 +433,20 @@ std::vector<MemBlockInfo> FindMemInfoByFlag(MemBlockFlags flags, uint32_t start,
return results;
}
std::string GetMemWriteTagAt(uint32_t start, uint32_t size) {
std::vector<MemBlockInfo> memRangeInfo = FindMemInfoByFlag(MemBlockFlags::WRITE, start, size);
for (auto range : memRangeInfo) {
return range.tag;
}
// Fall back to alloc and texture, especially for VRAM. We prefer write above.
memRangeInfo = FindMemInfoByFlag(MemBlockFlags::ALLOC | MemBlockFlags::TEXTURE, start, size);
for (auto range : memRangeInfo) {
return range.tag;
}
return "none";
}
void MemBlockInfoInit() {
std::lock_guard<std::mutex> guard(pendingMutex);
pendingNotifies.reserve(MAX_PENDING_NOTIFIES);

View File

@ -63,6 +63,8 @@ inline void NotifyMemInfo(MemBlockFlags flags, uint32_t start, uint32_t size, co
std::vector<MemBlockInfo> FindMemInfo(uint32_t start, uint32_t size);
std::vector<MemBlockInfo> FindMemInfoByFlag(MemBlockFlags flags, uint32_t start, uint32_t size);
std::string GetMemWriteTagAt(uint32_t start, uint32_t size);
void MemBlockInfoInit();
void MemBlockInfoShutdown();
void MemBlockInfoDoState(PointerWrap &p);

View File

@ -25,6 +25,7 @@
#include "Core/Host.h"
#include "Core/Reporting.h"
#include "Core/System.h"
#include "Core/Debugger/MemBlockInfo.h"
#include "Core/Dialog/SavedataParam.h"
#include "Core/Dialog/PSPSaveDialog.h"
#include "Core/FileSystems/MetaFileSystem.h"
@ -644,7 +645,7 @@ int SavedataParam::LoadSaveData(SceUtilitySavedataParam *param, const std::strin
}
WARN_LOG_REPORT(SCEUTILITY, "Savedata version requested: %d", param->secureVersion);
}
u8 *data_ = param->dataBuf;
std::string filename = GetFileName(param);
std::string filePath = dirPath + "/" + filename;
s64 readSize;
@ -663,21 +664,27 @@ int SavedataParam::LoadSaveData(SceUtilitySavedataParam *param, const std::strin
int prevCryptMode = GetSaveCryptMode(param, saveDirName);
bool isCrypted = prevCryptMode != 0 && secureMode;
bool saveDone = false;
u32 loadedSize = 0;
if (isCrypted) {
if (DetermineCryptMode(param) > 1 && !HasKey(param))
return SCE_UTILITY_SAVEDATA_ERROR_LOAD_PARAM;
u8 hash[16];
bool hasExpectedHash = GetExpectedHash(dirPath, filename, hash);
LoadCryptedSave(param, data_, saveData, saveSize, prevCryptMode, hasExpectedHash ? hash : nullptr, saveDone);
loadedSize = LoadCryptedSave(param, param->dataBuf, saveData, saveSize, prevCryptMode, hasExpectedHash ? hash : nullptr, saveDone);
// TODO: Should return SCE_UTILITY_SAVEDATA_ERROR_LOAD_DATA_BROKEN here if !saveDone.
}
if (!saveDone) {
LoadNotCryptedSave(param, data_, saveData, saveSize);
loadedSize = LoadNotCryptedSave(param, param->dataBuf, saveData, saveSize);
}
param->dataSize = (SceSize)saveSize;
delete[] saveData;
if (loadedSize != 0) {
std::string tag = "LoadSaveData/" + filePath;
NotifyMemInfo(MemBlockFlags::WRITE, param->dataBuf.ptr, loadedSize, tag.c_str(), tag.size());
}
return 0;
}
@ -696,7 +703,7 @@ int SavedataParam::DetermineCryptMode(const SceUtilitySavedataParam *param) cons
return decryptMode;
}
void SavedataParam::LoadCryptedSave(SceUtilitySavedataParam *param, u8 *data, const u8 *saveData, int &saveSize, int prevCryptMode, const u8 *expectedHash, bool &saveDone) {
u32 SavedataParam::LoadCryptedSave(SceUtilitySavedataParam *param, u8 *data, const u8 *saveData, int &saveSize, int prevCryptMode, const u8 *expectedHash, bool &saveDone) {
int orig_size = saveSize;
int align_len = align16(saveSize);
u8 *data_base = new u8[align_len];
@ -760,18 +767,27 @@ void SavedataParam::LoadCryptedSave(SceUtilitySavedataParam *param, u8 *data, co
err = DecryptSave(decryptMode, data_base, &saveSize, &align_len, hasKey ? cryptKey : nullptr, nullptr);
}
u32 sz = 0;
if (err == 0) {
if (param->dataBuf.IsValid())
memcpy(data, data_base, std::min((u32)saveSize, (u32)param->dataBufSize));
if (param->dataBuf.IsValid()) {
sz = std::min((u32)saveSize, (u32)param->dataBufSize);
memcpy(data, data_base, sz);
}
saveDone = true;
}
delete[] data_base;
delete[] cryptKey;
return sz;
}
void SavedataParam::LoadNotCryptedSave(SceUtilitySavedataParam *param, u8 *data, u8 *saveData, int &saveSize) {
if (param->dataBuf.IsValid())
memcpy(data, saveData, std::min((u32)saveSize, (u32)param->dataBufSize));
u32 SavedataParam::LoadNotCryptedSave(SceUtilitySavedataParam *param, u8 *data, u8 *saveData, int &saveSize) {
if (param->dataBuf.IsValid()) {
u32 sz = std::min((u32)saveSize, (u32)param->dataBufSize);
memcpy(data, saveData, sz);
return sz;
}
return 0;
}
void SavedataParam::LoadSFO(SceUtilitySavedataParam *param, const std::string& dirPath) {
@ -849,8 +865,11 @@ void SavedataParam::LoadFile(const std::string& dirPath, const std::string& file
u8 *buf = fileData->buf;
u32 size = Memory::ValidSize(fileData->buf.ptr, fileData->bufSize);
s64 readSize = -1;
if (ReadPSPFile(filePath, &buf, size, &readSize))
if (ReadPSPFile(filePath, &buf, size, &readSize)) {
fileData->size = readSize;
const std::string tag = "SavedataLoad/" + filePath;
NotifyMemInfo(MemBlockFlags::WRITE, fileData->buf.ptr, fileData->size, tag.c_str(), tag.size());
}
}
int SavedataParam::EncryptData(unsigned int mode,
@ -1066,6 +1085,7 @@ int SavedataParam::GetSizes(SceUtilitySavedataParam *param)
const std::string spaceTxt = SavedataParam::GetSpaceText(freeBytes, false);
memset(param->msFree->freeSpaceStr, 0, sizeof(param->msFree->freeSpaceStr));
strncpy(param->msFree->freeSpaceStr, spaceTxt.c_str(), sizeof(param->msFree->freeSpaceStr));
NotifyMemInfo(MemBlockFlags::WRITE, param->msFree.ptr, sizeof(SceUtilitySavedataMsFreeInfo), "SavedataGetSizes");
}
if (param->msData.IsValid())
{
@ -1103,6 +1123,7 @@ int SavedataParam::GetSizes(SceUtilitySavedataParam *param)
strncpy(param->msData->info.usedSpace32Str, "", sizeof(param->msData->info.usedSpace32Str));
ret = SCE_UTILITY_SAVEDATA_ERROR_SIZES_NO_DATA;
}
NotifyMemInfo(MemBlockFlags::WRITE, param->msData.ptr, sizeof(SceUtilitySavedataMsDataInfo), "SavedataGetSizes");
}
if (param->utilityData.IsValid())
{
@ -1138,6 +1159,7 @@ int SavedataParam::GetSizes(SceUtilitySavedataParam *param)
spaceTxt = SavedataParam::GetSpaceText(total_size, true);
memset(param->utilityData->usedSpace32Str, 0, sizeof(param->utilityData->usedSpace32Str));
strncpy(param->utilityData->usedSpace32Str, spaceTxt.c_str(), sizeof(param->utilityData->usedSpace32Str));
NotifyMemInfo(MemBlockFlags::WRITE, param->utilityData.ptr, sizeof(SceUtilitySavedataUsedDataInfo), "SavedataGetSizes");
}
return ret;
@ -1157,47 +1179,47 @@ bool SavedataParam::GetList(SceUtilitySavedataParam *param)
std::vector<PSPFileInfo> sfoFiles;
std::vector<PSPFileInfo> allDir = pspFileSystem.GetDirListing(savePath);
if (param->idList.IsValid())
std::string searchString = GetGameName(param)+GetSaveName(param);
for (size_t i = 0; i < allDir.size() && validDir.size() < maxFile; i++)
{
std::string searchString = GetGameName(param)+GetSaveName(param);
for (size_t i = 0; i < allDir.size() && validDir.size() < maxFile; i++)
std::string dirName = allDir[i].name;
if(PSPMatch(dirName, searchString))
{
std::string dirName = allDir[i].name;
if(PSPMatch(dirName, searchString))
{
validDir.push_back(allDir[i]);
}
validDir.push_back(allDir[i]);
}
}
PSPFileInfo sfoFile;
for (size_t i = 0; i < validDir.size(); ++i) {
// GetFileName(param) == NUll here
// so use sfo files to set the date.
sfoFile = pspFileSystem.GetFileInfo(savePath + validDir[i].name + "/" + "PARAM.SFO");
sfoFiles.push_back(sfoFile);
}
PSPFileInfo sfoFile;
for (size_t i = 0; i < validDir.size(); ++i) {
// GetFileName(param) == NUll here
// so use sfo files to set the date.
sfoFile = pspFileSystem.GetFileInfo(savePath + validDir[i].name + "/" + "PARAM.SFO");
sfoFiles.push_back(sfoFile);
}
SceUtilitySavedataIdListEntry *entries = param->idList->entries;
for (u32 i = 0; i < (u32)validDir.size(); i++)
{
entries[i].st_mode = 0x11FF;
if (sfoFiles[i].exists) {
__IoCopyDate(entries[i].st_ctime, sfoFiles[i].ctime);
__IoCopyDate(entries[i].st_atime, sfoFiles[i].atime);
__IoCopyDate(entries[i].st_mtime, sfoFiles[i].mtime);
} else {
__IoCopyDate(entries[i].st_ctime, validDir[i].ctime);
__IoCopyDate(entries[i].st_atime, validDir[i].atime);
__IoCopyDate(entries[i].st_mtime, validDir[i].mtime);
}
// folder name without gamename (max 20 u8)
std::string outName = validDir[i].name.substr(GetGameName(param).size());
memset(entries[i].name, 0, sizeof(entries[i].name));
strncpy(entries[i].name, outName.c_str(), sizeof(entries[i].name));
SceUtilitySavedataIdListEntry *entries = param->idList->entries;
for (u32 i = 0; i < (u32)validDir.size(); i++)
{
entries[i].st_mode = 0x11FF;
if (sfoFiles[i].exists) {
__IoCopyDate(entries[i].st_ctime, sfoFiles[i].ctime);
__IoCopyDate(entries[i].st_atime, sfoFiles[i].atime);
__IoCopyDate(entries[i].st_mtime, sfoFiles[i].mtime);
} else {
__IoCopyDate(entries[i].st_ctime, validDir[i].ctime);
__IoCopyDate(entries[i].st_atime, validDir[i].atime);
__IoCopyDate(entries[i].st_mtime, validDir[i].mtime);
}
// folder name without gamename (max 20 u8)
std::string outName = validDir[i].name.substr(GetGameName(param).size());
memset(entries[i].name, 0, sizeof(entries[i].name));
strncpy(entries[i].name, outName.c_str(), sizeof(entries[i].name));
}
// Save num of folder found
param->idList->resultCount = (u32)validDir.size();
NotifyMemInfo(MemBlockFlags::WRITE, param->idList.ptr, sizeof(SceUtilitySavedataIdListInfo), "SavedataGetList");
NotifyMemInfo(MemBlockFlags::WRITE, param->idList->entries.ptr, validDir.size() * sizeof(SceUtilitySavedataIdListEntry), "SavedataGetList");
}
return true;
}
@ -1306,6 +1328,14 @@ int SavedataParam::GetFilesList(SceUtilitySavedataParam *param)
// Don't know what it is, but PSP always respond this
param->bind = 1021;
NotifyMemInfo(MemBlockFlags::WRITE, fileList.ptr, sizeof(SceUtilitySavedataFileListInfo), "SavedataGetFilesList");
if (fileList->resultNumSystemEntries != 0)
NotifyMemInfo(MemBlockFlags::WRITE, fileList->systemEntries.ptr, fileList->resultNumSystemEntries * sizeof(SceUtilitySavedataFileListEntry), "SavedataGetFilesList");
if (fileList->resultNumSecureEntries != 0)
NotifyMemInfo(MemBlockFlags::WRITE, fileList->secureEntries.ptr, fileList->resultNumSecureEntries * sizeof(SceUtilitySavedataFileListEntry), "SavedataGetFilesList");
if (fileList->resultNumNormalEntries != 0)
NotifyMemInfo(MemBlockFlags::WRITE, fileList->normalEntries.ptr, fileList->resultNumNormalEntries * sizeof(SceUtilitySavedataFileListEntry), "SavedataGetFilesList");
return 0;
}
@ -1372,6 +1402,8 @@ bool SavedataParam::GetSize(SceUtilitySavedataParam *param)
truncate_cpy(param->sizeInfo->overwriteString, spaceTxt.c_str());
}
}
NotifyMemInfo(MemBlockFlags::WRITE, param->sizeInfo.ptr, sizeof(PspUtilitySavedataSizeInfo), "SavedataGetSize");
}
return exists;

View File

@ -364,8 +364,8 @@ private:
PSPFileInfo GetSaveInfo(std::string saveDir);
int LoadSaveData(SceUtilitySavedataParam *param, const std::string &saveDirName, const std::string& dirPath, bool secureMode);
void LoadCryptedSave(SceUtilitySavedataParam *param, u8 *data, const u8 *saveData, int &saveSize, int prevCryptMode, const u8 *expectedHash, bool &saveDone);
void LoadNotCryptedSave(SceUtilitySavedataParam *param, u8 *data, u8 *saveData, int &saveSize);
u32 LoadCryptedSave(SceUtilitySavedataParam *param, u8 *data, const u8 *saveData, int &saveSize, int prevCryptMode, const u8 *expectedHash, bool &saveDone);
u32 LoadNotCryptedSave(SceUtilitySavedataParam *param, u8 *data, u8 *saveData, int &saveSize);
void LoadSFO(SceUtilitySavedataParam *param, const std::string& dirPath);
void LoadFile(const std::string& dirPath, const std::string& filename, PspUtilitySavedataFileData *fileData);

View File

@ -156,8 +156,9 @@ static int Replace_memcpy() {
}
RETURN(destPtr);
NotifyMemInfo(MemBlockFlags::READ, srcPtr, bytes, "ReplaceMemcpy");
NotifyMemInfo(MemBlockFlags::WRITE, destPtr, bytes, "ReplaceMemcpy");
const std::string tag = "ReplaceMemcpy/" + GetMemWriteTagAt(srcPtr, bytes);
NotifyMemInfo(MemBlockFlags::READ, srcPtr, bytes, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, destPtr, bytes, tag.c_str(), tag.size());
return 10 + bytes / 4; // approximation
}
@ -198,8 +199,9 @@ static int Replace_memcpy_jak() {
currentMIPS->r[MIPS_REG_A3] = destPtr + bytes;
RETURN(destPtr);
NotifyMemInfo(MemBlockFlags::READ, srcPtr, bytes, "ReplaceMemcpy");
NotifyMemInfo(MemBlockFlags::WRITE, destPtr, bytes, "ReplaceMemcpy");
const std::string tag = "ReplaceMemcpy/" + GetMemWriteTagAt(srcPtr, bytes);
NotifyMemInfo(MemBlockFlags::READ, srcPtr, bytes, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, destPtr, bytes, tag.c_str(), tag.size());
return 5 + bytes * 8 + 2; // approximation. This is a slow memcpy - a byte copy loop..
}
@ -226,8 +228,9 @@ static int Replace_memcpy16() {
}
RETURN(destPtr);
NotifyMemInfo(MemBlockFlags::READ, srcPtr, bytes, "ReplaceMemcpy16");
NotifyMemInfo(MemBlockFlags::WRITE, destPtr, bytes, "ReplaceMemcpy16");
const std::string tag = "ReplaceMemcpy16/" + GetMemWriteTagAt(srcPtr, bytes);
NotifyMemInfo(MemBlockFlags::READ, srcPtr, bytes, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, destPtr, bytes, tag.c_str(), tag.size());
return 10 + bytes / 4; // approximation
}
@ -264,8 +267,9 @@ static int Replace_memcpy_swizzled() {
RETURN(0);
NotifyMemInfo(MemBlockFlags::READ, srcPtr, pitch * h, "ReplaceMemcpySwizzle");
NotifyMemInfo(MemBlockFlags::WRITE, destPtr, pitch * h, "ReplaceMemcpySwizzle");
const std::string tag = "ReplaceMemcpySwizzle/" + GetMemWriteTagAt(srcPtr, pitch * h);
NotifyMemInfo(MemBlockFlags::READ, srcPtr, pitch * h, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, destPtr, pitch * h, tag.c_str(), tag.size());
return 10 + (pitch * h) / 4; // approximation
}
@ -292,8 +296,9 @@ static int Replace_memmove() {
}
RETURN(destPtr);
NotifyMemInfo(MemBlockFlags::READ, srcPtr, bytes, "ReplaceMemmove");
NotifyMemInfo(MemBlockFlags::WRITE, destPtr, bytes, "ReplaceMemmove");
const std::string tag = "ReplaceMemmove/" + GetMemWriteTagAt(srcPtr, bytes);
NotifyMemInfo(MemBlockFlags::READ, srcPtr, bytes, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, destPtr, bytes, tag.c_str(), tag.size());
return 10 + bytes / 4; // approximation
}

View File

@ -153,7 +153,7 @@ struct InputBuffer {
struct Atrac;
int __AtracSetContext(Atrac *atrac);
void _AtracGenerateContext(Atrac *atrac, SceAtracId *context);
void _AtracGenerateContext(Atrac *atrac);
struct AtracLoopInfo {
int cuePointID;
@ -520,6 +520,15 @@ struct Atrac {
currentSample_ = sample;
}
uint32_t CurBufferAddress(int adjust = 0) {
u32 off = FileOffsetBySample(currentSample_ + adjust);
if (off < first_.size && ignoreDataBuf_) {
return first_.addr + off;
}
// If it's in dataBug, it's not in PSP memory.
return 0;
}
bool FillPacket(int adjust = 0) {
u32 off = FileOffsetBySample(currentSample_ + adjust);
if (off < first_.size) {
@ -1031,7 +1040,7 @@ u32 _AtracAddStreamData(int atracID, u32 bufPtr, u32 bytesToAdd) {
if (!atrac)
return 0;
int addbytes = std::min(bytesToAdd, atrac->first_.filesize - atrac->first_.fileoffset);
Memory::Memcpy(atrac->dataBuf_ + atrac->first_.fileoffset, bufPtr, addbytes);
Memory::Memcpy(atrac->dataBuf_ + atrac->first_.fileoffset, bufPtr, addbytes, "AtracAddStreamData");
atrac->first_.size += bytesToAdd;
if (atrac->first_.size >= atrac->first_.filesize) {
atrac->first_.size = atrac->first_.filesize;
@ -1041,7 +1050,7 @@ u32 _AtracAddStreamData(int atracID, u32 bufPtr, u32 bytesToAdd) {
atrac->first_.fileoffset += addbytes;
if (atrac->context_.IsValid()) {
// refresh context_
_AtracGenerateContext(atrac, atrac->context_);
_AtracGenerateContext(atrac);
}
return 0;
}
@ -1142,7 +1151,7 @@ static u32 sceAtracAddStreamData(int atracID, u32 bytesToAdd) {
atrac->first_.fileoffset = readOffset;
int addbytes = std::min(bytesToAdd, atrac->first_.filesize - atrac->first_.fileoffset);
if (!atrac->ignoreDataBuf_) {
Memory::Memcpy(atrac->dataBuf_ + atrac->first_.fileoffset, atrac->first_.addr + atrac->first_.offset, addbytes);
Memory::Memcpy(atrac->dataBuf_ + atrac->first_.fileoffset, atrac->first_.addr + atrac->first_.offset, addbytes, "AtracAddStreamData");
}
atrac->first_.fileoffset += addbytes;
}
@ -1152,7 +1161,7 @@ static u32 sceAtracAddStreamData(int atracID, u32 bytesToAdd) {
if (atrac->bufferState_ == ATRAC_STATUS_HALFWAY_BUFFER)
atrac->bufferState_ = ATRAC_STATUS_ALL_DATA_LOADED;
if (atrac->context_.IsValid()) {
_AtracGenerateContext(atrac, atrac->context_);
_AtracGenerateContext(atrac);
}
}
@ -1208,6 +1217,8 @@ u32 _AtracDecodeData(int atracID, u8 *outbuf, u32 outbufPtr, u32 *SamplesNum, u3
AtracDecodeResult res = ATDECODE_FEEDME;
while (atrac->FillPacket(-skipSamples)) {
uint32_t packetAddr = atrac->CurBufferAddress(-skipSamples);
int packetSize = atrac->packet_->size;
res = atrac->DecodePacket();
if (res == ATDECODE_FAILED) {
*SamplesNum = 0;
@ -1246,7 +1257,13 @@ u32 _AtracDecodeData(int atracID, u8 *outbuf, u32 outbufPtr, u32 *SamplesNum, u3
int avret = swr_convert(atrac->swrCtx_, &out, numSamples, inbuf, numSamples);
if (outbufPtr != 0) {
u32 outBytes = numSamples * atrac->outputChannels_ * sizeof(s16);
NotifyMemInfo(MemBlockFlags::WRITE, outbufPtr, outBytes, "AtracDecode");
if (packetAddr != 0 && g_Config.bDebugMemInfoDetailed) {
const std::string tag = "AtracDecode/" + GetMemWriteTagAt(packetAddr, packetSize);
NotifyMemInfo(MemBlockFlags::READ, packetAddr, packetSize, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, outbufPtr, outBytes, tag.c_str(), tag.size());
} else {
NotifyMemInfo(MemBlockFlags::WRITE, outbufPtr, outBytes, "AtracDecode");
}
}
if (avret < 0) {
ERROR_LOG(ME, "swr_convert: Error while converting %d", avret);
@ -1313,7 +1330,7 @@ u32 _AtracDecodeData(int atracID, u8 *outbuf, u32 outbufPtr, u32 *SamplesNum, u3
}
if (atrac->context_.IsValid()) {
// refresh context_
_AtracGenerateContext(atrac, atrac->context_);
_AtracGenerateContext(atrac);
}
}
@ -1729,7 +1746,7 @@ static u32 sceAtracResetPlayPosition(int atracID, int sample, int bytesWrittenFi
// Okay, it's a valid number of bytes. Let's set them up.
if (bytesWrittenFirstBuf != 0) {
if (!atrac->ignoreDataBuf_) {
Memory::Memcpy(atrac->dataBuf_ + atrac->first_.size, atrac->first_.addr + atrac->first_.size, bytesWrittenFirstBuf);
Memory::Memcpy(atrac->dataBuf_ + atrac->first_.size, atrac->first_.addr + atrac->first_.size, bytesWrittenFirstBuf, "AtracResetPlayPosition");
}
atrac->first_.fileoffset += bytesWrittenFirstBuf;
atrac->first_.size += bytesWrittenFirstBuf;
@ -1752,7 +1769,7 @@ static u32 sceAtracResetPlayPosition(int atracID, int sample, int bytesWrittenFi
if (bytesWrittenFirstBuf != 0) {
if (!atrac->ignoreDataBuf_) {
Memory::Memcpy(atrac->dataBuf_ + atrac->first_.fileoffset, atrac->first_.addr, bytesWrittenFirstBuf);
Memory::Memcpy(atrac->dataBuf_ + atrac->first_.fileoffset, atrac->first_.addr, bytesWrittenFirstBuf, "AtracResetPlayPosition");
}
atrac->first_.fileoffset += bytesWrittenFirstBuf;
}
@ -1769,7 +1786,7 @@ static u32 sceAtracResetPlayPosition(int atracID, int sample, int bytesWrittenFi
}
if (atrac->context_.IsValid()) {
_AtracGenerateContext(atrac, atrac->context_);
_AtracGenerateContext(atrac);
}
return hleDelayResult(hleLogSuccessInfoI(ME, 0), "reset play pos", 3000);
@ -1924,7 +1941,7 @@ static int _AtracSetData(Atrac *atrac, u32 buffer, u32 readSize, u32 bufferSize,
atrac->dataBuf_ = new u8[atrac->first_.filesize];
if (!atrac->ignoreDataBuf_) {
u32 copybytes = std::min(bufferSize, atrac->first_.filesize);
Memory::Memcpy(atrac->dataBuf_, buffer, copybytes);
Memory::Memcpy(atrac->dataBuf_, buffer, copybytes, "AtracSetData");
}
int ret = __AtracSetContext(atrac);
if (ret < 0) {
@ -2083,7 +2100,7 @@ static u32 sceAtracSetLoopNum(int atracID, int loopNum) {
atrac->loopEndSample_ = atrac->endSample_ + atrac->firstSampleOffset_ + atrac->FirstOffsetExtra();
}
if (atrac->context_.IsValid()) {
_AtracGenerateContext(atrac, atrac->context_);
_AtracGenerateContext(atrac);
}
}
return 0;
@ -2291,7 +2308,8 @@ int _AtracGetIDByContext(u32 contextAddr) {
return atracID;
}
void _AtracGenerateContext(Atrac *atrac, SceAtracId *context) {
void _AtracGenerateContext(Atrac *atrac) {
SceAtracId *context = atrac->context_;
context->info.buffer = atrac->first_.addr;
context->info.bufferByte = atrac->bufferMaxSize_;
context->info.secondBuffer = atrac->second_.addr;
@ -2321,6 +2339,8 @@ void _AtracGenerateContext(Atrac *atrac, SceAtracId *context) {
u8 *buf = (u8 *)context;
*(u32_le *)(buf + 0xfc) = atrac->atracID_;
NotifyMemInfo(MemBlockFlags::WRITE, atrac->context_.ptr, sizeof(SceAtracId), "AtracContext");
}
static u32 _sceAtracGetContextAddress(int atracID) {
@ -2341,7 +2361,7 @@ static u32 _sceAtracGetContextAddress(int atracID) {
else
WARN_LOG(ME, "%08x=_sceAtracGetContextAddress(%i)", atrac->context_.ptr, atracID);
if (atrac->context_.IsValid())
_AtracGenerateContext(atrac, atrac->context_);
_AtracGenerateContext(atrac);
return atrac->context_.ptr;
}
@ -2430,7 +2450,7 @@ static int sceAtracLowLevelInitDecoder(int atracID, u32 paramsAddr) {
int ret = __AtracSetContext(atrac);
if (atrac->context_.IsValid()) {
_AtracGenerateContext(atrac, atrac->context_);
_AtracGenerateContext(atrac);
}
if (ret < 0) {

View File

@ -18,147 +18,63 @@
#include "zlib.h"
#include "Common/CommonTypes.h"
#include "Core/Debugger/MemBlockInfo.h"
#include "Core/HLE/HLE.h"
#include "Core/HLE/FunctionWrappers.h"
#include "Core/HLE/sceDeflt.h"
#include "Core/MemMap.h"
// All the decompress functions are identical with only differing window bits. Possibly should be one function
static int sceDeflateDecompress(u32 OutBuffer, int OutBufferLength, u32 InBuffer, u32 Crc32Addr) {
DEBUG_LOG(HLE, "sceGzipDecompress(%08x, %x, %08x, %08x)", OutBuffer, OutBufferLength, InBuffer, Crc32Addr);
int err;
uLong crc;
z_stream stream;
u8 *outBufferPtr;
u32_le *crc32AddrPtr = nullptr;
// All the decompress functions are identical with only differing window bits.
static int CommonDecompress(int windowBits, u32 OutBuffer, int OutBufferLength, u32 InBuffer, u32 Crc32Addr) {
if (!Memory::IsValidAddress(OutBuffer) || !Memory::IsValidAddress(InBuffer)) {
ERROR_LOG(HLE, "sceZlibDecompress: Bad address %08x %08x", OutBuffer, InBuffer);
return 0;
return hleLogError(HLE, 0, "bad address");
}
if (Crc32Addr) {
if (!Memory::IsValidAddress(Crc32Addr)) {
ERROR_LOG(HLE, "sceZlibDecompress: Bad address %08x", Crc32Addr);
return 0;
}
crc32AddrPtr = (u32_le *)Memory::GetPointer(Crc32Addr);
auto crc32Addr = PSPPointer<u32_le>::Create(Crc32Addr);
if (Crc32Addr && !crc32Addr.IsValid()) {
return hleLogError(HLE, 0, "bad crc32 address");
}
outBufferPtr = Memory::GetPointer(OutBuffer);
z_stream stream{};
u8 *outBufferPtr = Memory::GetPointer(OutBuffer);
stream.next_in = (Bytef*)Memory::GetPointer(InBuffer);
stream.avail_in = (uInt)OutBufferLength;
// We don't know the available length, just let it use as much as it wants.
stream.avail_in = (uInt)Memory::ValidSize(InBuffer, Memory::g_MemorySize);
stream.next_out = outBufferPtr;
stream.avail_out = (uInt)OutBufferLength;
stream.zalloc = (alloc_func)0;
stream.zfree = (free_func)0;
err = inflateInit2(&stream, -MAX_WBITS);
int err = inflateInit2(&stream, windowBits);
if (err != Z_OK) {
ERROR_LOG(HLE, "sceZlibDecompress: inflateInit2 failed %08x", err);
return 0;
return hleLogError(HLE, 0, "inflateInit2 failed %08x", err);
}
err = inflate(&stream, Z_FINISH);
if (err != Z_STREAM_END) {
inflateEnd(&stream);
ERROR_LOG(HLE, "sceZlibDecompress: inflate failed %08x", err);
return 0;
}
inflateEnd(&stream);
if (crc32AddrPtr) {
crc = crc32(0L, Z_NULL, 0);
*crc32AddrPtr = crc32(crc, outBufferPtr, stream.total_out);
if (err != Z_STREAM_END) {
return hleLogError(HLE, 0, "inflate failed %08x", err);
}
return stream.total_out;
if (crc32Addr.IsValid()) {
uLong crc = crc32(0L, Z_NULL, 0);
*crc32Addr = crc32(crc, outBufferPtr, stream.total_out);
}
const std::string tag = "sceDeflt/" + GetMemWriteTagAt(InBuffer, stream.total_in);
NotifyMemInfo(MemBlockFlags::READ, InBuffer, stream.total_in, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, OutBuffer, stream.total_out, tag.c_str(), tag.size());
return hleLogSuccessI(HLE, stream.total_out);
}
static int sceDeflateDecompress(u32 OutBuffer, int OutBufferLength, u32 InBuffer, u32 Crc32Addr) {
return CommonDecompress(-MAX_WBITS, OutBuffer, OutBufferLength, InBuffer, Crc32Addr);
}
static int sceGzipDecompress(u32 OutBuffer, int OutBufferLength, u32 InBuffer, u32 Crc32Addr) {
DEBUG_LOG(HLE, "sceGzipDecompress(%08x, %x, %08x, %08x)", OutBuffer, OutBufferLength, InBuffer, Crc32Addr);
int err;
uLong crc;
z_stream stream;
u8 *outBufferPtr;
u32_le *crc32AddrPtr = nullptr;
if (!Memory::IsValidAddress(OutBuffer) || !Memory::IsValidAddress(InBuffer)) {
ERROR_LOG(HLE, "sceZlibDecompress: Bad address %08x %08x", OutBuffer, InBuffer);
return 0;
}
if (Crc32Addr) {
if (!Memory::IsValidAddress(Crc32Addr)) {
ERROR_LOG(HLE, "sceZlibDecompress: Bad address %08x", Crc32Addr);
return 0;
}
crc32AddrPtr = (u32_le *)Memory::GetPointer(Crc32Addr);
}
outBufferPtr = Memory::GetPointer(OutBuffer);
stream.next_in = (Bytef*)Memory::GetPointer(InBuffer);
stream.avail_in = (uInt)OutBufferLength;
stream.next_out = outBufferPtr;
stream.avail_out = (uInt)OutBufferLength;
stream.zalloc = (alloc_func)0;
stream.zfree = (free_func)0;
err = inflateInit2(&stream, 16+MAX_WBITS);
if (err != Z_OK) {
ERROR_LOG(HLE, "sceZlibDecompress: inflateInit2 failed %08x", err);
return 0;
}
err = inflate(&stream, Z_FINISH);
if (err != Z_STREAM_END) {
inflateEnd(&stream);
ERROR_LOG(HLE, "sceZlibDecompress: inflate failed %08x", err);
return 0;
}
inflateEnd(&stream);
if (crc32AddrPtr) {
crc = crc32(0L, Z_NULL, 0);
*crc32AddrPtr = crc32(crc, outBufferPtr, stream.total_out);
}
return stream.total_out;
return CommonDecompress(16 + MAX_WBITS, OutBuffer, OutBufferLength, InBuffer, Crc32Addr);
}
static int sceZlibDecompress(u32 OutBuffer, int OutBufferLength, u32 InBuffer, u32 Crc32Addr) {
DEBUG_LOG(HLE, "sceZlibDecompress(%08x, %x, %08x, %08x)", OutBuffer, OutBufferLength, InBuffer, Crc32Addr);
int err;
uLong crc;
z_stream stream;
u8 *outBufferPtr;
u32_le *crc32AddrPtr = 0;
if (!Memory::IsValidAddress(OutBuffer) || !Memory::IsValidAddress(InBuffer)) {
ERROR_LOG(HLE, "sceZlibDecompress: Bad address %08x %08x", OutBuffer, InBuffer);
return 0;
}
if (Crc32Addr) {
if (!Memory::IsValidAddress(Crc32Addr)) {
ERROR_LOG(HLE, "sceZlibDecompress: Bad address %08x", Crc32Addr);
return 0;
}
crc32AddrPtr = (u32_le *)Memory::GetPointer(Crc32Addr);
}
outBufferPtr = Memory::GetPointer(OutBuffer);
stream.next_in = (Bytef*)Memory::GetPointer(InBuffer);
stream.avail_in = (uInt)OutBufferLength;
stream.next_out = outBufferPtr;
stream.avail_out = (uInt)OutBufferLength;
stream.zalloc = (alloc_func)0;
stream.zfree = (free_func)0;
err = inflateInit2(&stream, MAX_WBITS);
if (err != Z_OK) {
ERROR_LOG(HLE, "sceZlibDecompress: inflateInit failed %08x", err);
return 0;
}
err = inflate(&stream, Z_FINISH);
if (err != Z_STREAM_END) {
inflateEnd(&stream);
ERROR_LOG(HLE, "sceZlibDecompress: inflate failed %08x", err);
return 0;
}
inflateEnd(&stream);
if (crc32AddrPtr) {
crc = crc32(0L, Z_NULL, 0);
*crc32AddrPtr = crc32(crc, outBufferPtr, stream.total_out);
}
return stream.total_out;
return CommonDecompress(MAX_WBITS, OutBuffer, OutBufferLength, InBuffer, Crc32Addr);
}
const HLEFunction sceDeflt[] = {
@ -166,11 +82,11 @@ const HLEFunction sceDeflt[] = {
{0X106A3552, nullptr, "sceGzipGetName", '?', "" },
{0X1B5B82BC, nullptr, "sceGzipIsValid", '?', "" },
{0X2EE39A64, nullptr, "sceZlibAdler32", '?', "" },
{0X44054E03, &WrapI_UIUU<sceDeflateDecompress>, "sceDeflateDecompress", 'i', "xixx"},
{0X44054E03, &WrapI_UIUU<sceDeflateDecompress>, "sceDeflateDecompress", 'i', "xixp"},
{0X6A548477, nullptr, "sceZlibGetCompressedData", '?', "" },
{0X6DBCF897, &WrapI_UIUU<sceGzipDecompress>, "sceGzipDecompress", 'i', "xixx"},
{0X6DBCF897, &WrapI_UIUU<sceGzipDecompress>, "sceGzipDecompress", 'i', "xixp"},
{0X8AA82C92, nullptr, "sceGzipGetInfo", '?', "" },
{0XA9E4FB28, &WrapI_UIUU<sceZlibDecompress>, "sceZlibDecompress", 'i', "xixx"},
{0XA9E4FB28, &WrapI_UIUU<sceZlibDecompress>, "sceZlibDecompress", 'i', "xixp"},
{0XAFE01FD3, nullptr, "sceZlibGetInfo", '?', "" },
{0XB767F9A0, nullptr, "sceGzipGetComment", '?', "" },
{0XE46EB986, nullptr, "sceZlibIsValid", '?', "" },

View File

@ -50,8 +50,9 @@ static int __DmacMemcpy(u32 dst, u32 src, u32 size) {
skip = gpu->PerformMemoryCopy(dst, src, size);
}
if (!skip) {
// TODO: InvalidateICache src before copy?
Memory::Memcpy(dst, Memory::GetPointer(src), size, "DmacMemcpy");
currentMIPS->InvalidateICache(src, size);
const std::string tag = "DmacMemcpy/" + GetMemWriteTagAt(src, size);
Memory::Memcpy(dst, src, size, tag.c_str(), tag.size());
currentMIPS->InvalidateICache(dst, size);
}

View File

@ -26,6 +26,7 @@
#include "Common/Serialize/SerializeFuncs.h"
#include "Common/Serialize/SerializeMap.h"
#include "Common/Serialize/SerializeSet.h"
#include "Common/StringUtils.h"
#include "Core/Core.h"
#include "Core/Config.h"
#include "Core/ConfigValues.h"
@ -777,6 +778,14 @@ void __IoShutdown() {
memStickFatCallbacks.clear();
}
static std::string IODetermineFilename(FileNode *f) {
uint64_t offset = pspFileSystem.GetSeekPos(f->handle);
if ((pspFileSystem.DevType(f->handle) & PSPDevType::BLOCK) != 0) {
return StringFromFormat("%s offset 0x%08llx", f->fullpath.c_str(), offset * 2048);
}
return StringFromFormat("%s offset 0x%08llx", f->fullpath.c_str(), offset);
}
u32 __IoGetFileHandleFromId(u32 id, u32 &outError)
{
FileNode *f = __IoGetFd(id, outError);
@ -1026,7 +1035,8 @@ static bool __IoRead(int &result, int id, u32 data_addr, int size, int &us) {
result = SCE_KERNEL_ERROR_ILLEGAL_ADDR;
return true;
} else if (Memory::IsValidAddress(data_addr)) {
NotifyMemInfo(MemBlockFlags::WRITE, data_addr, size, "IoRead");
const std::string tag = "IoRead/" + IODetermineFilename(f);
NotifyMemInfo(MemBlockFlags::WRITE, data_addr, size, tag.c_str(), tag.size());
u8 *data = (u8 *)Memory::GetPointer(data_addr);
u32 validSize = Memory::ValidSize(data_addr, size);
if (f->npdrm) {
@ -1162,7 +1172,8 @@ static bool __IoWrite(int &result, int id, u32 data_addr, int size, int &us) {
return true;
}
NotifyMemInfo(MemBlockFlags::READ, data_addr, size, "IoWrite");
const std::string tag = "IoWrite/" + IODetermineFilename(f);
NotifyMemInfo(MemBlockFlags::READ, data_addr, size, tag.c_str(), tag.size());
bool useThread = __KernelIsDispatchEnabled() && ioManagerThreadEnabled && size > IO_THREAD_MIN_DATA_SIZE;
if (useThread) {

View File

@ -658,8 +658,9 @@ static u32 sceKernelMemcpy(u32 dst, u32 src, u32 size)
}
}
NotifyMemInfo(MemBlockFlags::READ, src, size, "KernelMemcpy");
NotifyMemInfo(MemBlockFlags::WRITE, dst, size, "KernelMemcpy");
const std::string tag = "KernelMemcpy/" + GetMemWriteTagAt(src, size);
NotifyMemInfo(MemBlockFlags::READ, src, size, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, dst, size, tag.c_str(), tag.size());
return dst;
}
@ -690,8 +691,9 @@ static u32 sysclib_memcpy(u32 dst, u32 src, u32 size) {
if (Memory::IsValidRange(dst, size) && Memory::IsValidRange(src, size)) {
memcpy(Memory::GetPointer(dst), Memory::GetPointer(src), size);
}
NotifyMemInfo(MemBlockFlags::READ, src, size, "KernelMemcpy");
NotifyMemInfo(MemBlockFlags::WRITE, dst, size, "KernelMemcpy");
const std::string tag = "KernelMemcpy/" + GetMemWriteTagAt(src, size);
NotifyMemInfo(MemBlockFlags::READ, src, size, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, dst, size, tag.c_str(), tag.size());
return dst;
}
@ -790,8 +792,9 @@ static u32 sysclib_memmove(u32 dst, u32 src, u32 size) {
if (Memory::IsValidRange(dst, size) && Memory::IsValidRange(src, size)) {
memmove(Memory::GetPointer(dst), Memory::GetPointer(src), size);
}
NotifyMemInfo(MemBlockFlags::READ, src, size, "KernelMemmove");
NotifyMemInfo(MemBlockFlags::WRITE, dst, size, "KernelMemmove");
const std::string tag = "KernelMemmove/" + GetMemWriteTagAt(src, size);
NotifyMemInfo(MemBlockFlags::READ, src, size, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, dst, size, tag.c_str(), tag.size());
return 0;
}

View File

@ -149,6 +149,8 @@ void VagDecoder::GetSamples(s16 *outSamples, int numSamples) {
}
if (readp > origp) {
if (g_Config.bDebugMemInfoDetailed)
NotifyMemInfo(MemBlockFlags::READ, read_, readp - origp, "SasVagDecoder");
read_ += readp - origp;
}
}
@ -426,7 +428,7 @@ void SasVoice::ReadSamples(s16 *output, int numSamples) {
pcmIndex = 0;
break;
}
Memory::Memcpy(out, pcmAddr + pcmIndex * sizeof(s16), size * sizeof(s16));
Memory::Memcpy(out, pcmAddr + pcmIndex * sizeof(s16), size * sizeof(s16), "SasVoicePCM");
pcmIndex += size;
needed -= size;
out += size;
@ -580,6 +582,11 @@ void SasInstance::Mix(u32 outAddr, u32 inAddr, int leftVol, int rightVol) {
if (outputMode == PSP_SAS_OUTPUTMODE_MIXED) {
// Okay, apply effects processing to the Send buffer.
WriteMixedOutput(outp, inp, leftVol, rightVol);
if (g_Config.bDebugMemInfoDetailed) {
if (inp)
NotifyMemInfo(MemBlockFlags::READ, inAddr, grainSize * sizeof(u16) * 2, "SasMix");
NotifyMemInfo(MemBlockFlags::WRITE, outAddr, grainSize * sizeof(u16) * 2, "SasMix");
}
} else {
s16 *outpL = outp + grainSize * 0;
s16 *outpR = outp + grainSize * 1;
@ -592,6 +599,7 @@ void SasInstance::Mix(u32 outAddr, u32 inAddr, int leftVol, int rightVol) {
*outpSendL++ = clamp_s16(sendBuffer[i + 0]);
*outpSendR++ = clamp_s16(sendBuffer[i + 1]);
}
NotifyMemInfo(MemBlockFlags::WRITE, outAddr, grainSize * sizeof(u16) * 4, "SasMix");
}
memset(mixBuffer, 0, grainSize * sizeof(int) * 2);
memset(sendBuffer, 0, grainSize * sizeof(int) * 2);

View File

@ -35,7 +35,7 @@ public:
if (!Memory::IsValidAddress((u32)(address+length-1)))
return false;
Memory::Memcpy((u32)address,data,(u32)length);
Memory::Memcpy((u32)address, data, (u32)length, "Debugger");
// In case this is a delay slot or combined instruction, clear cache above it too.
if (MIPSComp::jit)

View File

@ -30,31 +30,76 @@ extern MIPSState *currentMIPS;
namespace Memory
{
inline void Memcpy(const u32 to_address, const void *from_data, const u32 len, const char *tag = "Memcpy") {
inline void Memcpy(const u32 to_address, const void *from_data, const u32 len, const char *tag, size_t tagLen) {
u8 *to = GetPointer(to_address);
if (to) {
memcpy(to, from_data, len);
size_t tagLen = strlen(tag);
if (!tag) {
tag = "Memcpy";
tagLen = sizeof("Memcpy") - 1;
}
NotifyMemInfo(MemBlockFlags::WRITE, to_address, len, tag, tagLen);
}
// if not, GetPointer will log.
}
inline void Memcpy(void *to_data, const u32 from_address, const u32 len, const char *tag = "Memcpy") {
inline void Memcpy(void *to_data, const u32 from_address, const u32 len, const char *tag, size_t tagLen) {
const u8 *from = GetPointer(from_address);
if (from) {
memcpy(to_data, from, len);
size_t tagLen = strlen(tag);
if (!tag) {
tag = "Memcpy";
tagLen = sizeof("Memcpy") - 1;
}
NotifyMemInfo(MemBlockFlags::READ, from_address, len, tag, tagLen);
}
// if not, GetPointer will log.
}
inline void Memcpy(const u32 to_address, const u32 from_address, const u32 len, const char *tag = "Memcpy") {
Memcpy(GetPointer(to_address), from_address, len);
size_t tagLen = strlen(tag);
NotifyMemInfo(MemBlockFlags::READ, from_address, len, tag, tagLen);
NotifyMemInfo(MemBlockFlags::WRITE, to_address, len, tag, tagLen);
inline void Memcpy(const u32 to_address, const u32 from_address, const u32 len, const char *tag, size_t tagLen) {
u8 *to = GetPointer(to_address);
if (to) {
const u8 *from = GetPointer(from_address);
if (from) {
memcpy(to, from, len);
char tagData[128];
if (!tag) {
const std::string srcTag = GetMemWriteTagAt(from_address, len);
tag = tagData;
tagLen = snprintf(tagData, sizeof(tagData), "Memcpy/%s", srcTag.c_str());
}
NotifyMemInfo(MemBlockFlags::READ, from_address, len, tag, tagLen);
NotifyMemInfo(MemBlockFlags::WRITE, to_address, len, tag, tagLen);
}
}
// if not, GetPointer will log.
}
template<size_t tagLen>
inline void Memcpy(const u32 to_address, const void *from_data, const u32 len, const char(&tag)[tagLen]) {
Memcpy(to_address, from_data, len, tag, tagLen);
}
template<size_t tagLen>
inline void Memcpy(void *to_data, const u32 from_address, const u32 len, const char(&tag)[tagLen]) {
Memcpy(to_data, from_address, len, tag, tagLen);
}
template<size_t tagLen>
inline void Memcpy(const u32 to_address, const u32 from_address, const u32 len, const char(&tag)[tagLen]) {
Memcpy(to_address, from_address, len, tag, tagLen);
}
inline void Memcpy(const u32 to_address, const void *from_data, const u32 len) {
Memcpy(to_address, from_data, len, nullptr, 0);
}
inline void Memcpy(void *to_data, const u32 from_address, const u32 len) {
Memcpy(to_data, from_address, len, nullptr, 0);
}
inline void Memcpy(const u32 to_address, const u32 from_address, const u32 len) {
Memcpy(to_address, from_address, len, nullptr, 0);
}
void Memset(const u32 _Address, const u8 _Data, const u32 _iLength, const char *tag = "Memset");

View File

@ -2179,7 +2179,9 @@ void FramebufferManagerCommon::PackFramebufferSync_(VirtualFramebuffer *vfb, int
if (destPtr) {
draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_COLOR_BIT, x, y, w, h, destFormat, destPtr, vfb->fb_stride, "PackFramebufferSync_");
NotifyMemInfo(MemBlockFlags::WRITE, fb_address + dstByteOffset, dstSize, "FramebufferPack");
char tag[128];
size_t len = snprintf(tag, sizeof(tag), "FramebufferPack/%08x_%08x_%dx%d_%s", vfb->fb_address, vfb->z_address, w, h, GeBufferFormatToString(vfb->format));
NotifyMemInfo(MemBlockFlags::WRITE, fb_address + dstByteOffset, dstSize, tag, len);
} else {
ERROR_LOG(G3D, "PackFramebufferSync_: Tried to readback to bad address %08x (stride = %d)", fb_address + dstByteOffset, vfb->fb_stride);
}

View File

@ -2721,8 +2721,11 @@ void GPUCommon::DoBlockTransfer(u32 skipDrawReason) {
framebufferManager_->NotifyBlockTransferAfter(dstBasePtr, dstStride, dstX, dstY, srcBasePtr, srcStride, srcX, srcY, width, height, bpp, skipDrawReason);
}
NotifyMemInfo(MemBlockFlags::READ, srcBasePtr + (srcY * srcStride + srcX) * bpp, height * srcStride * bpp, "GPUBlockTransfer");
NotifyMemInfo(MemBlockFlags::WRITE, dstBasePtr + (dstY * dstStride + dstX) * bpp, height * dstStride * bpp, "GPUBlockTransfer");
const uint32_t src = srcBasePtr + (srcY * srcStride + srcX) * bpp;
const uint32_t srcSize = height * srcStride * bpp;
const std::string tag = "GPUBlockTransfer/" + GetMemWriteTagAt(src, srcSize);
NotifyMemInfo(MemBlockFlags::READ, src, srcSize, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, dstBasePtr + (dstY * dstStride + dstX) * bpp, height * dstStride * bpp, tag.c_str(), tag.size());
// TODO: Correct timing appears to be 1.9, but erring a bit low since some of our other timing is inaccurate.
cyclesExecuted += ((height * width * bpp) * 16) / 10;
@ -2735,15 +2738,17 @@ bool GPUCommon::PerformMemoryCopy(u32 dest, u32 src, int size) {
// We use a little hack for PerformMemoryDownload/PerformMemoryUpload using a VRAM mirror.
// Since they're identical we don't need to copy.
if (!Memory::IsVRAMAddress(dest) || (dest ^ 0x00400000) != src) {
Memory::Memcpy(dest, src, size);
const std::string tag = "GPUMemcpy/" + GetMemWriteTagAt(src, size);
Memory::Memcpy(dest, src, size, tag.c_str(), tag.size());
}
}
InvalidateCache(dest, size, GPU_INVALIDATE_HINT);
return true;
}
NotifyMemInfo(MemBlockFlags::READ, src, size, "GPUMemcpy");
NotifyMemInfo(MemBlockFlags::WRITE, dest, size, "GPUMemcpy");
const std::string tag = "GPUMemcpy/" + GetMemWriteTagAt(src, size);
NotifyMemInfo(MemBlockFlags::READ, src, size, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, dest, size, tag.c_str(), tag.size());
InvalidateCache(dest, size, GPU_INVALIDATE_HINT);
GPURecord::NotifyMemcpy(dest, src, size);
return false;

View File

@ -653,8 +653,11 @@ void SoftGPU::ExecuteOp(u32 op, u32 diff) {
memcpy(dst, src, width * bpp);
}
NotifyMemInfo(MemBlockFlags::READ, srcBasePtr + (srcY * srcStride + srcX) * bpp, height * srcStride * bpp, "GPUBlockTransfer");
NotifyMemInfo(MemBlockFlags::WRITE, dstBasePtr + (dstY * dstStride + dstX) * bpp, height * dstStride * bpp, "GPUBlockTransfer");
const uint32_t src = srcBasePtr + (srcY * srcStride + srcX) * bpp;
const uint32_t srcSize = height * srcStride * bpp;
const std::string tag = "GPUBlockTransfer/" + GetMemWriteTagAt(src, srcSize);
NotifyMemInfo(MemBlockFlags::READ, src, srcSize, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, dstBasePtr + (dstY * dstStride + dstX) * bpp, height * dstStride * bpp, tag.c_str(), tag.size());
// TODO: Correct timing appears to be 1.9, but erring a bit low since some of our other timing is inaccurate.
cyclesExecuted += ((height * width * bpp) * 16) / 10;

View File

@ -533,6 +533,28 @@ void CtrlMemView::onMouseUp(WPARAM wParam, LPARAM lParam, int button)
}
break;
case ID_MEMVIEW_EXTENTBEGIN:
{
std::vector<MemBlockInfo> memRangeInfo = FindMemInfoByFlag(highlightFlags_, curAddress, 1);
uint32_t addr = curAddress;
for (MemBlockInfo info : memRangeInfo) {
addr = info.start;
}
gotoAddr(addr);
break;
}
case ID_MEMVIEW_EXTENTEND:
{
std::vector<MemBlockInfo> memRangeInfo = FindMemInfoByFlag(highlightFlags_, curAddress, 1);
uint32_t addr = curAddress;
for (MemBlockInfo info : memRangeInfo) {
addr = info.start + info.size - 1;
}
gotoAddr(addr);
break;
}
case ID_MEMVIEW_COPYADDRESS:
{
char temp[24];
@ -845,6 +867,7 @@ void CtrlMemView::toggleOffsetScale(CommonToggles toggle)
void CtrlMemView::setHighlightType(MemBlockFlags flags) {
if (highlightFlags_ != flags) {
highlightFlags_ = flags;
updateStatusBarText();
redraw();
}
}

View File

@ -679,6 +679,9 @@ BEGIN
MENUITEM "Go to in Disasm", ID_MEMVIEW_GOTOINDISASM
MENUITEM "Copy address", ID_MEMVIEW_COPYADDRESS
MENUITEM SEPARATOR
MENUITEM "Go to Extent Begin", ID_MEMVIEW_EXTENTBEGIN
MENUITEM "Go to Extent End", ID_MEMVIEW_EXTENTEND
MENUITEM SEPARATOR
MENUITEM "Copy Value (8 bit)", ID_MEMVIEW_COPYVALUE_8
MENUITEM "Copy Value (16 bit)", ID_MEMVIEW_COPYVALUE_16
MENUITEM "Copy Value (32 bit)", ID_MEMVIEW_COPYVALUE_32

View File

@ -376,6 +376,8 @@
#define ID_FILE_DUMP_VIDEO_OUTPUT 40204
#define ID_EMULATION_CHAT 40205
#define IDC_MEMVIEW_STATUS 40206
#define ID_MEMVIEW_EXTENTBEGIN 40207
#define ID_MEMVIEW_EXTENTEND 40208
// Dummy option to let the buffered rendering hotkey cycle through all the options.
#define ID_OPTIONS_BUFFEREDRENDERINGDUMMY 40500
@ -388,7 +390,7 @@
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 256
#define _APS_NEXT_COMMAND_VALUE 40207
#define _APS_NEXT_COMMAND_VALUE 40209
#define _APS_NEXT_CONTROL_VALUE 1202
#define _APS_NEXT_SYMED_VALUE 101
#endif