diff --git a/Core/Debugger/MemBlockInfo.cpp b/Core/Debugger/MemBlockInfo.cpp index ac2b35a4dd..f0be93ea60 100644 --- a/Core/Debugger/MemBlockInfo.cpp +++ b/Core/Debugger/MemBlockInfo.cpp @@ -37,6 +37,7 @@ public: bool Mark(uint32_t addr, uint32_t size, uint64_t ticks, uint32_t pc, bool allocated, const char *tag); bool Find(MemBlockFlags flags, uint32_t addr, uint32_t size, std::vector &results); + bool FastFindWriteTag(MemBlockFlags flags, uint32_t addr, uint32_t size, std::string &result); void Reset(); void DoState(PointerWrap &p); @@ -87,8 +88,10 @@ static MemSlabMap suballocMap; static MemSlabMap writeMap; static MemSlabMap textureMap; static std::vector pendingNotifies; -static std::atomic pendingNotifyMinAddr; -static std::atomic pendingNotifyMaxAddr; +static std::atomic pendingNotifyMinAddr1; +static std::atomic pendingNotifyMaxAddr1; +static std::atomic pendingNotifyMinAddr2; +static std::atomic pendingNotifyMaxAddr2; static std::mutex pendingMutex; static int detailedOverride; @@ -139,7 +142,7 @@ bool MemSlabMap::Find(MemBlockFlags flags, uint32_t addr, uint32_t size, std::ve Slab *slab = FindSlab(addr); bool found = false; while (slab != nullptr && slab->start < end) { - if (slab->pc != 0 || strlen(slab->tag)) { + if (slab->pc != 0 || slab->tag[0] != '\0') { results.push_back({ flags, slab->start, slab->end - slab->start, slab->ticks, slab->pc, slab->tag, slab->allocated }); found = true; } @@ -148,6 +151,19 @@ bool MemSlabMap::Find(MemBlockFlags flags, uint32_t addr, uint32_t size, std::ve return found; } +bool MemSlabMap::FastFindWriteTag(MemBlockFlags flags, uint32_t addr, uint32_t size, std::string &result) { + uint32_t end = addr + size; + Slab *slab = FindSlab(addr); + while (slab != nullptr && slab->start < end) { + if (slab->pc != 0 || slab->tag[0] != '\0') { + result = slab->tag; + return true; + } + slab = slab->next; + } + return false; +} + void MemSlabMap::Reset() { Clear(); @@ -377,8 +393,10 @@ void FlushPendingMemInfo() { } } pendingNotifies.clear(); - pendingNotifyMinAddr = 0xFFFFFFFF; - pendingNotifyMaxAddr = 0; + pendingNotifyMinAddr1 = 0xFFFFFFFF; + pendingNotifyMaxAddr1 = 0; + pendingNotifyMinAddr2 = 0xFFFFFFFF; + pendingNotifyMaxAddr2 = 0; } void NotifyMemInfoPC(MemBlockFlags flags, uint32_t start, uint32_t size, uint32_t pc, const char *tagStr, size_t strLength) { @@ -403,8 +421,13 @@ void NotifyMemInfoPC(MemBlockFlags flags, uint32_t start, uint32_t size, uint32_ info.tag[copyLength] = 0; std::lock_guard guard(pendingMutex); - pendingNotifyMinAddr = std::min(pendingNotifyMinAddr.load(), start); - pendingNotifyMaxAddr = std::max(pendingNotifyMaxAddr.load(), start + size); + if (start < 0x08000000) { + pendingNotifyMinAddr1 = std::min(pendingNotifyMinAddr1.load(), start); + pendingNotifyMaxAddr1 = std::max(pendingNotifyMaxAddr1.load(), start + size); + } else { + pendingNotifyMinAddr2 = std::min(pendingNotifyMinAddr2.load(), start); + pendingNotifyMaxAddr2 = std::max(pendingNotifyMaxAddr2.load(), start + size); + } pendingNotifies.push_back(info); needFlush = pendingNotifies.size() > MAX_PENDING_NOTIFIES; } @@ -429,7 +452,9 @@ void NotifyMemInfo(MemBlockFlags flags, uint32_t start, uint32_t size, const cha std::vector FindMemInfo(uint32_t start, uint32_t size) { start &= ~0xC0000000; - if (pendingNotifyMinAddr < start + size && pendingNotifyMaxAddr >= start) + if (pendingNotifyMinAddr1 < start + size && pendingNotifyMaxAddr1 >= start) + FlushPendingMemInfo(); + if (pendingNotifyMinAddr2 < start + size && pendingNotifyMaxAddr2 >= start) FlushPendingMemInfo(); std::vector results; @@ -443,7 +468,9 @@ std::vector FindMemInfo(uint32_t start, uint32_t size) { std::vector FindMemInfoByFlag(MemBlockFlags flags, uint32_t start, uint32_t size) { start &= ~0xC0000000; - if (pendingNotifyMinAddr < start + size && pendingNotifyMaxAddr >= start) + if (pendingNotifyMinAddr1 < start + size && pendingNotifyMaxAddr1 >= start) + FlushPendingMemInfo(); + if (pendingNotifyMinAddr2 < start + size && pendingNotifyMaxAddr2 >= start) FlushPendingMemInfo(); std::vector results; @@ -458,25 +485,54 @@ std::vector FindMemInfoByFlag(MemBlockFlags flags, uint32_t start, return results; } -std::string GetMemWriteTagAt(uint32_t start, uint32_t size) { - std::vector memRangeInfo = FindMemInfoByFlag(MemBlockFlags::WRITE, start, size); - for (auto range : memRangeInfo) { - return range.tag; +static std::string FindWriteTagByFlag(MemBlockFlags flags, uint32_t start, uint32_t size) { + start &= ~0xC0000000; + + if (pendingNotifyMinAddr1 < start + size && pendingNotifyMaxAddr1 >= start) + FlushPendingMemInfo(); + if (pendingNotifyMinAddr2 < start + size && pendingNotifyMaxAddr2 >= start) + FlushPendingMemInfo(); + + std::string tag; + if (flags & MemBlockFlags::ALLOC) { + if (allocMap.FastFindWriteTag(MemBlockFlags::ALLOC, start, size, tag)) + return tag; } + if (flags & MemBlockFlags::SUB_ALLOC) { + if (suballocMap.FastFindWriteTag(MemBlockFlags::SUB_ALLOC, start, size, tag)) + return tag; + } + if (flags & MemBlockFlags::WRITE) { + if (writeMap.FastFindWriteTag(MemBlockFlags::WRITE, start, size, tag)) + return tag; + } + if (flags & MemBlockFlags::TEXTURE) { + if (textureMap.FastFindWriteTag(MemBlockFlags::TEXTURE, start, size, tag)) + return tag; + } + return ""; +} + +std::string GetMemWriteTagAt(uint32_t start, uint32_t size) { + std::string tag = FindWriteTagByFlag(MemBlockFlags::WRITE, start, size); + if (!tag.empty() && tag != "MemInit") + return 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"; + tag = FindWriteTagByFlag(MemBlockFlags::ALLOC | MemBlockFlags::TEXTURE, start, size); + if (!tag.empty()) + return tag; + + return StringFromFormat("%08x_size_%08x", start, size); } void MemBlockInfoInit() { std::lock_guard guard(pendingMutex); pendingNotifies.reserve(MAX_PENDING_NOTIFIES); - pendingNotifyMinAddr = 0xFFFFFFFF; - pendingNotifyMaxAddr = 0; + pendingNotifyMinAddr1 = 0xFFFFFFFF; + pendingNotifyMaxAddr1 = 0; + pendingNotifyMinAddr2 = 0xFFFFFFFF; + pendingNotifyMaxAddr2 = 0; } void MemBlockInfoShutdown() { diff --git a/GPU/Software/Rasterizer.cpp b/GPU/Software/Rasterizer.cpp index 126f2cb852..8fff0f3f4e 100644 --- a/GPU/Software/Rasterizer.cpp +++ b/GPU/Software/Rasterizer.cpp @@ -1038,7 +1038,7 @@ void DrawPoint(const VertexData &v0, const BinCoords &range, const RasterizerSta auto &pixelID = state.pixelID; auto &samplerID = state.samplerID; - if (state.enableTextures && !pixelID.clearMode) { + if (state.enableTextures) { float s = v0.texturecoords.s(); float t = v0.texturecoords.t(); if (state.throughMode) { @@ -1064,7 +1064,7 @@ void DrawPoint(const VertexData &v0, const BinCoords &range, const RasterizerSta u16 z = pos.z; u8 fog = 255; - if (pixelID.applyFog && !pixelID.clearMode) { + if (pixelID.applyFog) { fog = ClampFogDepth(v0.fogdepth); } @@ -1315,7 +1315,7 @@ void DrawLine(const VertexData &v0, const VertexData &v1, const BinCoords &range } u8 fog = 255; - if (pixelID.applyFog && !pixelID.clearMode) { + if (pixelID.applyFog) { fog = ClampFogDepth((v0.fogdepth * (float)(steps - i) + v1.fogdepth * (float)i) / steps1); } @@ -1325,7 +1325,7 @@ void DrawLine(const VertexData &v0, const VertexData &v1, const BinCoords &range prim_color.a() = 0x7F; } - if (state.enableTextures && !pixelID.clearMode) { + if (state.enableTextures) { float s, s1; float t, t1; if (state.throughMode) { diff --git a/GPU/Software/SoftGpu.cpp b/GPU/Software/SoftGpu.cpp index b0f313a749..4ddb947c04 100644 --- a/GPU/Software/SoftGpu.cpp +++ b/GPU/Software/SoftGpu.cpp @@ -792,10 +792,24 @@ void SoftGPU::Execute_BlockTransferStart(u32 op, u32 diff) { DEBUG_LOG(G3D, "Block transfer: %08x/%x -> %08x/%x, %ix%ix%i (%i,%i)->(%i,%i)", srcBasePtr, srcStride, dstBasePtr, dstStride, width, height, bpp, srcX, srcY, dstX, dstY); - for (int y = 0; y < height; y++) { - const u8 *srcp = Memory::GetPointer(srcBasePtr + ((y + srcY) * srcStride + srcX) * bpp); - u8 *dstp = Memory::GetPointer(dstBasePtr + ((y + dstY) * dstStride + dstX) * bpp); - memcpy(dstp, srcp, width * bpp); + if (srcStride == dstStride && (u32)width == srcStride) { + u32 srcLineStartAddr = srcBasePtr + (srcY * srcStride + srcX) * bpp; + u32 dstLineStartAddr = dstBasePtr + (dstY * dstStride + dstX) * bpp; + + const u8 *srcp = Memory::GetPointer(srcLineStartAddr); + u8 *dstp = Memory::GetPointer(dstLineStartAddr); + memcpy(dstp, srcp, width * height * bpp); + GPURecord::NotifyMemcpy(dstLineStartAddr, srcLineStartAddr, width * height * bpp); + } else { + for (int y = 0; y < height; y++) { + u32 srcLineStartAddr = srcBasePtr + ((y + srcY) * srcStride + srcX) * bpp; + u32 dstLineStartAddr = dstBasePtr + ((y + dstY) * dstStride + dstX) * bpp; + + const u8 *srcp = Memory::GetPointer(srcLineStartAddr); + u8 *dstp = Memory::GetPointer(dstLineStartAddr); + memcpy(dstp, srcp, width * bpp); + GPURecord::NotifyMemcpy(dstLineStartAddr, srcLineStartAddr, width * bpp); + } } if (MemBlockInfoDetailed(srcSize, dstSize)) {