From a9c0cb3fe5a7edc28cf7a182cfd3a11cf506553b Mon Sep 17 00:00:00 2001 From: "Bernhart, Bryan" Date: Fri, 6 Jan 2023 13:26:44 -0800 Subject: [PATCH] Report object to event-console output. --- src/gpgmm/common/EventMessage.cpp | 28 +++++----------- src/gpgmm/common/EventMessage.h | 33 ++++++++++++++++--- src/gpgmm/common/MemoryAllocator.cpp | 8 ++--- src/gpgmm/common/SlabMemoryAllocator.cpp | 11 ++++--- src/gpgmm/d3d12/BufferAllocatorD3D12.cpp | 2 +- src/gpgmm/d3d12/ResidencyManagerD3D12.cpp | 16 ++++----- src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp | 13 ++++---- .../d3d12/ResourceHeapAllocatorD3D12.cpp | 6 ++-- src/gpgmm/vk/DeviceMemoryAllocatorVk.cpp | 3 +- src/gpgmm/vk/ResourceAllocatorVk.cpp | 3 +- 10 files changed, 70 insertions(+), 53 deletions(-) diff --git a/src/gpgmm/common/EventMessage.cpp b/src/gpgmm/common/EventMessage.cpp index 2705adf95..755439eca 100644 --- a/src/gpgmm/common/EventMessage.cpp +++ b/src/gpgmm/common/EventMessage.cpp @@ -16,6 +16,7 @@ #include "gpgmm/common/TraceEvent.h" #include "gpgmm/utils/Assert.h" +#include "gpgmm/utils/Utils.h" #include @@ -45,15 +46,18 @@ namespace gpgmm { // EventMessage - EventMessage::EventMessage(const LogSeverity& level, const char* name, EventMessageId messageId) - : mSeverity(level), mName(name), mMessageId(messageId) { + EventMessage::EventMessage(const LogSeverity& level, + const char* name, + const void* object, + EventMessageId messageId) + : mSeverity(level), mName(name), mObject(object), mMessageId(messageId) { } EventMessage::~EventMessage() { const std::string description = mStream.str(); - gpgmm::Log(mSeverity) << mName << "(" << static_cast(mMessageId) << ")" - << ": " << description; + gpgmm::Log(mSeverity) << mName << "=" << ToString(mObject) << ": " << description << " (" + << static_cast(mMessageId) << ")"; #if defined(GPGMM_ENABLE_ASSERT_ON_WARNING) ASSERT(mSeverity < LogSeverity::Warning); @@ -65,20 +69,4 @@ namespace gpgmm { } } - EventMessage DebugEvent(const char* name, EventMessageId messageId) { - return {LogSeverity::Debug, name, messageId}; - } - - EventMessage InfoEvent(const char* name, EventMessageId messageId) { - return {LogSeverity::Info, name, messageId}; - } - - EventMessage WarnEvent(const char* name, EventMessageId messageId) { - return {LogSeverity::Warning, name, messageId}; - } - - EventMessage ErrorEvent(const char* name, EventMessageId messageId) { - return {LogSeverity::Error, name, messageId}; - } - } // namespace gpgmm diff --git a/src/gpgmm/common/EventMessage.h b/src/gpgmm/common/EventMessage.h index 25c2356cc..a29e87b91 100644 --- a/src/gpgmm/common/EventMessage.h +++ b/src/gpgmm/common/EventMessage.h @@ -43,6 +43,7 @@ namespace gpgmm { public: EventMessage(const LogSeverity& level, const char* name, + const void* object, EventMessageId messageId = EventMessageId::kUnknown); ~EventMessage(); @@ -58,15 +59,39 @@ namespace gpgmm { private: LogSeverity mSeverity; const char* mName = nullptr; + const void* mObject = nullptr; EventMessageId mMessageId = EventMessageId::kUnknown; std::ostringstream mStream; }; - EventMessage DebugEvent(const char* name, EventMessageId messageId = EventMessageId::kUnknown); - EventMessage InfoEvent(const char* name, EventMessageId messageId = EventMessageId::kUnknown); - EventMessage WarnEvent(const char* name, EventMessageId messageId = EventMessageId::kUnknown); - EventMessage ErrorEvent(const char* name, EventMessageId messageId = EventMessageId::kUnknown); + template + EventMessage DebugEvent(const char* name, + const T* object, + EventMessageId messageId = EventMessageId::kUnknown) { + return {LogSeverity::Debug, name, object, messageId}; + } + + template + EventMessage InfoEvent(const char* name, + const T* object, + EventMessageId messageId = EventMessageId::kUnknown) { + return {LogSeverity::Info, name, object, messageId}; + } + + template + EventMessage WarnEvent(const char* name, + const T* object, + EventMessageId messageId = EventMessageId::kUnknown) { + return {LogSeverity::Warning, name, object, messageId}; + } + + template + EventMessage ErrorEvent(const char* name, + T* object, + EventMessageId messageId = EventMessageId::kUnknown) { + return {LogSeverity::Error, name, object, messageId}; + } // Messages of a given severity to be recorded. void SetEventMessageLevel(const LogSeverity& level); diff --git a/src/gpgmm/common/MemoryAllocator.cpp b/src/gpgmm/common/MemoryAllocator.cpp index cd06fb355..9f1703009 100644 --- a/src/gpgmm/common/MemoryAllocator.cpp +++ b/src/gpgmm/common/MemoryAllocator.cpp @@ -156,7 +156,7 @@ namespace gpgmm { // Check request size cannot overflow. if (request.SizeInBytes > std::numeric_limits::max() - (request.Alignment - 1)) { - DebugEvent(GetTypename(), EventMessageId::kSizeExceeded) + DebugEvent(GetTypename(), this, EventMessageId::kSizeExceeded) << "Requested size rejected due to overflow: " + std::to_string(request.SizeInBytes) << " bytes."; return false; @@ -165,7 +165,7 @@ namespace gpgmm { // Check request size cannot overflow |this| memory allocator. const uint64_t alignedSize = AlignTo(request.SizeInBytes, request.Alignment); if (GetMemorySize() != kInvalidSize && alignedSize > GetMemorySize()) { - DebugEvent(GetTypename(), EventMessageId::kSizeExceeded) + DebugEvent(GetTypename(), this, EventMessageId::kSizeExceeded) << "Requested size exceeds memory size (" + std::to_string(alignedSize) + " vs " + std::to_string(GetMemorySize()) + " bytes)."; return false; @@ -175,7 +175,7 @@ namespace gpgmm { // Alignment value of 1 means no alignment required. if (GetMemoryAlignment() == 0 || (GetMemoryAlignment() > 1 && !IsAligned(GetMemoryAlignment(), request.Alignment))) { - DebugEvent(GetTypename(), EventMessageId::kAlignmentMismatch) + DebugEvent(GetTypename(), this, EventMessageId::kAlignmentMismatch) << "Requested alignment exceeds memory alignment (" + std::to_string(request.Alignment) + " vs " + std::to_string(GetMemoryAlignment()) + " bytes)."; @@ -201,7 +201,7 @@ namespace gpgmm { void MemoryAllocator::CheckAndReportAllocationMisalignment(const MemoryAllocation& allocation) { if (allocation.GetSize() > allocation.GetRequestSize()) { - DebugEvent(GetTypename(), EventMessageId::kAlignmentMismatch) + DebugEvent(GetTypename(), this, EventMessageId::kAlignmentMismatch) << "Resource allocation is larger then the requested size (" + std::to_string(allocation.GetSize()) + " vs " + std::to_string(allocation.GetRequestSize()) + " bytes)."; diff --git a/src/gpgmm/common/SlabMemoryAllocator.cpp b/src/gpgmm/common/SlabMemoryAllocator.cpp index 9424b903d..cbbcbbbed 100644 --- a/src/gpgmm/common/SlabMemoryAllocator.cpp +++ b/src/gpgmm/common/SlabMemoryAllocator.cpp @@ -144,8 +144,9 @@ namespace gpgmm { if (availableForAllocation < slabSize) { const uint64_t slabSizeUnderBudget = FindNextFreeSlabOfSize(requestSize); if (slabSizeUnderBudget == kInvalidSize) { - DebugEvent(GetTypename()) << "Slab size exceeds available memory: " << slabSize - << " vs " << availableForAllocation << " bytes."; + DebugEvent(GetTypename(), this) + << "Slab size exceeds available memory: " << slabSize << " vs " + << availableForAllocation << " bytes."; return kInvalidSize; } @@ -204,7 +205,7 @@ namespace gpgmm { // Slab cannot exceed memory size. if (slabSize > mMaxSlabSize) { - gpgmm::DebugEvent(GetTypename()) + gpgmm::DebugEvent(GetTypename(), this) << "Slab allocation was disabled because the size was invalid."; return {}; } @@ -281,7 +282,7 @@ namespace gpgmm { } if (prefetchedSlabAllocation != nullptr) { - DebugEvent(GetTypename(), EventMessageId::kPrefetchFailed) + DebugEvent(GetTypename(), this, EventMessageId::kPrefetchFailed) << "Pre-fetch slab memory is incompatible (" << slabSize << " vs " << prefetchedSlabAllocation->GetSize() << " bytes."; } @@ -458,7 +459,7 @@ namespace gpgmm { SafeDivide(mStats.PrefetchedMemoryMissesEliminated, mStats.PrefetchedMemoryMissesEliminated + mStats.PrefetchedMemoryMisses); if (currentCoverage < kPrefetchCoverageWarnMinThreshold) { - WarnEvent(GetTypename(), EventMessageId::kPrefetchFailed) + WarnEvent(GetTypename(), this, EventMessageId::kPrefetchFailed) << "Prefetch coverage is below threshold (%): " << currentCoverage * 100 << " vs " << kPrefetchCoverageWarnMinThreshold * 100; return false; diff --git a/src/gpgmm/d3d12/BufferAllocatorD3D12.cpp b/src/gpgmm/d3d12/BufferAllocatorD3D12.cpp index 0d920d10a..e0e8d8149 100644 --- a/src/gpgmm/d3d12/BufferAllocatorD3D12.cpp +++ b/src/gpgmm/d3d12/BufferAllocatorD3D12.cpp @@ -48,7 +48,7 @@ namespace gpgmm::d3d12 { const uint64_t heapSize = AlignTo(request.SizeInBytes, request.Alignment); if (heapSize > request.SizeInBytes) { - DebugEvent(GetTypename(), EventMessageId::kAlignmentMismatch) + DebugEvent(GetTypename(), this, EventMessageId::kAlignmentMismatch) << "Resource heap size is larger then the requested size (" + std::to_string(heapSize) + " vs " + std::to_string(request.SizeInBytes) + " bytes)."; diff --git a/src/gpgmm/d3d12/ResidencyManagerD3D12.cpp b/src/gpgmm/d3d12/ResidencyManagerD3D12.cpp index 84bca9497..eadbc249d 100644 --- a/src/gpgmm/d3d12/ResidencyManagerD3D12.cpp +++ b/src/gpgmm/d3d12/ResidencyManagerD3D12.cpp @@ -68,7 +68,7 @@ namespace gpgmm::d3d12 { break; } - gpgmm::DebugEvent("ResidencyManager", EventMessageId::kBudgetUpdated) + gpgmm::DebugEvent("ResidencyManager", this, EventMessageId::kBudgetUpdated) << "Recieved budget notification from OS."; break; } @@ -520,7 +520,7 @@ namespace gpgmm::d3d12 { // Ignore when no budget was specified. if (pVideoMemoryInfo->Budget > 0 && pVideoMemoryInfo->CurrentUsage > pVideoMemoryInfo->Budget) { - WarnEvent("ResidencyManager", EventMessageId::kBudgetExceeded) + WarnEvent(GetTypename(), this, EventMessageId::kBudgetExceeded) << GetMemorySegmentName(memorySegmentGroup, mIsUMA) << " GPU memory exceeds budget: " << GPGMM_BYTES_TO_MB(pVideoMemoryInfo->CurrentUsage) << " vs " @@ -590,7 +590,7 @@ namespace gpgmm::d3d12 { // If a budget wasn't provided, it not possible to evict. This is because either the budget // update event has not happened yet or was invalid. if (pVideoMemoryInfo->Budget == 0) { - WarnEvent("GPU page-out", EventMessageId::kBudgetInvalid) + WarnEvent(GetTypename(), this, EventMessageId::kBudgetInvalid) << "GPU memory segment (" << GetMemorySegmentName(DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL, IsUMA()) << ") was unable to evict memory because a budget was not specified."; @@ -661,9 +661,9 @@ namespace gpgmm::d3d12 { const uint32_t objectEvictCount = static_cast(objectsToEvict.size()); ReturnIfFailed(mDevice->Evict(objectEvictCount, objectsToEvict.data())); - DebugEvent("GPU page-out", EventMessageId::kBudgetExceeded) - << "Number of allocations: " << objectsToEvict.size() << " (" << bytesEvicted - << " bytes)."; + DebugEvent(GetTypename(), this, EventMessageId::kBudgetExceeded) + << "GPU page-out. Number of allocations: " << objectsToEvict.size() << " (" + << bytesEvicted << " bytes)."; } if (bytesEvictedOut != nullptr) { @@ -796,8 +796,8 @@ namespace gpgmm::d3d12 { ReturnIfFailed(EvictInternal(sizeToMakeResident, memorySegmentGroup, nullptr)); - DebugEvent("GPU page-in", EventMessageId::kBudgetExceeded) - << "Number of allocations: " << numberOfObjectsToMakeResident << " (" + DebugEvent(GetTypename(), this, EventMessageId::kBudgetExceeded) + << "GPU page-in. Number of allocations: " << numberOfObjectsToMakeResident << " (" << sizeToMakeResident << " bytes)."; // Decrease the overhead from using MakeResident, a synchronous call, by calling the diff --git a/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp b/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp index 4dd9fb86e..d4417bded 100644 --- a/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp +++ b/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp @@ -309,7 +309,8 @@ namespace gpgmm::d3d12 { if (allocation == nullptr) { // NeverAllocate always fails, so suppress it. if (!request.NeverAllocate) { - DebugEvent(allocator->GetTypename(), EventMessageId::kAllocatorFailed) + DebugEvent(allocator->GetTypename(), allocator, + EventMessageId::kAllocatorFailed) << "Unable to allocate memory for request."; } return E_FAIL; @@ -317,7 +318,7 @@ namespace gpgmm::d3d12 { HRESULT hr = createResourceFn(*allocation); if (FAILED(hr)) { - InfoEvent(allocator->GetTypename(), EventMessageId::kAllocatorFailed) + InfoEvent(allocator->GetTypename(), allocator, EventMessageId::kAllocatorFailed) << "Failed to create resource using allocation: " + GetDeviceErrorMessage(device, hr); allocator->DeallocateMemory(std::move(allocation)); @@ -959,7 +960,7 @@ namespace gpgmm::d3d12 { // Check memory requirements. D3D12_HEAP_FLAGS heapFlags = GetHeapFlags(resourceHeapType, IsCreateHeapNotResident()); if (!HasAllFlags(heapFlags, allocationDescriptor.ExtraRequiredHeapFlags)) { - DebugEvent(GetTypename()) + DebugEvent(GetTypename(), this) << "Required heap flags are incompatible with resource heap type (" << std::to_string(allocationDescriptor.ExtraRequiredHeapFlags) << " vs " << std::to_string(heapFlags) + ")."; @@ -1035,7 +1036,7 @@ namespace gpgmm::d3d12 { if (currentVideoInfo->CurrentUsage > currentVideoInfo->Budget) { request.AvailableForAllocation = GetInfoInternal().FreeMemoryUsage; - DebugEvent(GetTypename()) + DebugEvent(GetTypename(), this) << "Current usage exceeded budget (" << std::to_string(currentVideoInfo->CurrentUsage) << " vs " << std::to_string(currentVideoInfo->Budget) + " bytes)."; @@ -1195,7 +1196,7 @@ namespace gpgmm::d3d12 { if (allocationDescriptor.Flags & ALLOCATION_FLAG_NEVER_FALLBACK) { return E_FAIL; } - InfoEvent(GetTypename(), EventMessageId::kAllocatorFailed) + InfoEvent(GetTypename(), this, EventMessageId::kAllocatorFailed) << "Unable to allocate by using a heap, falling back to a committed resource."; } @@ -1415,7 +1416,7 @@ namespace gpgmm::d3d12 { switch (message->ID) { case D3D12_MESSAGE_ID_LIVE_HEAP: case D3D12_MESSAGE_ID_LIVE_RESOURCE: { - gpgmm::WarnEvent("Device") + gpgmm::WarnEvent("Device", device.Get()) << "Leak detected: " + std::string(message->pDescription); } break; default: diff --git a/src/gpgmm/d3d12/ResourceHeapAllocatorD3D12.cpp b/src/gpgmm/d3d12/ResourceHeapAllocatorD3D12.cpp index d760cc5c0..83f752c41 100644 --- a/src/gpgmm/d3d12/ResourceHeapAllocatorD3D12.cpp +++ b/src/gpgmm/d3d12/ResourceHeapAllocatorD3D12.cpp @@ -77,10 +77,10 @@ namespace gpgmm::d3d12 { } if (resourceHeapDesc.SizeInBytes > request.SizeInBytes) { - DebugEvent(GetTypename(), EventMessageId::kAlignmentMismatch) + DebugEvent(GetTypename(), this, EventMessageId::kAlignmentMismatch) << "Resource heap was larger then the requested size (" + - std::to_string(resourceHeapDesc.SizeInBytes) + " vs " + std::to_string(request.SizeInBytes) + - " bytes)."; + std::to_string(resourceHeapDesc.SizeInBytes) + " vs " + + std::to_string(request.SizeInBytes) + " bytes)."; } mStats.UsedMemoryUsage += resourceHeapDesc.SizeInBytes; diff --git a/src/gpgmm/vk/DeviceMemoryAllocatorVk.cpp b/src/gpgmm/vk/DeviceMemoryAllocatorVk.cpp index ef990fe52..1e184716b 100644 --- a/src/gpgmm/vk/DeviceMemoryAllocatorVk.cpp +++ b/src/gpgmm/vk/DeviceMemoryAllocatorVk.cpp @@ -39,7 +39,8 @@ namespace gpgmm::vk { const uint64_t maxDeviceMemoryAllocationCount = mResourceAllocator->GetCaps()->GetMaxDeviceAllocationCount(); if (mStats.UsedMemoryCount + 1 >= maxDeviceMemoryAllocationCount) { - DebugEvent("DeviceMemoryAllocator.TryAllocateMemory", EventMessageId::kAllocatorFailed) + DebugEvent("DeviceMemoryAllocator.TryAllocateMemory", this, + EventMessageId::kAllocatorFailed) << "Device exceeded max number of device memory allocations (" + std::to_string(mStats.UsedMemoryCount) + " vs " + std::to_string(maxDeviceMemoryAllocationCount) + ")."; diff --git a/src/gpgmm/vk/ResourceAllocatorVk.cpp b/src/gpgmm/vk/ResourceAllocatorVk.cpp index 1fedb1219..0d6f344ed 100644 --- a/src/gpgmm/vk/ResourceAllocatorVk.cpp +++ b/src/gpgmm/vk/ResourceAllocatorVk.cpp @@ -352,7 +352,8 @@ namespace gpgmm::vk { } if (memoryAllocation == nullptr) { - ErrorEvent("GpResourceAllocator.TryAllocateResource", EventMessageId::kAllocatorFailed) + ErrorEvent("GpResourceAllocator.TryAllocateResource", this, + EventMessageId::kAllocatorFailed) << "Unable to allocate memory for resource."; return VK_ERROR_UNKNOWN;