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
2 changes: 2 additions & 0 deletions src/gpgmm/common/Message.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ namespace gpgmm {
kBudgetExceeded,
kBudgetUpdated,
kBudgetInvalid,
kInvalidArgument,
kBadOperation,
};

enum class MessageSeverity {
Expand Down
5 changes: 3 additions & 2 deletions src/gpgmm/d3d12/HeapD3D12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,9 @@ 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)) {
gpgmm::ErrorLog() << "Creating a heap always in budget cannot be used with "
"D3D12_HEAP_FLAG_CREATE_NOT_RESIDENT.";
gpgmm::ErrorLog(MessageId::kInvalidArgument)
<< "Creating a heap always in budget cannot be used with "
"D3D12_HEAP_FLAG_CREATE_NOT_RESIDENT.";
return E_INVALIDARG;
}

Expand Down
67 changes: 38 additions & 29 deletions src/gpgmm/d3d12/ResidencyManagerD3D12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,9 @@ namespace gpgmm::d3d12 {
}

if (FAILED(hr)) {
gpgmm::ErrorLog() << "Unable to update budget: " +
GetDeviceErrorMessage(mResidencyManager->mDevice, hr);
gpgmm::ErrorLog(MessageId::kBudgetInvalid)
<< "Unable to update budget: " +
GetDeviceErrorMessage(mResidencyManager->mDevice, hr);
}

SetLastError(hr);
Expand Down Expand Up @@ -172,13 +173,15 @@ namespace gpgmm::d3d12 {
}

if ((descriptor.Flags & RESIDENCY_FLAG_DISABLE_UNIFIED_MEMORY) && caps->IsAdapterUMA()) {
gpgmm::WarningLog() << "RESIDENCY_FLAG_DISABLE_UNIFIED_MEMORY flag was specified but "
"did not match the architecture of the adapter.";
gpgmm::WarningLog(MessageId::kInvalidArgument)
<< "RESIDENCY_FLAG_DISABLE_UNIFIED_MEMORY flag was specified but "
"did not match the architecture of the adapter.";
}

if (descriptor.MaxPctOfVideoMemoryToBudget != 0 && descriptor.MaxBudgetInBytes != 0) {
gpgmm::ErrorLog() << "Both the OS based memory budget and restricted budget were "
"specified but cannot be used at the same time.";
gpgmm::ErrorLog(MessageId::kInvalidArgument)
<< "Both the OS based memory budget and restricted budget were "
"specified but cannot be used at the same time.";
return E_UNEXPECTED;
}

Expand Down Expand Up @@ -224,18 +227,19 @@ 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) {
gpgmm::WarningLog()
gpgmm::WarningLog(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) {
gpgmm::WarningLog() << "GPU memory segment ("
<< GetMemorySegmentName(DXGI_MEMORY_SEGMENT_GROUP_NON_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.";
gpgmm::WarningLog(MessageId::kBudgetInvalid)
<< "GPU memory segment ("
<< GetMemorySegmentName(DXGI_MEMORY_SEGMENT_GROUP_NON_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.";
}
}

Expand Down Expand Up @@ -346,7 +350,7 @@ namespace gpgmm::d3d12 {
}

if (heap->IsInList()) {
gpgmm::ErrorLog()
gpgmm::ErrorLog(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 @@ -681,14 +685,15 @@ namespace gpgmm::d3d12 {
std::lock_guard<std::mutex> lock(mMutex);

if (count == 0) {
gpgmm::ErrorLog() << "ExecuteCommandLists is required to have at-least one residency "
"list to be called.";
gpgmm::ErrorLog(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) {
gpgmm::ErrorLog()
gpgmm::ErrorLog(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 @@ -842,10 +847,11 @@ namespace gpgmm::d3d12 {
ReturnIfFailed(
EvictInternal(mEvictSizeInBytes, memorySegmentGroup, &evictedSizeInBytes));
if (evictedSizeInBytes == 0) {
gpgmm::ErrorLog() << "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 "
"residency usage.";
gpgmm::ErrorLog(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 "
"residency usage.";
return E_OUTOFMEMORY;
}
}
Expand Down Expand Up @@ -951,23 +957,26 @@ namespace gpgmm::d3d12 {

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

if (!heap->GetInfo().IsCachedForResidency) {
gpgmm::ErrorLog() << "Heap residency cannot be updated because no residency "
"manager was specified upon creation. The heap must be created "
"using a residency manager to update the residency status.";
gpgmm::ErrorLog(MessageId::kBadOperation)
<< "Heap residency cannot be updated because no residency "
"manager was specified upon creation. The heap must be created "
"using a residency manager to update the residency status.";
return E_FAIL;
}

const RESIDENCY_STATUS oldState = heap->GetInfo().Status;
if (state == RESIDENCY_STATUS_UNKNOWN && oldState != RESIDENCY_STATUS_UNKNOWN) {
gpgmm::ErrorLog() << "Heap residency cannot be unknown when previously known by the "
"residency manager. "
"Check the status before updating the state.";
gpgmm::ErrorLog(MessageId::kBadOperation)
<< "Heap residency cannot be unknown when previously known by the "
"residency manager. "
"Check the status before updating the state.";
return E_FAIL;
}

Expand Down
10 changes: 6 additions & 4 deletions src/gpgmm/d3d12/ResourceAllocationD3D12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,9 @@ namespace gpgmm::d3d12 {
// Allocation coordinates relative to the resource cannot be used when specifying
// subresource-relative coordinates.
if (subresource > 0 && GetMethod() == AllocationMethod::kSubAllocatedWithin) {
gpgmm::ErrorLog() << "Map() on resource sub-allocation within cannot use "
"non-zero subresource-relative coordinates.";
gpgmm::ErrorLog(MessageId::kBadOperation)
<< "Map() on resource sub-allocation within cannot use "
"non-zero subresource-relative coordinates.";
return E_INVALIDARG;
}

Expand Down Expand Up @@ -112,8 +113,9 @@ namespace gpgmm::d3d12 {
// Allocation coordinates relative to the resource cannot be used when specifying
// subresource-relative coordinates.
if (subresource > 0 && GetMethod() == AllocationMethod::kSubAllocatedWithin) {
gpgmm::ErrorLog() << "Unmap() on resource sub-allocation within cannot use "
"non-zero subresource-relative coordinates.";
gpgmm::ErrorLog(MessageId::kBadOperation)
<< "Unmap() on resource sub-allocation within cannot use "
"non-zero subresource-relative coordinates.";
return;
}

Expand Down
52 changes: 29 additions & 23 deletions src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -442,27 +442,29 @@ namespace gpgmm::d3d12 {
}

if (allocatorDescriptor.ResourceHeapTier > caps->GetMaxResourceHeapTierSupported()) {
gpgmm::ErrorLog() << "Resource heap tier exceeds the capabilities of the device "
"(ResourceHeapTier:"
<< allocatorDescriptor.ResourceHeapTier << " vs "
<< caps->GetMaxResourceHeapTierSupported()
<< "). Please consider using a lower resource heap tier.";
gpgmm::ErrorLog(MessageId::kInvalidArgument)
<< "Resource heap tier exceeds the capabilities of the device "
"(ResourceHeapTier:"
<< allocatorDescriptor.ResourceHeapTier << " vs "
<< caps->GetMaxResourceHeapTierSupported()
<< "). Please consider using a lower resource heap tier.";
return E_FAIL;
}

if (allocatorDescriptor.ResourceHeapTier != 0 &&
allocatorDescriptor.ResourceHeapTier < caps->GetMaxResourceHeapTierSupported()) {
gpgmm::DebugLog()
gpgmm::DebugLog(MessageId::kInvalidArgument)
<< "Resource heap tier requested was lower than what the device "
"supports. This is allowed but not recommended because it prevents "
"resources of different categories from sharing the same heap.";
}

if (allocatorDescriptor.Flags & ALLOCATOR_FLAG_ALWAYS_IN_BUDGET && !pResidencyManager) {
gpgmm::WarningLog() << "ALLOCATOR_FLAG_ALWAYS_IN_BUDGET has no effect when residency "
"management does not exist. This is probably not what the "
"developer intended to do. Please consider creating a residency "
"manager with this resource allocator before using this flag.";
gpgmm::WarningLog(MessageId::kInvalidArgument)
<< "ALLOCATOR_FLAG_ALWAYS_IN_BUDGET has no effect when residency "
"management does not exist. This is probably not what the "
"developer intended to do. Please consider creating a residency "
"manager with this resource allocator before using this flag.";
}

ALLOCATOR_DESC newDescriptor = allocatorDescriptor;
Expand All @@ -483,7 +485,7 @@ namespace gpgmm::d3d12 {
// unsupported by the device.
if (!(allocatorDescriptor.Flags & ALLOCATOR_FLAG_DISABLE_UNIFIED_MEMORY) &&
!caps->IsAdapterCacheCoherentUMA()) {
gpgmm::DebugLog()
gpgmm::DebugLog(MessageId::kInvalidArgument)
<< "ALLOCATOR_FLAG_DISABLE_UNIFIED_MEMORY was not requested but enabled "
"anyway because the device did not support cache-coherent UMA.";
newDescriptor.Flags |= ALLOCATOR_FLAG_DISABLE_UNIFIED_MEMORY;
Expand All @@ -501,7 +503,7 @@ namespace gpgmm::d3d12 {
!caps->IsCreateHeapNotResidentSupported()) {
newDescriptor.Flags |= ALLOCATOR_FLAG_ALWAYS_IN_BUDGET;

gpgmm::DebugLog()
gpgmm::DebugLog(MessageId::kInvalidArgument)
<< "ALLOCATOR_FLAG_ALWAYS_IN_BUDGET was not requested but enabled "
"anyway because the device did not support creating non-resident heaps.";
}
Expand All @@ -521,9 +523,10 @@ namespace gpgmm::d3d12 {
: kDefaultFragmentationLimit;

if (newDescriptor.PreferredResourceHeapSize > newDescriptor.MaxResourceHeapSize) {
gpgmm::ErrorLog() << "Requested preferred resource heap size exceeded the capabilities "
"of the device. This is probably not what the developer intended "
"to do. Please consider using a smaller resource heap size.";
gpgmm::ErrorLog(MessageId::kInvalidArgument)
<< "Requested preferred resource heap size exceeded the capabilities "
"of the device. This is probably not what the developer intended "
"to do. Please consider using a smaller resource heap size.";
return E_INVALIDARG;
}

Expand All @@ -544,7 +547,7 @@ namespace gpgmm::d3d12 {
D3D12_INFO_QUEUE_FILTER emptyFilter{};
ReturnIfFailed(leakMessageQueue->PushRetrievalFilter(&emptyFilter));
} else {
gpgmm::WarningLog()
gpgmm::WarningLog(MessageId::kInvalidArgument)
<< "GPGMM_ENABLE_DEVICE_LEAK_CHECKS has no effect because the D3D12 debug "
"layer was either not installed or enabled. Please call "
"ID3D12Debug::EnableDebugLayer before using this flag.";
Expand Down Expand Up @@ -822,7 +825,8 @@ namespace gpgmm::d3d12 {
return "ResourceAllocator";
}

HRESULT ResourceAllocator::ReleaseResourceHeaps(uint64_t bytesToRelease, uint64_t* pBytesReleased) {
HRESULT ResourceAllocator::ReleaseResourceHeaps(uint64_t bytesToRelease,
uint64_t* pBytesReleased) {
std::lock_guard<std::mutex> lock(mMutex);
uint64_t bytesReleased = 0;
for (uint32_t resourceHeapTypeIndex = 0; resourceHeapTypeIndex < kNumOfResourceHeapTypes;
Expand Down Expand Up @@ -933,8 +937,9 @@ namespace gpgmm::d3d12 {
const D3D12_RESOURCE_ALLOCATION_INFO resourceInfo =
GetResourceAllocationInfo(mDevice, newResourceDesc);
if (resourceInfo.SizeInBytes > mCaps->GetMaxResourceSize()) {
gpgmm::ErrorLog() << "Unable to create resource allocation because the size exceeded "
"capabilities of the device.";
gpgmm::ErrorLog(MessageId::kInvalidArgument)
<< "Unable to create resource allocation because the size exceeded "
"capabilities of the device.";
return E_OUTOFMEMORY;
}

Expand Down Expand Up @@ -971,7 +976,7 @@ namespace gpgmm::d3d12 {
const RESOURCE_HEAP_TYPE resourceHeapType = GetResourceHeapType(
newResourceDesc.Dimension, heapType, newResourceDesc.Flags, mResourceHeapTier);
if (resourceHeapType == RESOURCE_HEAP_TYPE_INVALID) {
gpgmm::ErrorLog()
gpgmm::ErrorLog(MessageId::kInvalidArgument)
<< "Unable to create resource allocation because the resource type was invalid due "
"to the combination of resource flags, descriptor, and resource heap tier.";
return E_INVALIDARG;
Expand All @@ -984,9 +989,10 @@ namespace gpgmm::d3d12 {
// Check memory requirements.
D3D12_HEAP_FLAGS heapFlags = GetHeapFlags(resourceHeapType, IsCreateHeapNotResident());
if (!HasAllFlags(heapFlags, allocationDescriptor.ExtraRequiredHeapFlags)) {
DebugEvent(this) << "Required heap flags are incompatible with resource heap type ("
<< std::to_string(allocationDescriptor.ExtraRequiredHeapFlags)
<< " vs " << std::to_string(heapFlags) + ").";
DebugEvent(this, MessageId::kInvalidArgument)
<< "Required heap flags are incompatible with resource heap type ("
<< std::to_string(allocationDescriptor.ExtraRequiredHeapFlags) << " vs "
<< std::to_string(heapFlags) + ").";

heapFlags |= allocationDescriptor.ExtraRequiredHeapFlags;

Expand Down