diff --git a/src/gpgmm/common/Message.h b/src/gpgmm/common/Message.h index 060407f5f..b7893574c 100644 --- a/src/gpgmm/common/Message.h +++ b/src/gpgmm/common/Message.h @@ -26,6 +26,8 @@ namespace gpgmm { kBudgetExceeded, kBudgetUpdated, kBudgetInvalid, + kInvalidArgument, + kBadOperation, }; enum class MessageSeverity { diff --git a/src/gpgmm/d3d12/HeapD3D12.cpp b/src/gpgmm/d3d12/HeapD3D12.cpp index f009476a3..3bcc33459 100644 --- a/src/gpgmm/d3d12/HeapD3D12.cpp +++ b/src/gpgmm/d3d12/HeapD3D12.cpp @@ -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; } diff --git a/src/gpgmm/d3d12/ResidencyManagerD3D12.cpp b/src/gpgmm/d3d12/ResidencyManagerD3D12.cpp index 6e93907fe..8aa1e6a47 100644 --- a/src/gpgmm/d3d12/ResidencyManagerD3D12.cpp +++ b/src/gpgmm/d3d12/ResidencyManagerD3D12.cpp @@ -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); @@ -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; } @@ -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."; } } @@ -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."; @@ -681,14 +685,15 @@ namespace gpgmm::d3d12 { std::lock_guard 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; @@ -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; } } @@ -951,23 +957,26 @@ namespace gpgmm::d3d12 { Heap* heap = static_cast(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; } diff --git a/src/gpgmm/d3d12/ResourceAllocationD3D12.cpp b/src/gpgmm/d3d12/ResourceAllocationD3D12.cpp index b2c11d6b9..e41ed8983 100644 --- a/src/gpgmm/d3d12/ResourceAllocationD3D12.cpp +++ b/src/gpgmm/d3d12/ResourceAllocationD3D12.cpp @@ -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; } @@ -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; } diff --git a/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp b/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp index 61ec87424..924ad9177 100644 --- a/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp +++ b/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp @@ -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; @@ -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; @@ -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."; } @@ -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; } @@ -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."; @@ -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 lock(mMutex); uint64_t bytesReleased = 0; for (uint32_t resourceHeapTypeIndex = 0; resourceHeapTypeIndex < kNumOfResourceHeapTypes; @@ -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; } @@ -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; @@ -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;