diff --git a/rocclr/runtime/device/device.cpp b/rocclr/runtime/device/device.cpp index 0d96f97977..c299f2cc74 100644 --- a/rocclr/runtime/device/device.cpp +++ b/rocclr/runtime/device/device.cpp @@ -689,11 +689,7 @@ Memory::saveMapInfo( WriteMapInfo* pInfo = &info; auto it = writeMapInfo_.find(mapAddress); if (it != writeMapInfo_.end()) { - LogWarning("Double map of the same region!"); - } - else { - writeMapInfo_.insert(std::pair(mapAddress, info)); - it = writeMapInfo_.find(mapAddress); + LogWarning("Double map of the same or overlapped region!"); pInfo = &it->second; } @@ -707,6 +703,12 @@ Memory::saveMapInfo( pInfo->unmapRead_ = true; } pInfo->baseMip_ = baseMip; + + // Insert into the map if it's the first region + if (++pInfo->count_ == 1) { + writeMapInfo_.insert(std::pair(mapAddress, info)); + } + } Program::Program(amd::Device& device) diff --git a/rocclr/runtime/device/device.hpp b/rocclr/runtime/device/device.hpp index 239882ab32..901e42049a 100644 --- a/rocclr/runtime/device/device.hpp +++ b/rocclr/runtime/device/device.hpp @@ -629,13 +629,14 @@ public: SyncFlags(): value_(0) {} }; - struct WriteMapInfo: public amd::EmbeddedObject + struct WriteMapInfo: public amd::HeapObject { amd::Coord3D origin_; //!< Origin of the map location amd::Coord3D region_; //!< Mapped region amd::Image* baseMip_; //!< The base mip level for images union { struct { + uint32_t count_: 8; //!< The same map region counter uint32_t unmapWrite_: 1; //!< Unmap write operation uint32_t unmapRead_: 1; //!< Unmap read operation uint32_t entire_: 1; //!< Process the entire memory @@ -766,7 +767,7 @@ public: auto it = writeMapInfo_.find(mapAddress); if (it == writeMapInfo_.end()) { if (writeMapInfo_.size() == 0) { - assert(false && "Unmap() call without map!"); + LogError("Unmap is a NOP!"); return nullptr; } LogWarning("Unknown unmap signature!"); @@ -786,7 +787,9 @@ public: // Get the first map info it = writeMapInfo_.begin(); } - writeMapInfo_.erase(it); + if (--it->second.count_ == 0) { + writeMapInfo_.erase(it); + } } //! Returns state of memory direct access flag diff --git a/rocclr/runtime/device/gpu/gpuvirtual.cpp b/rocclr/runtime/device/gpu/gpuvirtual.cpp index 311b8c31ff..ef9773d503 100644 --- a/rocclr/runtime/device/gpu/gpuvirtual.cpp +++ b/rocclr/runtime/device/gpu/gpuvirtual.cpp @@ -1179,12 +1179,16 @@ VirtualGPU::submitUnmapMemory(amd::UnmapMemoryCommand& vcmd) // Make sure VirtualGPU has an exclusive access to the resources amd::ScopedLock lock(execution()); - profilingBegin(vcmd, true); gpu::Memory* memory = dev().getGpuMemory(&vcmd.memory()); amd::Memory* owner = memory->owner(); bool unmapMip = false; const device::Memory::WriteMapInfo* writeMapInfo = memory->writeMapInfo(vcmd.mapPtr()); + if (nullptr == writeMapInfo) { + LogError("Unmap without map call"); + return; + } + profilingBegin(vcmd, true); // Check if image is a mipmap and assign a saved view amd::Image* amdImage = owner->asImage(); diff --git a/rocclr/runtime/device/pal/palvirtual.cpp b/rocclr/runtime/device/pal/palvirtual.cpp index 8909c0172a..2912ec7afc 100644 --- a/rocclr/runtime/device/pal/palvirtual.cpp +++ b/rocclr/runtime/device/pal/palvirtual.cpp @@ -1422,12 +1422,16 @@ VirtualGPU::submitUnmapMemory(amd::UnmapMemoryCommand& vcmd) // Make sure VirtualGPU has an exclusive access to the resources amd::ScopedLock lock(execution()); - profilingBegin(vcmd, true); pal::Memory* memory = dev().getGpuMemory(&vcmd.memory()); amd::Memory* owner = memory->owner(); bool unmapMip = false; const device::Memory::WriteMapInfo* writeMapInfo = memory->writeMapInfo(vcmd.mapPtr()); + if (nullptr == writeMapInfo) { + LogError("Unmap without map call"); + return; + } + profilingBegin(vcmd, true); // Check if image is a mipmap and assign a saved view amd::Image* amdImage = owner->asImage();