Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 15 additions & 17 deletions src/gpgmm/common/EventMessage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,43 +46,41 @@ namespace gpgmm {

// EventMessage

EventMessage::EventMessage(const MessageSeverity& level,
const char* name,
const void* object,
MessageId messageId)
: mSeverity(level), mName(name), mObject(object), mMessageId(messageId) {
EventMessage::EventMessage(const MessageSeverity& severity,
MessageId messageId,
const ObjectBase* object)
: mSeverity(severity), mMessageId(messageId), mObject(object) {
}

EventMessage::~EventMessage() {
const std::string description = mStream.str();

gpgmm::Log(mSeverity, mMessageId)
<< mName << "=" << ToString(mObject) << ": " << description;
gpgmm::Log(mSeverity, mMessageId, mObject) << ": " << description;

#if defined(GPGMM_ENABLE_ASSERT_ON_WARNING)
ASSERT(mSeverity < MessageSeverity::kWarning);
#endif

if (mSeverity >= GetEventMessageLevel()) {
if (mSeverity >= GetEventMessageLevel() && mObject != nullptr) {
GPGMM_TRACE_EVENT_OBJECT_CALL(
mName, MessageInfo({description.c_str(), mMessageId, mSeverity}));
mObject->GetTypename(), MessageInfo({description.c_str(), mMessageId, mSeverity}));
}
}

EventMessage DebugEvent(const ObjectBase* object, MessageId messageId) {
return {MessageSeverity::kDebug, object->GetTypename(), object, messageId};
EventMessage DebugEvent(MessageId messageId, const ObjectBase* object) {
return {MessageSeverity::kDebug, messageId, object};
}

EventMessage InfoEvent(const ObjectBase* object, MessageId messageId) {
return {MessageSeverity::kInfo, object->GetTypename(), object, messageId};
EventMessage InfoEvent(MessageId messageId, const ObjectBase* object) {
return {MessageSeverity::kInfo, messageId, object};
}

EventMessage WarnEvent(const ObjectBase* object, MessageId messageId) {
return {MessageSeverity::kWarning, object->GetTypename(), object, messageId};
EventMessage WarnEvent(MessageId messageId, const ObjectBase* object) {
return {MessageSeverity::kWarning, messageId, object};
}

EventMessage ErrorEvent(const ObjectBase* object, MessageId messageId) {
return {MessageSeverity::kError, object->GetTypename(), object, messageId};
EventMessage ErrorEvent(MessageId messageId, const ObjectBase* object) {
return {MessageSeverity::kError, messageId, object};
}

} // namespace gpgmm
26 changes: 13 additions & 13 deletions src/gpgmm/common/EventMessage.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,9 @@ namespace gpgmm {

class EventMessage {
public:
EventMessage(const MessageSeverity& level,
const char* name,
const void* object,
MessageId messageId = MessageId::kUnknown);
EventMessage(const MessageSeverity& severity,
MessageId messageId,
const ObjectBase* object);
~EventMessage();

EventMessage(EventMessage&& other) = default;
Expand All @@ -44,20 +43,21 @@ namespace gpgmm {

private:
MessageSeverity mSeverity;
const char* mName = nullptr;
const void* mObject = nullptr;
MessageId mMessageId = MessageId::kUnknown;
const ObjectBase* mObject = nullptr;

std::ostringstream mStream;
};

EventMessage DebugEvent(const ObjectBase* object, MessageId messageId = MessageId::kUnknown);

EventMessage InfoEvent(const ObjectBase* object, MessageId messageId = MessageId::kUnknown);

EventMessage WarnEvent(const ObjectBase* object, MessageId messageId = MessageId::kUnknown);

EventMessage ErrorEvent(const ObjectBase* object, MessageId messageId = MessageId::kUnknown);
// Short-hands to create a EventMessage with the respective severity.
EventMessage DebugEvent(MessageId messageId = MessageId::kUnknown,
const ObjectBase* object = nullptr);
EventMessage InfoEvent(MessageId messageId = MessageId::kUnknown,
const ObjectBase* object = nullptr);
EventMessage WarnEvent(MessageId messageId = MessageId::kUnknown,
const ObjectBase* object = nullptr);
EventMessage ErrorEvent(MessageId messageId = MessageId::kUnknown,
const ObjectBase* object = nullptr);

// Messages of a given severity to be recorded.
void SetEventMessageLevel(const MessageSeverity& level);
Expand Down
6 changes: 3 additions & 3 deletions src/gpgmm/common/MemoryAllocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ namespace gpgmm {

// Check request size cannot overflow.
if (request.SizeInBytes > std::numeric_limits<uint64_t>::max() - (request.Alignment - 1)) {
DebugEvent(this, MessageId::kSizeExceeded)
DebugEvent(MessageId::kSizeExceeded, this)
<< "Requested size rejected due to overflow: " + std::to_string(request.SizeInBytes)
<< " bytes.";
return false;
Expand All @@ -174,7 +174,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(this, MessageId::kSizeExceeded)
DebugEvent(MessageId::kSizeExceeded, this)
<< "Requested size exceeds memory size (" + std::to_string(alignedSize) + " vs " +
std::to_string(GetMemorySize()) + " bytes).";
return false;
Expand All @@ -184,7 +184,7 @@ namespace gpgmm {
// Alignment value of 1 means no alignment required.
if (GetMemoryAlignment() == 0 ||
(GetMemoryAlignment() > 1 && !IsAligned(GetMemoryAlignment(), request.Alignment))) {
DebugEvent(this, MessageId::kAlignmentMismatch)
DebugEvent(MessageId::kAlignmentMismatch, this)
<< "Requested alignment exceeds memory alignment (" +
std::to_string(request.Alignment) + " vs " +
std::to_string(GetMemoryAlignment()) + " bytes).";
Expand Down
8 changes: 4 additions & 4 deletions src/gpgmm/common/SlabMemoryAllocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ namespace gpgmm {
if (availableForAllocation < slabSize) {
const uint64_t slabSizeUnderBudget = FindNextFreeSlabOfSize(requestSize);
if (slabSizeUnderBudget == kInvalidSize) {
DebugEvent(this, MessageId::kSizeExceeded)
DebugEvent(MessageId::kSizeExceeded, this)
<< "Slab size exceeded available memory: " << GPGMM_BYTES_TO_MB(slabSize)
<< " vs " << GPGMM_BYTES_TO_MB(availableForAllocation) << " MBs.";
return kInvalidSize;
Expand Down Expand Up @@ -209,7 +209,7 @@ namespace gpgmm {

// Slab cannot exceed memory size.
if (slabSize > mMaxSlabSize) {
gpgmm::DebugEvent(this, MessageId::kSizeExceeded)
gpgmm::DebugEvent(MessageId::kSizeExceeded, this)
<< "Slab allocation was disabled because the slab size exceeded the max slab size "
"allowed: "
<< GPGMM_BYTES_TO_MB(slabSize) << " vs " << GPGMM_BYTES_TO_MB(mMaxSlabSize)
Expand Down Expand Up @@ -295,7 +295,7 @@ namespace gpgmm {
}

if (prefetchedSlabAllocation != nullptr) {
DebugEvent(this, MessageId::kPrefetchFailed)
DebugEvent(MessageId::kPrefetchFailed, this)
<< "Pre-fetching failed because the slab size did not match: "
<< GPGMM_BYTES_TO_MB(slabSize) << " vs "
<< GPGMM_BYTES_TO_MB(prefetchedSlabAllocation->GetSize())
Expand Down Expand Up @@ -476,7 +476,7 @@ namespace gpgmm {
SafeDivide(mStats.PrefetchedMemoryMissesEliminated,
mStats.PrefetchedMemoryMissesEliminated + mStats.PrefetchedMemoryMisses);
if (currentCoverage < kPrefetchCoverageWarnMinThreshold) {
WarnEvent(this, MessageId::kPrefetchFailed)
WarnEvent(MessageId::kPrefetchFailed, this)
<< "Prefetch coverage is below threshold (%): " << currentCoverage * 100 << " vs "
<< kPrefetchCoverageWarnMinThreshold * 100;
return false;
Expand Down
10 changes: 5 additions & 5 deletions src/gpgmm/d3d12/ResidencyManagerD3D12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,7 @@ namespace gpgmm::d3d12 {
// Ignore when no budget was specified.
if (pVideoMemoryInfo->Budget > 0 &&
pVideoMemoryInfo->CurrentUsage > pVideoMemoryInfo->Budget) {
WarnEvent(this, MessageId::kBudgetExceeded)
WarnEvent(MessageId::kBudgetExceeded, this)
<< GetMemorySegmentName(memorySegmentGroup, mIsUMA)
<< " GPU memory usage exceeds budget: "
<< GPGMM_BYTES_TO_MB(pVideoMemoryInfo->CurrentUsage) << " vs "
Expand All @@ -551,7 +551,7 @@ namespace gpgmm::d3d12 {
SafeDivide(pVideoMemoryInfo->CurrentUsage, pVideoMemoryInfo->Budget);
if (pVideoMemoryInfo->Budget > 0 &&
currentUsageOfBudget > kMinCurrentUsageOfBudgetReportingThreshold) {
EventMessage message = WarnEvent(this, MessageId::kBudgetExceeded);
EventMessage message = WarnEvent(MessageId::kBudgetExceeded, this);
message << GetMemorySegmentName(memorySegmentGroup, mIsUMA)
<< " GPU memory usage is above budget threshold: "
<< uint64_t(currentUsageOfBudget * 100) << "% vs "
Expand Down Expand Up @@ -638,7 +638,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(this, MessageId::kBudgetInvalid)
WarnEvent(MessageId::kBudgetInvalid, this)
<< "GPU memory segment ("
<< GetMemorySegmentName(DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL, IsUMA())
<< ") was unable to evict memory because a budget was not specified.";
Expand Down Expand Up @@ -711,7 +711,7 @@ namespace gpgmm::d3d12 {
const uint32_t objectEvictCount = static_cast<uint32_t>(objectsToEvict.size());
ReturnIfFailedDevice(mDevice->Evict(objectEvictCount, objectsToEvict.data()), mDevice);

DebugEvent(this, MessageId::kBudgetExceeded)
DebugEvent(MessageId::kBudgetExceeded, this)
<< "GPU page-out. Number of allocations: " << objectsToEvict.size() << " ("
<< bytesEvicted << " bytes).";
}
Expand Down Expand Up @@ -872,7 +872,7 @@ namespace gpgmm::d3d12 {

ReturnIfFailed(EvictInternal(sizeToMakeResident, memorySegmentGroup, nullptr));

DebugEvent(this, MessageId::kBudgetExceeded)
DebugEvent(MessageId::kBudgetExceeded, this)
<< "GPU page-in. Number of allocations: " << numberOfObjectsToMakeResident << " ("
<< sizeToMakeResident << " bytes).";

Expand Down
4 changes: 2 additions & 2 deletions src/gpgmm/d3d12/ResourceAllocationD3D12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ namespace gpgmm::d3d12 {
// Allocation coordinates relative to the resource cannot be used when specifying
// subresource-relative coordinates.
if (subresource > 0 && GetMethod() == AllocationMethod::kSubAllocatedWithin) {
gpgmm::ErrorEvent(this, MessageId::kBadOperation)
gpgmm::ErrorEvent(MessageId::kBadOperation, this)
<< "Mapping a sub-allocation within a resource cannot use "
"non-zero subresource-relative coordinates.";
return E_INVALIDARG;
Expand Down Expand Up @@ -114,7 +114,7 @@ namespace gpgmm::d3d12 {
// Allocation coordinates relative to the resource cannot be used when specifying
// subresource-relative coordinates.
if (subresource > 0 && GetMethod() == AllocationMethod::kSubAllocatedWithin) {
gpgmm::ErrorEvent(this, MessageId::kBadOperation)
gpgmm::ErrorEvent(MessageId::kBadOperation, this)
<< "Unmapping a sub-allocation within a resource cannot use "
"non-zero subresource-relative coordinates.";
return;
Expand Down
10 changes: 5 additions & 5 deletions src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ namespace gpgmm::d3d12 {
if (FAILED(result.GetErrorCode())) {
// NeverAllocate always fails, so suppress it.
if (!request.NeverAllocate) {
DebugEvent(allocator, MessageId::kAllocatorFailed)
DebugEvent(MessageId::kAllocatorFailed, allocator)
<< "Unable to allocate memory for request.";
}
return static_cast<HRESULT>(result.GetErrorCode());
Expand All @@ -326,7 +326,7 @@ namespace gpgmm::d3d12 {

HRESULT hr = createResourceFn(*allocation);
if (FAILED(hr)) {
InfoEvent(allocator, MessageId::kAllocatorFailed)
InfoEvent(MessageId::kAllocatorFailed, allocator)
<< "Failed to create resource using allocation.";
allocator->DeallocateMemory(std::move(allocation));
}
Expand Down Expand Up @@ -1299,7 +1299,7 @@ namespace gpgmm::d3d12 {
return E_OUTOFMEMORY;
}

InfoEvent(this, MessageId::kAllocatorFailed)
InfoEvent(MessageId::kAllocatorFailed, this)
<< "Unable to allocate memory for a resource by using a heap, falling back to a "
"committed resource.";
}
Expand Down Expand Up @@ -1527,7 +1527,7 @@ namespace gpgmm::d3d12 {
// sub-allocation is used.
const uint64_t blocksPerHeap = SafeDivide(result.UsedBlockCount, result.UsedMemoryCount);
if (blocksPerHeap > 1 && blocksPerHeap < kMinBlockToMemoryCountReportingThreshold) {
gpgmm::WarnEvent(this, MessageId::kPerformanceWarning)
gpgmm::WarnEvent(MessageId::kPerformanceWarning, this)
<< "Average number of resource allocations per heap is below threshold: "
<< blocksPerHeap << " blocks per heap (vs "
<< kMinBlockToMemoryCountReportingThreshold
Expand All @@ -1541,7 +1541,7 @@ namespace gpgmm::d3d12 {
100;
if (allocationUsagePct > 0 &&
allocationUsagePct < kMinAllocationUsageReportingThreshold * 100) {
gpgmm::WarnEvent(this, MessageId::kPerformanceWarning)
gpgmm::WarnEvent(MessageId::kPerformanceWarning, this)
<< "Average resource allocation usage is below threshold: " << allocationUsagePct
<< "% vs " << uint64_t(kMinAllocationUsageReportingThreshold * 100)
<< "%. This either means memory has become fragmented or the working set has "
Expand Down
57 changes: 33 additions & 24 deletions src/gpgmm/utils/Log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,10 @@ namespace gpgmm {

// LogMessage

LogMessage::LogMessage(MessageSeverity severity, MessageId messageId) noexcept
: mSeverity(severity), mMessageId(messageId) {
LogMessage::LogMessage(MessageSeverity severity,
MessageId messageId,
const ObjectBase* object) noexcept
: mSeverity(severity), mMessageId(messageId), mObject(object) {
}

LogMessage::~LogMessage() {
Expand All @@ -121,14 +123,21 @@ namespace gpgmm {
if (IsDebuggerPresent()) {
std::string outputString;
if (mMessageId != MessageId::kUnknown) {
outputString = std::string(kLogTag) + " " + std::string(severityName) +
"(tid: " + ToString(std::this_thread::get_id()) +
"): " + fullMessage + "[" + GetMessageFromID(mMessageId) + "]" +
"\n";
outputString =
std::string(kLogTag) + " " + std::string(severityName) +
"(tid: " + ToString(std::this_thread::get_id()) + "): " +
((mObject != nullptr)
? ((std::string(mObject->GetTypename()) + "=") + ToString(mObject) + ", ")
: "") +
fullMessage + "[" + GetMessageFromID(mMessageId) + "]" + "\n";
} else {
outputString = std::string(kLogTag) + " " + std::string(severityName) +
"(tid: " + ToString(std::this_thread::get_id()) +
"): " + fullMessage + "\n";
outputString =
std::string(kLogTag) + " " + std::string(severityName) +
"(tid: " + ToString(std::this_thread::get_id()) + "): " +
((mObject != nullptr)
? ((std::string(mObject->GetTypename()) + "=") + ToString(mObject) + ", ")
: "") +
fullMessage + "\n";
}

OutputDebugStringA(outputString.c_str());
Expand Down Expand Up @@ -163,41 +172,41 @@ namespace gpgmm {
#endif
}

LogMessage DebugLog(MessageId messageId) {
return {MessageSeverity::kDebug, messageId};
LogMessage DebugLog(MessageId messageId, const ObjectBase* object) {
return {MessageSeverity::kDebug, messageId, object};
}

LogMessage InfoLog(MessageId messageId) {
return {MessageSeverity::kInfo, messageId};
LogMessage InfoLog(MessageId messageId, const ObjectBase* object) {
return {MessageSeverity::kInfo, messageId, object};
}

LogMessage WarningLog(MessageId messageId) {
return {MessageSeverity::kWarning, messageId};
LogMessage WarningLog(MessageId messageId, const ObjectBase* object) {
return {MessageSeverity::kWarning, messageId, object};
}

LogMessage ErrorLog(MessageId messageId) {
return {MessageSeverity::kError, messageId};
LogMessage ErrorLog(MessageId messageId, const ObjectBase* object) {
return {MessageSeverity::kError, messageId, object};
}

LogMessage DebugLog(const char* file, const char* function, int line) {
LogMessage message = DebugLog();
LogMessage message = DebugLog(MessageId::kUnknown, nullptr);
message << file << ":" << line << "(" << function << ")";
return message;
}

LogMessage Log(MessageSeverity severity, MessageId messageId) {
LogMessage Log(MessageSeverity severity, MessageId messageId, const ObjectBase* object) {
switch (severity) {
case MessageSeverity::kDebug:
return DebugLog(messageId);
return DebugLog(messageId, object);
case MessageSeverity::kInfo:
return InfoLog(messageId);
return InfoLog(messageId, object);
case MessageSeverity::kWarning:
return WarningLog(messageId);
return WarningLog(messageId, object);
case MessageSeverity::kError:
return ErrorLog(messageId);
return ErrorLog(messageId, object);
default:
UNREACHABLE();
return {severity, messageId};
return {severity, messageId, object};
}
}

Expand Down
Loading