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
1 change: 1 addition & 0 deletions src/gpgmm/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ source_set("gpgmm_sources") {
"d3d12/HeapD3D12.h",
"d3d12/JSONSerializerD3D12.cpp",
"d3d12/JSONSerializerD3D12.h",
"d3d12/LogD3D12.h",
"d3d12/ResidencyListD3D12.cpp",
"d3d12/ResidencyListD3D12.h",
"d3d12/ResidencyManagerD3D12.cpp",
Expand Down
1 change: 1 addition & 0 deletions src/gpgmm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ if (GPGMM_ENABLE_D3D12)
"d3d12/HeapD3D12.h"
"d3d12/JSONSerializerD3D12.cpp"
"d3d12/JSONSerializerD3D12.h"
"d3d12/LogD3D12.h"
"d3d12/ResidencyListD3D12.cpp"
"d3d12/ResidencyListD3D12.h"
"d3d12/ResidencyManagerD3D12.cpp"
Expand Down
10 changes: 5 additions & 5 deletions src/gpgmm/d3d12/HeapD3D12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "gpgmm/common/TraceEvent.h"
#include "gpgmm/d3d12/ErrorD3D12.h"
#include "gpgmm/d3d12/JSONSerializerD3D12.h"
#include "gpgmm/d3d12/LogD3D12.h"
#include "gpgmm/d3d12/ResidencyManagerD3D12.h"
#include "gpgmm/d3d12/UtilsD3D12.h"

Expand Down Expand Up @@ -84,7 +85,7 @@ namespace gpgmm::d3d12 {
DXGI_QUERY_VIDEO_MEMORY_INFO currentVideoInfo = {};
if (SUCCEEDED(residencyManager->QueryVideoMemoryInfo(descriptor.HeapSegment,
&currentVideoInfo))) {
ErrorLog(MessageId::kBudgetExceeded)
ErrorLog(MessageId::kBudgetExceeded, true)
<< "Unable to create heap because not enough budget exists ("
<< GPGMM_BYTES_TO_MB(descriptor.SizeInBytes) << " vs "
<< GPGMM_BYTES_TO_MB(
Expand Down Expand Up @@ -125,7 +126,7 @@ namespace gpgmm::d3d12 {
// Heap created not resident requires no budget to be created.
if (heap->mState == RESIDENCY_STATUS_PENDING_RESIDENCY &&
(descriptor.Flags & HEAP_FLAG_ALWAYS_IN_BUDGET)) {
ErrorLog(MessageId::kInvalidArgument)
ErrorLog(heap.get(), MessageId::kInvalidArgument)
<< "Creating a heap always in budget cannot be used with "
"D3D12_HEAP_FLAG_CREATE_NOT_RESIDENT.";
return E_INVALIDARG;
Expand All @@ -146,8 +147,7 @@ namespace gpgmm::d3d12 {
}
} else {
if (descriptor.Flags & HEAP_FLAG_ALWAYS_IN_RESIDENCY) {
WarningLog(MessageId::kInvalidArgument, true, WCharToUTF8(heap->GetDebugName()),
heap.get())
WarningLog(heap.get(), MessageId::kInvalidArgument)
<< "HEAP_FLAG_ALWAYS_IN_RESIDENCY was specified but had no effect becauase "
"residency management is "
"not being used.";
Expand All @@ -157,7 +157,7 @@ namespace gpgmm::d3d12 {
GPGMM_RETURN_IF_FAILED(heap->SetDebugName(descriptor.DebugName));
GPGMM_TRACE_EVENT_OBJECT_SNAPSHOT(heap.get(), descriptor);

DebugLog(MessageId::kObjectCreated, true, WCharToUTF8(heap->GetDebugName()), heap.get())
DebugLog(heap.get(), MessageId::kObjectCreated)
<< "Created heap, Size=" << heap->GetInfo().SizeInBytes
<< ", ID3D12Pageable=" << ToHexStr(heap->mPageable.Get());

Expand Down
70 changes: 70 additions & 0 deletions src/gpgmm/d3d12/LogD3D12.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright 2022 The GPGMM Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef GPGMM_D3D12_LOGD3D12_H_
#define GPGMM_D3D12_LOGD3D12_H_

#include "gpgmm/common/EventMessage.h"
#include "gpgmm/utils/WindowsUtils.h"

namespace gpgmm::d3d12 {

template <typename BackendT>
LogMessage DebugLog(const BackendT* object, MessageId messageId = MessageId::kUnknown) {
return gpgmm::DebugLog(messageId, true, gpgmm::WCharToUTF8(object->GetDebugName()), object);
}

template <typename BackendT>
LogMessage InfoLog(const BackendT* object, MessageId messageId = MessageId::kUnknown) {
return gpgmm::InfoLog(messageId, true, gpgmm::WCharToUTF8(object->GetDebugName()), object);
}

template <typename BackendT>
LogMessage WarningLog(const BackendT* object, MessageId messageId = MessageId::kUnknown) {
return gpgmm::WarningLog(messageId, true, gpgmm::WCharToUTF8(object->GetDebugName()),
object);
}

template <typename BackendT>
LogMessage ErrorLog(const BackendT* object, MessageId messageId = MessageId::kUnknown) {
return gpgmm::ErrorLog(messageId, true, gpgmm::WCharToUTF8(object->GetDebugName()), object);
}

template <typename BackendT>
EventMessage DebugEvent(const BackendT* object, MessageId messageId = MessageId::kUnknown) {
return gpgmm::DebugEvent(messageId, true, gpgmm::WCharToUTF8(object->GetDebugName()),
object);
}

template <typename BackendT>
EventMessage InfoEvent(const BackendT* object, MessageId messageId = MessageId::kUnknown) {
return gpgmm::InfoEvent(messageId, true, gpgmm::WCharToUTF8(object->GetDebugName()),
object);
}

template <typename BackendT>
EventMessage WarnEvent(const BackendT* object, MessageId messageId = MessageId::kUnknown) {
return gpgmm::WarnEvent(messageId, true, gpgmm::WCharToUTF8(object->GetDebugName()),
object);
}

template <typename BackendT>
EventMessage ErrorEvent(const BackendT* object, MessageId messageId = MessageId::kUnknown) {
return gpgmm::ErrorEvent(messageId, true, gpgmm::WCharToUTF8(object->GetDebugName()),
object);
}

} // namespace gpgmm::d3d12

#endif // GPGMM_D3D12_LOGD3D12_H_
64 changes: 30 additions & 34 deletions src/gpgmm/d3d12/ResidencyManagerD3D12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "gpgmm/d3d12/FenceD3D12.h"
#include "gpgmm/d3d12/HeapD3D12.h"
#include "gpgmm/d3d12/JSONSerializerD3D12.h"
#include "gpgmm/d3d12/LogD3D12.h"
#include "gpgmm/d3d12/ResidencyListD3D12.h"
#include "gpgmm/d3d12/UtilsD3D12.h"
#include "gpgmm/utils/Math.h"
Expand Down Expand Up @@ -74,8 +75,7 @@ namespace gpgmm::d3d12 {
break;
}

DebugLog(MessageId::kBudgetUpdated, true,
WCharToUTF8(mResidencyManager->GetDebugName()), mResidencyManager)
DebugLog(mResidencyManager, MessageId::kBudgetUpdated)
<< "Updated budget from OS notification.";
break;
}
Expand All @@ -92,8 +92,7 @@ namespace gpgmm::d3d12 {
}

if (FAILED(hr)) {
ErrorLog(MessageId::kBudgetInvalid, true,
WCharToUTF8(mResidencyManager->GetDebugName()), mResidencyManager)
ErrorLog(mResidencyManager, MessageId::kBudgetInvalid)
<< "Unable to update budget: " +
GetDeviceErrorMessage(mResidencyManager->mDevice, hr);
}
Expand Down Expand Up @@ -213,8 +212,7 @@ namespace gpgmm::d3d12 {
// Require automatic video memory budget updates.
if (!(descriptor.Flags & RESIDENCY_FLAG_DISABLE_BUDGET_UPDATES_ON_WORKER_THREAD)) {
GPGMM_RETURN_IF_FAILED(residencyManager->StartBudgetNotificationUpdates());
DebugLog(MessageId::kBudgetUpdated, true, WCharToUTF8(residencyManager->GetDebugName()),
residencyManager.get())
DebugLog(residencyManager.get(), MessageId::kBudgetUpdated)
<< "OS based memory budget updates were successfully enabled.";
}

Expand Down Expand Up @@ -242,13 +240,13 @@ namespace gpgmm::d3d12 {
// Emit a warning if the budget was initialized to zero.
// This means nothing will be ever evicted, which will lead to device lost.
if (localVideoMemorySegmentInfo->Budget == 0) {
WarningLog(MessageId::kBudgetInvalid, true)
WarningLog(residencyManager.get(), MessageId::kBudgetInvalid)
<< "GPU memory segment ("
<< GetMemorySegmentName(DXGI_MEMORY_SEGMENT_GROUP_LOCAL, residencyManager->mIsUMA)
<< ") did not initialize a budget. This means either a restricted budget was not "
"used or the first OS budget update hasn't occured.";
if (!residencyManager->mIsUMA && nonLocalVideoMemorySegmentInfo->Budget == 0) {
WarningLog(MessageId::kBudgetInvalid, true)
WarningLog(residencyManager.get(), MessageId::kBudgetInvalid)
<< "GPU memory segment ("
<< GetMemorySegmentName(DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL,
residencyManager->mIsUMA)
Expand All @@ -266,9 +264,7 @@ namespace gpgmm::d3d12 {

GPGMM_TRACE_EVENT_OBJECT_SNAPSHOT(residencyManager.get(), descriptor);

DebugLog(MessageId::kObjectCreated, true, WCharToUTF8(residencyManager->GetDebugName()),
residencyManager.get())
<< "Created residency manager";
DebugLog(residencyManager.get(), MessageId::kObjectCreated) << "Created residency manager";

if (ppResidencyManagerOut != nullptr) {
*ppResidencyManagerOut = residencyManager.release();
Expand Down Expand Up @@ -372,7 +368,7 @@ namespace gpgmm::d3d12 {
}

if (heap->IsInList()) {
ErrorLog(MessageId::kBadOperation, true, WCharToUTF8(GetDebugName()), this)
ErrorLog(this, MessageId::kBadOperation)
<< "Heap was never being tracked for residency. This usually occurs when a "
"non-resource heap was created by the developer and never made resident at "
"creation or failure to call LockHeap beforehand.";
Expand Down Expand Up @@ -507,16 +503,16 @@ namespace gpgmm::d3d12 {

if (previousUsage > pVideoMemoryInfo->CurrentUsage &&
GPGMM_BYTES_TO_MB(previousUsage - pVideoMemoryInfo->CurrentUsage) > 0) {
DebugLog(MessageId::kMemoryUsageUpdated, true, WCharToUTF8(GetDebugName()), this)
DebugLog(this, MessageId::kMemoryUsageUpdated)
<< GetMemorySegmentName(heapSegment, mIsUMA) << " GPU memory usage went down by "
<< GPGMM_BYTES_TO_MB(previousUsage - pVideoMemoryInfo->CurrentUsage) << " MBs.";
} else if (previousUsage < pVideoMemoryInfo->CurrentUsage &&
GPGMM_BYTES_TO_MB(pVideoMemoryInfo->CurrentUsage - previousUsage) > 0) {
DebugLog(MessageId::kMemoryUsageUpdated, true, WCharToUTF8(GetDebugName()), this)
DebugLog(this, MessageId::kMemoryUsageUpdated)
<< GetMemorySegmentName(heapSegment, mIsUMA) << " GPU memory usage went up by "
<< GPGMM_BYTES_TO_MB(pVideoMemoryInfo->CurrentUsage - previousUsage) << " MBs.";
} else if (previousUsage < pVideoMemoryInfo->CurrentUsage) {
DebugLog(MessageId::kMemoryUsageUpdated, true, WCharToUTF8(GetDebugName()), this)
DebugLog(this, MessageId::kMemoryUsageUpdated)
<< GetMemorySegmentName(heapSegment, mIsUMA) << " GPU memory usage went up by "
<< GPGMM_BYTES_TO_MB(pVideoMemoryInfo->CurrentUsage) << " MBs.";
}
Expand All @@ -530,13 +526,13 @@ namespace gpgmm::d3d12 {

if (previousBudget > pVideoMemoryInfo->Budget &&
GPGMM_BYTES_TO_MB(previousBudget - pVideoMemoryInfo->Budget) > 0) {
DebugLog(MessageId::kMemoryUsageUpdated, true, WCharToUTF8(GetDebugName()), this)
DebugLog(this, MessageId::kMemoryUsageUpdated)
<< GetMemorySegmentName(heapSegment, mIsUMA)
<< " GPU memory budget went down by "
<< GPGMM_BYTES_TO_MB(previousBudget - pVideoMemoryInfo->Budget) << " MBs.";
} else if (previousBudget < pVideoMemoryInfo->Budget &&
GPGMM_BYTES_TO_MB(pVideoMemoryInfo->Budget - previousBudget) > 0) {
DebugLog(MessageId::kMemoryUsageUpdated, true, WCharToUTF8(GetDebugName()), this)
DebugLog(this, MessageId::kMemoryUsageUpdated)
<< GetMemorySegmentName(heapSegment, mIsUMA) << " GPU memory budget went up by "
<< GPGMM_BYTES_TO_MB(pVideoMemoryInfo->Budget - previousBudget) << " MBs.";
}
Expand All @@ -545,7 +541,7 @@ namespace gpgmm::d3d12 {
// Ignore when no budget was specified.
if (pVideoMemoryInfo->Budget > 0 &&
pVideoMemoryInfo->CurrentUsage > pVideoMemoryInfo->Budget) {
WarnEvent(MessageId::kBudgetExceeded, true, WCharToUTF8(GetDebugName()), this)
WarnEvent(this, MessageId::kBudgetExceeded)
<< GetMemorySegmentName(heapSegment, mIsUMA) << " GPU memory usage exceeds budget: "
<< GPGMM_BYTES_TO_MB(pVideoMemoryInfo->CurrentUsage) << " vs "
<< GPGMM_BYTES_TO_MB(pVideoMemoryInfo->Budget) << " MBs.";
Expand All @@ -554,8 +550,7 @@ namespace gpgmm::d3d12 {
SafeDivide(pVideoMemoryInfo->CurrentUsage, pVideoMemoryInfo->Budget);
if (pVideoMemoryInfo->Budget > 0 &&
currentUsageOfBudget > kMinCurrentUsageOfBudgetReportingThreshold) {
EventMessage message =
WarnEvent(MessageId::kBudgetExceeded, true, WCharToUTF8(GetDebugName()), this);
EventMessage message = WarnEvent(this, MessageId::kBudgetExceeded);
message << GetMemorySegmentName(heapSegment, mIsUMA)
<< " GPU memory usage is above budget threshold: "
<< uint64_t(currentUsageOfBudget * 100) << "% vs "
Expand Down Expand Up @@ -631,7 +626,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(MessageId::kBudgetInvalid, true, WCharToUTF8(GetDebugName()), this)
WarnEvent(this, MessageId::kBudgetInvalid)
<< "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 @@ -705,7 +700,7 @@ namespace gpgmm::d3d12 {
GPGMM_RETURN_IF_FAILED_ON_DEVICE(
mDevice->Evict(objectEvictCount, objectsToEvict.data()), mDevice);

DebugEvent(MessageId::kBudgetExceeded, true, WCharToUTF8(GetDebugName()), this)
DebugEvent(this, MessageId::kBudgetExceeded)
<< "GPU page-out. Number of allocations: " << objectsToEvict.size() << " ("
<< bytesEvicted << " bytes).";
}
Expand All @@ -730,15 +725,15 @@ namespace gpgmm::d3d12 {
std::lock_guard<std::mutex> lock(mMutex);

if (count == 0) {
ErrorLog(MessageId::kInvalidArgument, true, WCharToUTF8(GetDebugName()), this)
ErrorLog(this, MessageId::kInvalidArgument)
<< "ExecuteCommandLists is required to have at-least one residency "
"list to be called.";
return E_INVALIDARG;
}

// TODO: support multiple command lists.
if (count > 1) {
ErrorLog(MessageId::kInvalidArgument, true, WCharToUTF8(GetDebugName()), this)
ErrorLog(this, MessageId::kInvalidArgument)
<< "ExecuteCommandLists does not support multiple residency lists at this time. "
"Please call ExecuteCommandLists per residency list as a workaround, if needed.";
return E_NOTIMPL;
Expand Down Expand Up @@ -799,7 +794,7 @@ namespace gpgmm::d3d12 {
// If the heap should be already resident, calling MakeResident again will be redundant.
// Tell the developer the heap wasn't properly tracked by the residency manager.
if (heap->GetInfo().Status == RESIDENCY_STATUS_UNKNOWN) {
DebugLog(MessageId::kBadOperation, true, WCharToUTF8(GetDebugName()), this)
DebugLog(this, MessageId::kBadOperation)
<< "Residency state could not be determined for the heap (Heap="
<< ToHexStr(heap)
<< "). This likely means the developer was attempting to make a "
Expand Down Expand Up @@ -868,7 +863,7 @@ namespace gpgmm::d3d12 {

GPGMM_RETURN_IF_FAILED(EvictInternal(sizeToMakeResident, heapSegment, nullptr));

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

Expand Down Expand Up @@ -897,7 +892,7 @@ namespace gpgmm::d3d12 {
GPGMM_RETURN_IF_FAILED(
EvictInternal(mEvictSizeInBytes, heapSegment, &evictedSizeInBytes));
if (evictedSizeInBytes == 0) {
ErrorLog(MessageId::kBudgetInvalid, true, WCharToUTF8(GetDebugName()), this)
ErrorLog(this, MessageId::kBudgetInvalid)
<< "Unable to evict enough heaps to stay within budget. This "
"usually occurs when there is not enough available memory. "
"Please reduce consumption by checking allocation sizes and "
Expand Down Expand Up @@ -990,13 +985,14 @@ namespace gpgmm::d3d12 {
DXGI_QUERY_VIDEO_MEMORY_INFO* info = GetVideoMemoryInfo(segmentGroup);
ASSERT(info != nullptr);

DebugLog() << GetMemorySegmentName(segmentGroup, IsUMA()) << " GPU memory segment:";
DebugLog() << "\tBudget: " << GPGMM_BYTES_TO_MB(info->Budget) << " MBs ("
<< GPGMM_BYTES_TO_MB(info->CurrentUsage) << " used).";
DebugLog(this) << GetMemorySegmentName(segmentGroup, IsUMA()) << " GPU memory segment:";
DebugLog(this) << "\tBudget: " << GPGMM_BYTES_TO_MB(info->Budget) << " MBs ("
<< GPGMM_BYTES_TO_MB(info->CurrentUsage) << " used).";

if (info->CurrentReservation == 0) {
DebugLog() << "\tReserved: " << GPGMM_BYTES_TO_MB(info->CurrentReservation) << " MBs ("
<< GPGMM_BYTES_TO_MB(info->AvailableForReservation) << " available).";
DebugLog(this) << "\tReserved: " << GPGMM_BYTES_TO_MB(info->CurrentReservation)
<< " MBs (" << GPGMM_BYTES_TO_MB(info->AvailableForReservation)
<< " available).";
}
}

Expand All @@ -1005,15 +1001,15 @@ namespace gpgmm::d3d12 {

Heap* heap = static_cast<Heap*>(pHeap);
if (heap->GetInfo().IsLocked) {
ErrorLog(MessageId::kBadOperation, true, WCharToUTF8(GetDebugName()), this)
ErrorLog(this, MessageId::kBadOperation)
<< "Heap residency cannot be updated because it was locked. "
"Please unlock the heap before updating the state.";
return E_FAIL;
}

const RESIDENCY_STATUS oldState = heap->GetInfo().Status;
if (state == RESIDENCY_STATUS_UNKNOWN && oldState != RESIDENCY_STATUS_UNKNOWN) {
ErrorLog(MessageId::kBadOperation, true, WCharToUTF8(GetDebugName()), this)
ErrorLog(this, MessageId::kBadOperation)
<< "Heap residency cannot be unknown when previously known by the "
"residency manager. "
"Check the status before updating the state.";
Expand Down
Loading