1 /*
2  * Copyright © Microsoft Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 #include "d3d12_video_enc.h"
25 #include "d3d12_video_enc_av1.h"
26 #include "d3d12_video_encoder_references_manager_av1.h"
27 #include <algorithm>
28 #include <string>
29 #include "d3d12_screen.h"
30 
31 using namespace std;
32 
d3d12_video_encoder_references_manager_av1(bool gopHasInterFrames,d3d12_video_dpb_storage_manager_interface & rDpbStorageManager)33 d3d12_video_encoder_references_manager_av1::d3d12_video_encoder_references_manager_av1(
34    bool gopHasInterFrames, d3d12_video_dpb_storage_manager_interface &rDpbStorageManager)
35    : m_CurrentFrameReferencesData({}),
36      m_PhysicalAllocationsStorage(rDpbStorageManager),
37      m_gopHasInterFrames(gopHasInterFrames),
38      m_isCurrentFrameUsedAsReference(false),
39      m_CurrentFramePicParams({})
40 {
41    assert((NUM_REF_FRAMES + 1 /*extra for cur frame output recon pic*/) ==
42           m_PhysicalAllocationsStorage.get_number_of_tracked_allocations());
43 
44    debug_printf("[D3D12 Video Encoder Picture Manager AV1] Completed construction of "
45                 "d3d12_video_encoder_references_manager_AV1 instance.\n");
46 }
47 
48 void
clear_dpb()49 d3d12_video_encoder_references_manager_av1::clear_dpb()
50 {
51    // Reset m_CurrentFrameReferencesData tracking
52    m_CurrentFrameReferencesData.pVirtualDPBEntries.clear();
53    m_CurrentFrameReferencesData.pVirtualDPBEntries.resize(NUM_REF_FRAMES);
54    m_CurrentFrameReferencesData.ReconstructedPicTexture = { nullptr, 0 };
55 
56    // Initialize DPB slots as unused
57    for (size_t i = 0; i < NUM_REF_FRAMES; i++)
58       m_CurrentFrameReferencesData.pVirtualDPBEntries[i].ReconstructedPictureResourceIndex =
59          UNUSED_VIRTUAL_DPB_SLOT_PHYSICAL_INDEX;
60 
61    // Reset physical DPB underlying storage
62    ASSERTED uint32_t numPicsBeforeClearInDPB = m_PhysicalAllocationsStorage.get_number_of_pics_in_dpb();
63    ASSERTED uint32_t cFreedResources = m_PhysicalAllocationsStorage.clear_decode_picture_buffer();
64    assert(numPicsBeforeClearInDPB == cFreedResources);
65 }
66 
67 D3D12_VIDEO_ENCODER_RECONSTRUCTED_PICTURE
get_current_frame_recon_pic_output_allocation()68 d3d12_video_encoder_references_manager_av1::get_current_frame_recon_pic_output_allocation()
69 {
70    return m_CurrentFrameReferencesData.ReconstructedPicTexture;
71 }
72 
73 bool
is_current_frame_used_as_reference()74 d3d12_video_encoder_references_manager_av1::is_current_frame_used_as_reference()
75 {
76    return m_isCurrentFrameUsedAsReference;
77 }
78 
79 void
begin_frame(D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA curFrameData,bool bUsedAsReference,struct pipe_picture_desc * picture)80 d3d12_video_encoder_references_manager_av1::begin_frame(D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA curFrameData,
81                                                         bool bUsedAsReference,
82                                                         struct pipe_picture_desc *picture)
83 {
84    m_CurrentFramePicParams = *curFrameData.pAV1PicData;
85    m_isCurrentFrameUsedAsReference = bUsedAsReference;
86 
87    if (m_CurrentFramePicParams.FrameType == D3D12_VIDEO_ENCODER_AV1_FRAME_TYPE_KEY_FRAME)
88       clear_dpb();
89 
90    // Prepare current frame recon pic allocation
91    m_CurrentFrameReferencesData.ReconstructedPicTexture = { nullptr, 0 };
92    if (is_current_frame_used_as_reference() && m_gopHasInterFrames) {
93       auto reconPic = m_PhysicalAllocationsStorage.get_new_tracked_picture_allocation();
94       m_CurrentFrameReferencesData.ReconstructedPicTexture.pReconstructedPicture = reconPic.pReconstructedPicture;
95       m_CurrentFrameReferencesData.ReconstructedPicTexture.ReconstructedPictureSubresource =
96          reconPic.ReconstructedPictureSubresource;
97    }
98 
99 #if MESA_DEBUG
100    assert(m_PhysicalAllocationsStorage.get_number_of_tracked_allocations() <=
101           (NUM_REF_FRAMES + 1));   // pool is not extended beyond maximum expected usage
102 
103    if (m_CurrentFramePicParams.FrameType == D3D12_VIDEO_ENCODER_AV1_FRAME_TYPE_KEY_FRAME) {
104       // After clearing the DPB, outstanding used allocations should be 1u only for the first allocation for the
105       // reconstructed picture of the initial KEY_FRAME
106       assert(m_PhysicalAllocationsStorage.get_number_of_in_use_allocations() ==
107              ((is_current_frame_used_as_reference() && m_gopHasInterFrames) ? 1u : 0u));
108    }
109 #endif
110 }
111 
112 void
end_frame()113 d3d12_video_encoder_references_manager_av1::end_frame()
114 {
115    refresh_dpb_slots_with_current_frame_reconpic();
116 }
117 
118 D3D12_VIDEO_ENCODE_REFERENCE_FRAMES
get_current_reference_frames()119 d3d12_video_encoder_references_manager_av1::get_current_reference_frames()
120 {
121    D3D12_VIDEO_ENCODE_REFERENCE_FRAMES retVal = { 0,
122                                                   // ppTexture2Ds
123                                                   nullptr,
124                                                   // pSubresources
125                                                   nullptr };
126 
127    if ((m_CurrentFramePicParams.FrameType != D3D12_VIDEO_ENCODER_AV1_FRAME_TYPE_KEY_FRAME) && m_gopHasInterFrames) {
128       auto curRef = m_PhysicalAllocationsStorage.get_current_reference_frames();
129       retVal.NumTexture2Ds = curRef.NumTexture2Ds;
130       retVal.ppTexture2Ds = curRef.ppTexture2Ds;
131       retVal.pSubresources = curRef.pSubresources;
132    }
133 
134    return retVal;
135 }
136 
137 void
print_ref_frame_idx()138 d3d12_video_encoder_references_manager_av1::print_ref_frame_idx()
139 {
140    std::string refListContentsString;
141    for (uint32_t idx = 0; idx < REFS_PER_FRAME; idx++) {
142       uint32_t reference = 0;
143       reference = m_CurrentFramePicParams.ReferenceIndices[idx];
144       refListContentsString += "{ ref_frame_idx[" + std::to_string(idx) + "] - ";
145       refListContentsString += " DPBidx: ";
146       refListContentsString += std::to_string(reference);
147       if (m_CurrentFrameReferencesData.pVirtualDPBEntries[reference].ReconstructedPictureResourceIndex !=
148           UNUSED_VIRTUAL_DPB_SLOT_PHYSICAL_INDEX) {
149          refListContentsString += " - OrderHint: ";
150          refListContentsString += std::to_string(m_CurrentFrameReferencesData.pVirtualDPBEntries[reference].OrderHint);
151          refListContentsString += " - PictureIndex: ";
152          refListContentsString +=
153             std::to_string(m_CurrentFrameReferencesData.pVirtualDPBEntries[reference].PictureIndex);
154       } else {
155          refListContentsString += " - Unused Virtual DPB slot ";
156       }
157 
158       refListContentsString += " }\n";
159    }
160 
161    debug_printf("[D3D12 Video Encoder Picture Manager AV1] ref_frame_idx[REFS_PER_FRAME] for frame with OrderHint %d "
162                 "(PictureIndex %d) is: \n%s \n",
163                 m_CurrentFramePicParams.OrderHint,
164                 m_CurrentFramePicParams.PictureIndex,
165                 refListContentsString.c_str());
166    debug_printf("[D3D12 Video Encoder Picture Manager AV1] Requested PrimaryRefFrame: %d\n",
167                 m_CurrentFramePicParams.PrimaryRefFrame);
168    debug_printf("[D3D12 Video Encoder Picture Manager AV1] Requested RefreshFrameFlags: %d\n",
169                 m_CurrentFramePicParams.RefreshFrameFlags);
170 }
171 
172 void
print_virtual_dpb_entries()173 d3d12_video_encoder_references_manager_av1::print_virtual_dpb_entries()
174 {
175    std::string dpbContents;
176    for (uint32_t dpbResIdx = 0; dpbResIdx < m_CurrentFrameReferencesData.pVirtualDPBEntries.size(); dpbResIdx++) {
177       auto &dpbDesc = m_CurrentFrameReferencesData.pVirtualDPBEntries[dpbResIdx];
178 
179       if (dpbDesc.ReconstructedPictureResourceIndex != UNUSED_VIRTUAL_DPB_SLOT_PHYSICAL_INDEX) {
180          d3d12_video_reconstructed_picture dpbEntry =
181             m_PhysicalAllocationsStorage.get_reference_frame(dpbDesc.ReconstructedPictureResourceIndex);
182          dpbContents += "{ DPBidx: ";
183          dpbContents += std::to_string(dpbResIdx);
184          dpbContents += " - OrderHint: ";
185          dpbContents += std::to_string(dpbDesc.OrderHint);
186          dpbContents += " - PictureIndex: ";
187          dpbContents += std::to_string(dpbDesc.PictureIndex);
188          dpbContents += " - DPBStorageIdx: ";
189          dpbContents += std::to_string(dpbDesc.ReconstructedPictureResourceIndex);
190          dpbContents += " - DPBStorageResourcePtr: ";
191          char strBuf[256];
192          memset(&strBuf, '\0', 256);
193          sprintf(strBuf, "%p", dpbEntry.pReconstructedPicture);
194          dpbContents += std::string(strBuf);
195          dpbContents += " - DPBStorageSubresource: ";
196          dpbContents += std::to_string(dpbEntry.ReconstructedPictureSubresource);
197          dpbContents += " - RefCount (from any ref_frame_idx[0..6]): ";
198          dpbContents += std::to_string(get_dpb_virtual_slot_refcount_from_ref_frame_idx(dpbResIdx));
199          dpbContents += " }\n";
200       } else {
201          dpbContents += "{ DPBidx: ";
202          dpbContents += std::to_string(dpbResIdx);
203          dpbContents += " < Unused Virtual DPB slot > }\n";
204       }
205    }
206 
207    debug_printf(
208       "[D3D12 Video Encoder Picture Manager AV1] DPB Current output reconstructed picture %p subresource %d\n",
209       m_CurrentFrameReferencesData.ReconstructedPicTexture.pReconstructedPicture,
210       m_CurrentFrameReferencesData.ReconstructedPicTexture.ReconstructedPictureSubresource);
211 
212    debug_printf("[D3D12 Video Encoder Picture Manager AV1] NumTexture2Ds is %d frames - "
213                 "Number of DPB virtual entries is %" PRIu64 " entries for frame with OrderHint "
214                 "%d (PictureIndex %d) are: \n%s \n",
215                 m_PhysicalAllocationsStorage.get_number_of_pics_in_dpb(),
216                 static_cast<uint64_t>(m_CurrentFrameReferencesData.pVirtualDPBEntries.size()),
217                 m_CurrentFramePicParams.OrderHint,
218                 m_CurrentFramePicParams.PictureIndex,
219                 dpbContents.c_str());
220 }
221 
222 void
print_physical_resource_references()223 d3d12_video_encoder_references_manager_av1::print_physical_resource_references()
224 {
225    debug_printf("[D3D12 Video Encoder Picture Manager AV1] %d physical resources IN USE out of a total of %d physical "
226                 "resources ALLOCATED "
227                 "resources at end_frame for frame with OrderHint %d (PictureIndex %d)\n",
228                 m_PhysicalAllocationsStorage.get_number_of_in_use_allocations(),
229                 m_PhysicalAllocationsStorage.get_number_of_tracked_allocations(),
230                 m_CurrentFramePicParams.OrderHint,
231                 m_CurrentFramePicParams.PictureIndex);
232 
233    D3D12_VIDEO_ENCODE_REFERENCE_FRAMES curRefs = get_current_reference_frames();
234    std::string descContents;
235    for (uint32_t index = 0; index < curRefs.NumTexture2Ds; index++) {
236       assert(curRefs.ppTexture2Ds[index]);   // These must be contiguous when sending down to D3D12 API
237       descContents += "{ REFERENCE_FRAMES Index: ";
238       descContents += std::to_string(index);
239       descContents += " - ppTextures ptr: ";
240       char strBuf[256];
241       memset(&strBuf, '\0', 256);
242       sprintf(strBuf, "%p", curRefs.ppTexture2Ds[index]);
243       descContents += std::string(strBuf);
244       descContents += " - ppSubresources index: ";
245       if (curRefs.pSubresources != nullptr)
246          descContents += std::to_string(curRefs.pSubresources[index]);
247       else
248          descContents += "(nil)";
249       descContents += " - RefCount (from any virtual dpb slot [0..REFS_PER_FRAME]): ";
250       descContents += std::to_string(get_dpb_physical_slot_refcount_from_virtual_dpb(index));
251       descContents += " }\n";
252    }
253 
254    debug_printf("[D3D12 Video Encoder Picture Manager AV1] D3D12_VIDEO_ENCODE_REFERENCE_FRAMES has %d physical "
255                 "resources in ppTexture2Ds for OrderHint "
256                 "%d (PictureIndex %d) are: \n%s \n",
257                 curRefs.NumTexture2Ds,
258                 m_CurrentFramePicParams.OrderHint,
259                 m_CurrentFramePicParams.PictureIndex,
260                 descContents.c_str());
261 }
262 
263 //
264 // Returns the number of Reference<XXX> (ie. LAST, LAST2, ..., ALTREF, etc)
265 // pointing to dpbSlotIndex
266 //
267 uint32_t
get_dpb_virtual_slot_refcount_from_ref_frame_idx(uint32_t dpbSlotIndex)268 d3d12_video_encoder_references_manager_av1::get_dpb_virtual_slot_refcount_from_ref_frame_idx(uint32_t dpbSlotIndex)
269 {
270    uint32_t refCount = 0;
271    for (uint8_t i = 0; i < ARRAY_SIZE(m_CurrentFramePicParams.ReferenceIndices); i++) {
272       if (m_CurrentFramePicParams.ReferenceIndices[i] == dpbSlotIndex) {
273          refCount++;
274       }
275    }
276 
277    return refCount;
278 }
279 
280 //
281 // Returns the number of entries in the virtual DPB descriptors
282 // that point to physicalSlotIndex
283 //
284 uint32_t
get_dpb_physical_slot_refcount_from_virtual_dpb(uint32_t physicalSlotIndex)285 d3d12_video_encoder_references_manager_av1::get_dpb_physical_slot_refcount_from_virtual_dpb(uint32_t physicalSlotIndex)
286 {
287    uint32_t refCount = 0;
288    for (unsigned dpbSlotIndex = 0; dpbSlotIndex < m_CurrentFrameReferencesData.pVirtualDPBEntries.size();
289         dpbSlotIndex++) {
290       if (m_CurrentFrameReferencesData.pVirtualDPBEntries[dpbSlotIndex].ReconstructedPictureResourceIndex ==
291           physicalSlotIndex)
292          refCount++;
293    }
294    return refCount;
295 }
296 
297 bool
get_current_frame_picture_control_data(D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA & codecAllocation)298 d3d12_video_encoder_references_manager_av1::get_current_frame_picture_control_data(
299    D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA &codecAllocation)
300 {
301    assert(m_CurrentFrameReferencesData.pVirtualDPBEntries.size() == NUM_REF_FRAMES);
302    assert(codecAllocation.DataSize == sizeof(D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_CODEC_DATA));
303 
304    // Some apps don't clean this up for INTRA/KEY frames
305    if ((m_CurrentFramePicParams.FrameType != D3D12_VIDEO_ENCODER_AV1_FRAME_TYPE_INTER_FRAME)
306    && (m_CurrentFramePicParams.FrameType != D3D12_VIDEO_ENCODER_AV1_FRAME_TYPE_SWITCH_FRAME))
307    {
308       for (uint8_t i = 0; i < ARRAY_SIZE(m_CurrentFramePicParams.ReferenceIndices); i++) {
309          m_CurrentFramePicParams.ReferenceIndices[i] = 0;
310       }
311    }
312 
313    for (uint8_t i = 0; i < NUM_REF_FRAMES; i++)
314       m_CurrentFramePicParams.ReferenceFramesReconPictureDescriptors[i] =
315          m_CurrentFrameReferencesData.pVirtualDPBEntries[i];
316 
317 #if MESA_DEBUG   // Otherwise may iterate over structures and do no-op debug_printf
318    print_ref_frame_idx();
319    print_virtual_dpb_entries();
320    print_physical_resource_references();
321 #endif
322 
323    *codecAllocation.pAV1PicData = m_CurrentFramePicParams;
324    return true;
325 }
326 
327 void
refresh_dpb_slots_with_current_frame_reconpic()328 d3d12_video_encoder_references_manager_av1::refresh_dpb_slots_with_current_frame_reconpic()
329 {
330    UINT refresh_frame_flags = m_CurrentFramePicParams.RefreshFrameFlags;
331    debug_printf("[D3D12 Video Encoder Picture Manager AV1] refresh_frame_flags 0x%x for frame with OrderHint %d "
332                 "(PictureIndex %d)\n",
333                 refresh_frame_flags,
334                 m_CurrentFramePicParams.OrderHint,
335                 m_CurrentFramePicParams.PictureIndex);
336 
337    //
338    // Put current frame in all slots of DPB indicated by refresh_frame_flags
339    //
340    if (is_current_frame_used_as_reference() && m_gopHasInterFrames && (refresh_frame_flags != 0)) {
341 
342       //
343       // First do a eviction pass and update virtual DPB physical indices in case the physical array shifted with an
344       // eviction (erasing an ppTexture2Ds entry)
345       //
346 
347       for (unsigned dpbSlotIdx = 0; dpbSlotIdx < NUM_REF_FRAMES; dpbSlotIdx++) {
348          if (((refresh_frame_flags >> dpbSlotIdx) & 0x1) != 0) {
349 
350             //
351             // Check if the slot this reconpic will take in the virtual DPB will leave an unreferenced
352             // physical allocation, that may need to be evicted (if no other virtual dpb slot references it)
353             //
354 
355             if (m_CurrentFrameReferencesData.pVirtualDPBEntries[dpbSlotIdx].ReconstructedPictureResourceIndex !=
356                 UNUSED_VIRTUAL_DPB_SLOT_PHYSICAL_INDEX) {
357 
358                // If this is a virtual dpb valid entry, there has to be a valid underlying physical allocation
359                assert(m_CurrentFrameReferencesData.pVirtualDPBEntries[dpbSlotIdx].ReconstructedPictureResourceIndex <
360                       m_PhysicalAllocationsStorage.get_number_of_pics_in_dpb());
361 
362                // Get the number of entries in the virtual DPB descriptors that point to
363                // ReconstructedPictureResourceIndex of the current virtual dpb slot (counting the current dpbSlotIdx we
364                // didn't clear yet)
365                uint32_t numRefs = get_dpb_physical_slot_refcount_from_virtual_dpb(
366                   m_CurrentFrameReferencesData.pVirtualDPBEntries[dpbSlotIdx].ReconstructedPictureResourceIndex);
367                if (numRefs == 1) {
368                   // When refreshing this dpbSlotIdx, we will leave an unreferenced physical allocation
369                   // so we can just remove it (and release the ID3D12Resource allocation back to the unused pool)
370 
371                   bool wasTracked = false;
372                   m_PhysicalAllocationsStorage.remove_reference_frame(
373                      m_CurrentFrameReferencesData.pVirtualDPBEntries[dpbSlotIdx].ReconstructedPictureResourceIndex,
374                      &wasTracked);
375                   assert(wasTracked);
376 
377                   // Indices in the virtual dpb higher or equal than
378                   // m_CurrentFrameReferencesData.pVirtualDPBEntries[dpbSlotIdx].ReconstructedPictureResourceIndex
379                   // must be shifted back one place as we erased the entry in the physical allocations array (ppTexture2Ds)
380                   for (auto &dpbVirtualEntry : m_CurrentFrameReferencesData.pVirtualDPBEntries) {
381                      if (
382                         // Check for slot being used
383                         (dpbVirtualEntry.ReconstructedPictureResourceIndex != UNUSED_VIRTUAL_DPB_SLOT_PHYSICAL_INDEX) &&
384                         // Check for slot to be affected by removing the entry in ppTexture2Ds above
385                         (dpbVirtualEntry.ReconstructedPictureResourceIndex >
386                          m_CurrentFrameReferencesData.pVirtualDPBEntries[dpbSlotIdx].ReconstructedPictureResourceIndex)) {
387 
388                         // Decrease the index to compensate for the removed ppTexture2Ds entry
389                         dpbVirtualEntry.ReconstructedPictureResourceIndex--;
390                      }
391                   }
392                }
393 
394                // Clear this virtual dpb entry (so next iterations will decrease refcount)
395                m_CurrentFrameReferencesData.pVirtualDPBEntries[dpbSlotIdx].ReconstructedPictureResourceIndex =
396                   UNUSED_VIRTUAL_DPB_SLOT_PHYSICAL_INDEX;
397             }
398          }
399       }
400 
401       //
402       // Find a new free physical index for the current recon pic; always put new physical entry at the end to avoid
403       // having to shift existing indices in virtual DPB
404       //
405       UINT allocationSlotIdx = m_PhysicalAllocationsStorage.get_number_of_pics_in_dpb();
406       assert(static_cast<uint32_t>(allocationSlotIdx) < NUM_REF_FRAMES);
407       D3D12_VIDEO_ENCODER_RECONSTRUCTED_PICTURE recAlloc = get_current_frame_recon_pic_output_allocation();
408       d3d12_video_reconstructed_picture refFrameDesc = {};
409       refFrameDesc.pReconstructedPicture = recAlloc.pReconstructedPicture;
410       refFrameDesc.ReconstructedPictureSubresource = recAlloc.ReconstructedPictureSubresource;
411       m_PhysicalAllocationsStorage.insert_reference_frame(refFrameDesc, allocationSlotIdx);
412 
413       //
414       // Update virtual DPB entries with the current frame recon picture
415       //
416       for (unsigned dpbSlotIdx = 0; dpbSlotIdx < NUM_REF_FRAMES; dpbSlotIdx++) {
417          if (((refresh_frame_flags >> dpbSlotIdx) & 0x1) != 0) {
418             m_CurrentFrameReferencesData.pVirtualDPBEntries[dpbSlotIdx] = { allocationSlotIdx,
419                                                                             0,   // NO temporal scalability support
420                                                                             0,   // NO spatial scalability support
421                                                                             m_CurrentFramePicParams.FrameType,
422                                                                             {},   // No global_motion support
423                                                                             m_CurrentFramePicParams.OrderHint,
424                                                                             m_CurrentFramePicParams.PictureIndex };
425          }
426       }
427    }
428 
429    // Number of allocations, disregarding if they are used or not, should not exceed this limit due to reuse policies
430    // on DPB items removal.
431    assert(m_PhysicalAllocationsStorage.get_number_of_tracked_allocations() <= (NUM_REF_FRAMES + 1));
432 }
433