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