1 // Copyright 2020 The Dawn Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef DAWNNATIVE_D3D12_PAGEABLED3D12_H_ 16 #define DAWNNATIVE_D3D12_PAGEABLED3D12_H_ 17 18 #include "common/LinkedList.h" 19 #include "dawn_native/D3D12Backend.h" 20 #include "dawn_native/IntegerTypes.h" 21 #include "dawn_native/d3d12/d3d12_platform.h" 22 23 namespace dawn_native { namespace d3d12 { 24 // This class is used to represent ID3D12Pageable allocations, and also serves as a node within 25 // the ResidencyManager's LRU cache. This node is inserted into the LRU-cache when it is first 26 // allocated, and any time it is scheduled to be used by the GPU. This node is removed from the 27 // LRU cache when it is evicted from resident memory due to budget constraints, or when the 28 // pageable allocation is released. 29 class Pageable : public LinkNode<Pageable> { 30 public: 31 Pageable(ComPtr<ID3D12Pageable> d3d12Pageable, MemorySegment memorySegment, uint64_t size); 32 ~Pageable(); 33 34 ID3D12Pageable* GetD3D12Pageable() const; 35 36 // We set mLastRecordingSerial to denote the serial this pageable was last recorded to be 37 // used. We must check this serial against the current serial when recording usages to 38 // ensure we do not process residency for this pageable multiple times. 39 ExecutionSerial GetLastUsage() const; 40 void SetLastUsage(ExecutionSerial serial); 41 42 // The residency manager must know the last serial that any portion of the pageable was 43 // submitted to be used so that we can ensure this pageable stays resident in memory at 44 // least until that serial has completed. 45 ExecutionSerial GetLastSubmission() const; 46 void SetLastSubmission(ExecutionSerial serial); 47 48 MemorySegment GetMemorySegment() const; 49 50 uint64_t GetSize() const; 51 52 bool IsInResidencyLRUCache() const; 53 54 // In some scenarios, such as async buffer mapping or descriptor heaps, we must lock 55 // residency to ensure the pageable cannot be evicted. Because multiple buffers may be 56 // mapped in a single heap, we must track the number of resources currently locked. 57 void IncrementResidencyLock(); 58 void DecrementResidencyLock(); 59 bool IsResidencyLocked() const; 60 61 protected: 62 ComPtr<ID3D12Pageable> mD3d12Pageable; 63 64 private: 65 // mLastUsage denotes the last time this pageable was recorded for use. 66 ExecutionSerial mLastUsage = ExecutionSerial(0); 67 // mLastSubmission denotes the last time this pageable was submitted to the GPU. Note that 68 // although this variable often contains the same value as mLastUsage, it can differ in some 69 // situations. When some asynchronous APIs (like WriteBuffer) are called, mLastUsage is 70 // updated upon the call, but the backend operation is deferred until the next submission 71 // to the GPU. This makes mLastSubmission unique from mLastUsage, and allows us to 72 // accurately identify when a pageable can be evicted. 73 ExecutionSerial mLastSubmission = ExecutionSerial(0); 74 MemorySegment mMemorySegment; 75 uint32_t mResidencyLockRefCount = 0; 76 uint64_t mSize = 0; 77 }; 78 }} // namespace dawn_native::d3d12 79 80 #endif 81