1 /*
2 * Copyright (c) 2018-2021, Intel 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 shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file     decode_allocator.h
24 //! \brief    Defines the interface for decode resource allocate
25 //! \details  decode allocator will allocate and destory buffers, the caller
26 //!           can use directly
27 //!
28 
29 #ifndef __DECODE_ALLOCATOR_H__
30 #define __DECODE_ALLOCATOR_H__
31 
32 #include "media_class_trace.h"
33 #include "mhw_utilities_next.h"
34 #include "mos_defs.h"
35 #include "mos_os.h"
36 #include "mos_os_hw.h"
37 #include "mos_os_specific.h"
38 #include "mos_resource_defs.h"
39 #include "External/Common/GmmCachePolicyExt.h"
40 #include <stdint.h>
41 #include <vector>
42 class Allocator;
43 
44 namespace decode {
45 
46 template <class T>
47 class ResourceArray;
48 
49 using BufferArray       = ResourceArray<MOS_BUFFER>;
50 using SurfaceArray      = ResourceArray<MOS_SURFACE>;
51 using BatchBufferArray  = ResourceArray<MHW_BATCH_BUFFER>;
52 
53 enum ResourceUsage
54 {
55     resourceOutputPicture            = MOS_HW_RESOURCE_USAGE_DECODE_OUTPUT_PICTURE,
56     resourceInputBitstream           = MOS_HW_RESOURCE_USAGE_DECODE_INPUT_BITSTREAM,
57     resourceInputReference           = MOS_HW_RESOURCE_USAGE_DECODE_INPUT_REFERENCE,
58     resourceInternalRead             = MOS_HW_RESOURCE_USAGE_DECODE_INTERNAL_READ,
59     resourceInternalWrite            = MOS_HW_RESOURCE_USAGE_DECODE_INTERNAL_WRITE,
60     resourceInternalReadWriteCache   = MOS_HW_RESOURCE_USAGE_DECODE_INTERNAL_READ_WRITE_CACHE,
61     resourceInternalReadWriteNoCache = MOS_HW_RESOURCE_USAGE_DECODE_INTERNAL_READ_WRITE_NOCACHE,
62     resourceStatisticsWrite          = MOS_HW_RESOURCE_USAGE_DECODE_OUTPUT_STATISTICS_WRITE,
63     resourceStatisticsReadWrite      = MOS_HW_RESOURCE_USAGE_DECODE_OUTPUT_STATISTICS_READ_WRITE,
64     resourceDefault                  = MOS_HW_RESOURCE_DEF_MAX
65 };
66 
67 enum ResourceAccessReq
68 {
69     notLockableVideoMem = 0,
70     lockableVideoMem,
71     lockableSystemMem
72 };
73 
74 class DecodeAllocator
75 {
76 public:
77     //!
78     //! \brief  Constructor
79     //! \param  [in] osInterface
80     //!         Pointer to MOS_INTERFACE
81     //! \param  [in] limitedLMemBar
82     //!         Indicate if running with limited LMem bar config
83     //!
84     DecodeAllocator(PMOS_INTERFACE osInterface, bool limitedLMemBar);
85 
86     //!
87     //! \brief  DecodeAllocator destructor
88     //!
89     ~DecodeAllocator();
90 
91     //!
92     //! \brief  Allocate buffer
93     //! \param  [in] sizeOfBuffer
94     //!         Buffer size
95     //! \param  [in] nameOfBuffer
96     //!         Buffer name
97     //! \param  [in] resUsageType
98     //!         ResourceUsage to be set
99     //! \param  [in] accessReq
100     //!         Resource access requirement, by default is lockable
101     //! \param  [in] initOnAllocate
102     //!         Indicate if this buffer need to be initialized when allocate, by default is false
103     //! \param  [in] initValue
104     //!         Initialization value when initOnAllocate flag is true, by default is 0
105     //! \param  [in] bPersistent
106     //!         persistent flag
107     //! \return MOS_BUFFER*
108     //!         return the pointer to MOS_BUFFER
109     //!
110     MOS_BUFFER* AllocateBuffer(const uint32_t sizeOfBuffer, const char* nameOfBuffer,
111         ResourceUsage resUsageType = resourceDefault, ResourceAccessReq accessReq = lockableVideoMem,
112         bool initOnAllocate = false, uint8_t initValue = 0, bool bPersistent = false);
113 
114     //!
115     //! \brief  Allocate buffer array
116     //! \param  [in] sizeOfBuffer
117     //!         Buffer size
118     //! \param  [in] nameOfBuffer
119     //!         Buffer name
120     //! \param  [in] numberOfBuffer
121     //!         number of buffer array
122     //! \param  [in] resUsageType
123     //!         ResourceUsage to be set
124     //! \param  [in] accessReq
125     //!         Resource access requirement, by default is lockable
126     //! \param  [in] initOnAllocate
127     //!         Indicate if this buffer need to be initialized when allocate, by default is false
128     //! \param  [in] initValue
129     //!         Initialization value when initOnAllocate flag is true, by default is 0
130     //! \return BufferArray*
131     //!         return the pointer to BufferArray
132     //!
133     BufferArray * AllocateBufferArray(
134         const uint32_t sizeOfBuffer, const char* nameOfBuffer, const uint32_t numberOfBuffer,
135         ResourceUsage resUsageType = resourceDefault, ResourceAccessReq accessReq = lockableVideoMem,
136         bool initOnAllocate = false, uint8_t initValue = 0, bool bPersistent = false);
137 
138     //!
139     //! \brief  Allocate Surface
140     //! \param  [in] width
141     //!         Surface width
142     //! \param  [in] height
143     //!         Surface height
144     //! \param  [in] name
145     //!         Surface name
146     //! \param  [in] format
147     //!         Surface format, by default is NV12
148     //! \param  [in] isCompressible
149     //!         Compressible flag, by default is false
150     //! \param  [in] resUsageType
151     //!         ResourceUsage to be set
152     //! \param  [in] accessReq
153     //!         Resource access requirement, by default is lockable
154     //! \param  [in] gmmTileMode
155     //!         Specified GMM tile mode
156     //! \return MOS_SURFACE*
157     //!         return the pointer to MOS_SURFACE
158     //!
159     MOS_SURFACE* AllocateSurface(
160         const uint32_t width, const uint32_t height, const char* nameOfSurface,
161         MOS_FORMAT format = Format_NV12, bool isCompressible = false,
162         ResourceUsage resUsageType = resourceDefault, ResourceAccessReq accessReq = lockableVideoMem,
163         MOS_TILE_MODE_GMM gmmTileMode = MOS_TILE_UNSET_GMM);
164 
165     //!
166     //! \brief  Allocate surface array
167     //! \param  [in] width
168     //!         Surface width
169     //! \param  [in] height
170     //!         Surface height
171     //! \param  [in] name
172     //!         Surface name
173     //! \param  [in] numberOfSurface
174     //!         Number of surface array
175     //! \param  [in] format
176     //!         Surface format, by default is NV12
177     //! \param  [in] isCompressed
178     //!         Compress flag, by default is false
179     //! \param  [in] resUsageType
180     //!         ResourceUsage to be set
181     //! \param  [in] accessReq
182     //!         Resource access requirement, by default is lockable
183     //! \return SurfaceArray*
184     //!         return the pointer to SurfaceArray
185     //!
186     SurfaceArray * AllocateSurfaceArray(
187         const uint32_t width, const uint32_t height, const char* nameOfSurface,
188         const uint32_t numberOfSurface, MOS_FORMAT format = Format_NV12, bool isCompressed = false,
189         ResourceUsage resUsageType = resourceDefault, ResourceAccessReq accessReq = lockableVideoMem);
190 
191     //!
192     //! \brief  Allocate Linear Output Surface
193     //! \param  [in] width
194     //!         surface width
195     //! \param  [in] height
196     //!         surface height
197     //! \param  [in] surfaceName
198     //!         Surface name
199     //! \param  [in] format
200     //!         Surface format, by default is NV12
201     //! \param  [in] compressible
202     //!         Compressible flag, by default is false
203     //! \param  [in] resUsageType
204     //!         ResourceUsage to be set
205     //! \param  [in] gmmTileMode
206     //!         Specified GMM tile mode
207     //!
208     MOS_SURFACE * AllocateLinearSurface(
209         const uint32_t width, const uint32_t height, const char *nameOfSurface,
210         MOS_FORMAT format = Format_NV12, bool isCompressible = false,
211         ResourceUsage resUsageType = resourceDefault, ResourceAccessReq accessReq = lockableVideoMem,
212         MOS_TILE_MODE_GMM gmmTileMode = MOS_TILE_UNSET_GMM);
213 
214     //!
215     //! \brief  Allocate batch buffer
216     //! \param  [in] sizeOfBuffer
217     //!         Batch buffer size
218     //! \param  [in] numOfBuffer
219     //!         Surface height
220     //! \param  [in] accessReq
221     //!         Resource access requirement, by default is lockable
222     //! \return PMHW_BATCH_BUFFER
223     //!         return the pointer to allocated batch buffer if success, else nullptr
224     //!
225     PMHW_BATCH_BUFFER AllocateBatchBuffer(const uint32_t sizeOfBuffer, const uint32_t numOfBuffer=1,
226         ResourceAccessReq accessReq = lockableVideoMem);
227 
228     //!
229     //! \brief  Allocate batch buffer array
230     //! \param  [in] sizeOfSubBuffer
231     //!         Size of sub buffer
232     //! \param  [in] numOfSubBuffer
233     //!         Number of sub buffer
234     //! \param  [in] numberOfBatchBuffer
235     //!         Number of batch buffer array
236     //! \param  [in] secondLevel
237     //!         Flag to indicate second level batch buffer
238     //! \param  [in] accessReq
239     //!         Resource access requirement, by default is lockable
240     //! \return BatchBufferArray*
241     //!         return the pointer to BatchBufferArray
242     //!
243     BatchBufferArray * AllocateBatchBufferArray(
244         const uint32_t sizeOfSubBuffer, const uint32_t numOfSubBuffer,
245         const uint32_t numberOfBatchBuffer, bool secondLevel,
246         ResourceAccessReq accessReq = lockableVideoMem);
247 
248     //!
249     //! \brief  Resize linear buffer
250     //! \param  [in/out] buffer
251     //!         The pointer of linear buffer
252     //! \param  [in] sizeNew
253     //!         New size for linear buffer
254     //! \param  [in] accessReq
255     //!         Resource access requirement, by default is lockable
256     //! \param  [in] force
257     //!         Flag indicates whether resize buffer by force when size changed
258     //! \param  [in] clearData
259     //!         Flag indicates whether clear cached buffer data when size changed
260     //! \return MOS_STATUS
261     //!         MOS_STATUS_SUCCESS if success, else fail reason
262     //!
263     MOS_STATUS Resize(MOS_BUFFER* &buffer, const uint32_t sizeNew, ResourceAccessReq accessReq = lockableVideoMem,
264         bool force = false, bool clearData = false);
265 
266     //!
267     //! \brief  Resize surface
268     //! \param  [in/out] surface
269     //!         The pointer of surface
270     //! \param  [in] widthNew
271     //!         New width
272     //! \param  [in] heightNew
273     //!         New height
274     //! \param  [in] accessReq
275     //!         Resource access requirement, by default is lockable
276     //! \param  [in] force
277     //!         Flag indicates whether resize surface by force when size changed
278     //! \param  [in] nameOfSurface
279     //!         Name of the surface
280     //! \return MOS_STATUS
281     //!         MOS_STATUS_SUCCESS if success, else fail reason
282     //!
283     MOS_STATUS Resize(MOS_SURFACE* &surface, const uint32_t widthNew, const uint32_t heightNew,
284         ResourceAccessReq accessReq = lockableVideoMem, bool force = false, const char* nameOfSurface = "");
285 
286     //!
287     //! \brief  Resize batch buffer
288     //! \param  [in] sizeOfBufferNew
289     //!         Size of new batch buffer
290     //! \param  [in] numOfBufferNew
291     //!         Number of new batch buffer
292     //! \return MOS_STATUS
293     //!         MOS_STATUS_SUCCESS if success, else fail reason
294     //!
295     MOS_STATUS Resize(PMHW_BATCH_BUFFER &batchBuffer, const uint32_t sizeOfBufferNew, const uint32_t numOfBufferNew,
296         ResourceAccessReq accessReq = lockableVideoMem);
297 
298     //!
299     //! \brief  Destroy buffer
300     //! \param  [in] resource
301     //!         The buffer to be destroyed
302     //! \return MOS_STATUS
303     //!         MOS_STATUS_SUCCESS if success, else fail reason
304     //!
305     MOS_STATUS Destroy(MOS_BUFFER* & resource);
306 
307     //!
308     //! \brief  Destroy Surface
309     //! \param  [in] surface
310     //!         The surface to be destroyed
311     //! \return MOS_STATUS
312     //!         MOS_STATUS_SUCCESS if success, else fail reason
313     //!
314     MOS_STATUS Destroy(MOS_SURFACE* & surface);
315 
316     //!
317     //! \brief  Destroy Surface
318     //! \param  [in] surface
319     //!         The surface to be destroyed
320     //! \return MOS_STATUS
321     //!         MOS_STATUS_SUCCESS if success, else fail reason
322     //!
323     MOS_STATUS Destroy(MOS_SURFACE& surface);
324 
325     //!
326     //! \brief  Destroy buffer array
327     //! \param  [in] bufferArray
328     //!         The buffer array to be destroyed
329     //! \return MOS_STATUS
330     //!         MOS_STATUS_SUCCESS if success, else fail reason
331     //!
332     MOS_STATUS Destroy(BufferArray* & bufferArray);
333 
334     //!
335     //! \brief  Destroy surface array
336     //! \param  [in] surfaceArray
337     //!         The surface array to be destroyed
338     //! \return MOS_STATUS
339     //!         MOS_STATUS_SUCCESS if success, else fail reason
340     //!
341     MOS_STATUS Destroy(SurfaceArray * & surfaceArray);
342 
343     //!
344     //! \brief  Destroy batch buffer
345     //! \param  [in] batchBuffer
346     //!         The batch buffer to be destroyed
347     //! \return MOS_STATUS
348     //!         MOS_STATUS_SUCCESS if success, else fail reason
349     //!
350     MOS_STATUS Destroy(PMHW_BATCH_BUFFER &batchBuffer);
351 
352     //!
353     //! \brief  Destroy batch buffer array
354     //! \param  [in] batchBufferArray
355     //!         The batch buffer array to be destroyed
356     //! \return MOS_STATUS
357     //!         MOS_STATUS_SUCCESS if success, else fail reason
358     //!
359     MOS_STATUS Destroy(BatchBufferArray * & batchBufferArray);
360 
361     //!
362     //! \brief  Lock resource
363     //! \param  [in] resource
364     //!         Pointer to MOS_RESOURCE
365     //! \param  [in] lockFlag
366     //!         Pointer to MOS_LOCK_PARAMS
367     //! \return void*
368     //!         a poniter to data
369     //!
370     void* Lock(MOS_RESOURCE* resource, MOS_LOCK_PARAMS* lockFlag);
371 
372     //!
373     //! \brief  Lock resource only for writing
374     //! \param  [in] resource
375     //!         Pointer to MOS_RESOURCE
376     //! \return void*
377     //!         a poniter to data
378     //!
379     void* LockResourceForWrite(MOS_RESOURCE *resource);
380 
381     //!
382     //! \brief  Lock resource with no overwrite flag
383     //! \param  [in] resource
384     //!         Pointer to MOS_RESOURCE
385     //! \return void*
386     //!         a poniter to data
387     //!
388     void* LockResourceWithNoOverwrite(MOS_RESOURCE *resource);
389 
390     //!
391     //! \brief  Lock resource only for reading
392     //! \param  [in] resource
393     //!         Pointer to MOS_RESOURCE
394     //! \return void*
395     //!         a poniter to data
396     //!
397     void* LockResourceForRead(MOS_RESOURCE *resource);
398 
399     //!
400     //! \brief  Lock resource only for reading
401     //! \param  [in] buffer
402     //!         Pointer to MOS_BUFFER
403     //! \return void*
404     //!         a poniter to data
405     //!
406     void* LockResourceForRead(MOS_BUFFER* buffer);
407 
408     //!
409     //! \brief  Lock batch buffer
410     //! \param  [in] batchBuffer
411     //!         Pointer to MHW_BATCH_BUFFER
412     //! \return MOS_STATUS
413     //!         MOS_STATUS_SUCCESS if success, else fail reason
414     //!
415     MOS_STATUS Lock(PMHW_BATCH_BUFFER batchBuffer);
416 
417     //!
418     //! \brief  UnLock resource
419     //! \param  [in] resource
420     //!         Pointer to MOS_RESOURCE
421     //! \return MOS_STATUS
422     //!         MOS_STATUS_SUCCESS if success, else fail reason
423     //!
424     MOS_STATUS UnLock(MOS_RESOURCE* resource);
425 
426     //!
427     //! \brief  UnLock buffer
428     //! \param  [in] buffer
429     //!         Pointer to MOS_BUFFER
430     //! \return MOS_STATUS
431     //!         MOS_STATUS_SUCCESS if success, else fail reason
432     //!
433     MOS_STATUS UnLock(MOS_BUFFER* buffer);
434 
435     //!
436     //! \brief  UnLock batch buffer
437     //! \param  [in] batchBuffer
438     //!         Pointer to MHW_BATCH_BUFFER
439     //! \return MOS_STATUS
440     //!         MOS_STATUS_SUCCESS if success, else fail reason
441     //!
442     MOS_STATUS UnLock(PMHW_BATCH_BUFFER batchBuffer, bool resetBuffer);
443 
444     MOS_STATUS DestroyAllResources();
445 
446     //!
447     //! \brief  Sync on resource
448     //! \param  [in] resource
449     //!         Pointer to MOS_RESOURCE
450     //! \param  [in] IsWriteOperation
451     //!         Indicate if sync for write operation
452     //! \return MOS_STATUS
453     //!         MOS_STATUS_SUCCESS if success, else fail reason
454     //!
455     MOS_STATUS SyncOnResource(MOS_RESOURCE* resource, bool IsWriteOperation);
456 
457     //!
458     //! \brief  Sync on resource
459     //! \param  [in] buffer
460     //!         Pointer to MOS_BUFFER
461     //! \param  [in] IsWriteOperation
462     //!         Indicate if sync for write operation
463     //! \return MOS_STATUS
464     //!         MOS_STATUS_SUCCESS if success, else fail reason
465     //!
466     MOS_STATUS SyncOnResource(MOS_BUFFER* buffer, bool IsWriteOperation);
467 
468     //!
469     //! \brief  Skip sync resource
470     //! \param  [in] resource
471     //!         Pointer to MOS_RESOURCE
472     //! \return MOS_STATUS
473     //!         MOS_STATUS_SUCCESS if success, else fail reason
474     //!
475     MOS_STATUS SkipResourceSync(MOS_RESOURCE* resource);
476 
477     //!
478     //! \brief  Skip sync resource
479     //! \param  [in] buffer
480     //!         Pointer to MOS_BUFFER
481     //! \return MOS_STATUS
482     //!         MOS_STATUS_SUCCESS if success, else fail reason
483     //!
484     MOS_STATUS SkipResourceSync(MOS_BUFFER* buffer);
485 
486     //!
487     //! \brief  Check if resource is null
488     //! \param  [in] resource
489     //!         Pointer to MOS_RESOURCE
490     //! \return BOOL
491     //!         Return TRUE for nullptr resource, otherwise FALSE
492     //!
493     bool ResourceIsNull(MOS_RESOURCE* resource);
494 
495     //!
496     //! \brief  get surface info from resource
497     //! \param  [in, out] surface
498     //!         Pointer to MOS_RESOURCE
499     //! \return MOS_STATUS
500     //!         MOS_STATUS_SUCCESS if success, else fail reason
501     //!
502     MOS_STATUS GetSurfaceInfo(PMOS_SURFACE surface);
503 
504     //!
505     //! \brief    Update the GMM usage type of resource for cache policy
506     //! \details  Update the GMM usage type of resource for cache policy
507     //! \param    PMOS_RESOURCE OsResource
508     //!           [in] OS resource sturcture
509     //! \param    [in] resUsageType
510     //!           ResourceUsage to be set
511     //! \return   VOID
512     //!
513     MOS_STATUS UpdateResoreceUsageType(
514         PMOS_RESOURCE osResource,
515         ResourceUsage resUsageType);
516 
517     //!
518     //! \brief    Registers Resource
519     //! \details  Get the Allocation Index from UMD Context and set into OS
520     //!           resource structure
521     //! \param    PMOS_INTERFACE pOsInterface
522     //!           [in] Pointer to OS Interface
523     //! \param    PMOS_RESOURCE pOsResource
524     //!           [in/out] Pointer to OS Resource
525     //! \return   MOS_STATUS
526     //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
527     //!
528     MOS_STATUS RegisterResource(PMOS_RESOURCE osResource);
529 
530     //!
531     //! \brief    Convert from GMM usage type of resource to MOS_HW_RESOURCE_DEF
532     //! \details  Convert from GMM usage type of resource to MOS_HW_RESOURCE_DEF
533     //! \param    GMM_RESOURCE_USAGE_TYPE gmmResUsage
534     //!           [in] GMM usage type of resource
535     //! \return   ResourceUsage
536     //!
537     ResourceUsage ConvertGmmResourceUsage(const GMM_RESOURCE_USAGE_TYPE gmmResUsage);
538 
539 protected:
540     //!
541     //! \brief    Apply resource access requirement to allocate parameters
542     //! \details  Apply resource access requirement to allocate parameters
543     //! \param    ResourceAccessReq accessReq
544     //!           [in] Resource access requirement
545     //! \param    MOS_ALLOC_GFXRES_PARAMS allocParams
546     //!           [out] allocation parameters
547     //! \return   void
548     //!
549     void SetAccessRequirement(ResourceAccessReq accessReq, MOS_ALLOC_GFXRES_PARAMS &allocParams);
550 
551     PMOS_INTERFACE m_osInterface = nullptr;  //!< PMOS_INTERFACE
552     Allocator *m_allocator = nullptr;
553     bool m_limitedLMemBar = false; //!< Indicate if running with limited LMem bar config
554 
555 #if (_DEBUG || _RELEASE_INTERNAL)
556     bool m_forceLockable = false;
557 #endif
558 
559 MEDIA_CLASS_DEFINE_END(decode__DecodeAllocator)
560 };
561 }
562 #endif // !__DECODE_ALLOCATOR_H__
563