1e5c31af7Sopenharmony_ci#ifndef _VKTVIDEOBASEDECODEUTILS_HPP
2e5c31af7Sopenharmony_ci#define _VKTVIDEOBASEDECODEUTILS_HPP
3e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------
4e5c31af7Sopenharmony_ci * Vulkan Conformance Tests
5e5c31af7Sopenharmony_ci * ------------------------
6e5c31af7Sopenharmony_ci *
7e5c31af7Sopenharmony_ci * Copyright (c) 2021 The Khronos Group Inc.
8e5c31af7Sopenharmony_ci *
9e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
10e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License.
11e5c31af7Sopenharmony_ci * You may obtain a copy of the License at
12e5c31af7Sopenharmony_ci *
13e5c31af7Sopenharmony_ci *      http://www.apache.org/licenses/LICENSE-2.0
14e5c31af7Sopenharmony_ci *
15e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
16e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
17e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and
19e5c31af7Sopenharmony_ci * limitations under the License.
20e5c31af7Sopenharmony_ci *
21e5c31af7Sopenharmony_ci */
22e5c31af7Sopenharmony_ci/*!
23e5c31af7Sopenharmony_ci * \file
24e5c31af7Sopenharmony_ci * \brief Video Decoding Base Classe Functionality
25e5c31af7Sopenharmony_ci */
26e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*/
27e5c31af7Sopenharmony_ci/*
28e5c31af7Sopenharmony_ci * Copyright 2020 NVIDIA Corporation.
29e5c31af7Sopenharmony_ci *
30e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
31e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License.
32e5c31af7Sopenharmony_ci * You may obtain a copy of the License at
33e5c31af7Sopenharmony_ci *
34e5c31af7Sopenharmony_ci *    http://www.apache.org/licenses/LICENSE-2.0
35e5c31af7Sopenharmony_ci *
36e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
37e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
38e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
39e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and
40e5c31af7Sopenharmony_ci * limitations under the License.
41e5c31af7Sopenharmony_ci */
42e5c31af7Sopenharmony_ci
43e5c31af7Sopenharmony_ci#include "extNvidiaVideoParserIf.hpp"
44e5c31af7Sopenharmony_ci#include "vktVideoTestUtils.hpp"
45e5c31af7Sopenharmony_ci#include "vktVideoFrameBuffer.hpp"
46e5c31af7Sopenharmony_ci
47e5c31af7Sopenharmony_ci#include "deMemory.h"
48e5c31af7Sopenharmony_ci#include "vkBufferWithMemory.hpp"
49e5c31af7Sopenharmony_ci#include "vkImageWithMemory.hpp"
50e5c31af7Sopenharmony_ci
51e5c31af7Sopenharmony_ci#include <array>
52e5c31af7Sopenharmony_ci#include <bitset>
53e5c31af7Sopenharmony_ci#include <list>
54e5c31af7Sopenharmony_ci#include <queue>
55e5c31af7Sopenharmony_ci#include <vector>
56e5c31af7Sopenharmony_ci
57e5c31af7Sopenharmony_cinamespace vkt
58e5c31af7Sopenharmony_ci{
59e5c31af7Sopenharmony_cinamespace video
60e5c31af7Sopenharmony_ci{
61e5c31af7Sopenharmony_ci
62e5c31af7Sopenharmony_ciusing namespace vk;
63e5c31af7Sopenharmony_ciusing namespace std;
64e5c31af7Sopenharmony_ci
65e5c31af7Sopenharmony_ci#define MAKEFRAMERATE(num, den) (((num) << 14) | (den))
66e5c31af7Sopenharmony_ci#define NV_FRAME_RATE_NUM(rate) ((rate) >> 14)
67e5c31af7Sopenharmony_ci#define NV_FRAME_RATE_DEN(rate) ((rate)&0x3fff)
68e5c31af7Sopenharmony_ci
69e5c31af7Sopenharmony_ciconst uint64_t TIMEOUT_100ms = 100 * 1000 * 1000;
70e5c31af7Sopenharmony_ci
71e5c31af7Sopenharmony_ci// Keeps track of data associated with active internal reference frames
72e5c31af7Sopenharmony_ciclass DpbSlot
73e5c31af7Sopenharmony_ci{
74e5c31af7Sopenharmony_cipublic:
75e5c31af7Sopenharmony_ci	bool isInUse()
76e5c31af7Sopenharmony_ci	{
77e5c31af7Sopenharmony_ci		return (m_reserved || m_inUse);
78e5c31af7Sopenharmony_ci	}
79e5c31af7Sopenharmony_ci
80e5c31af7Sopenharmony_ci	bool isAvailable()
81e5c31af7Sopenharmony_ci	{
82e5c31af7Sopenharmony_ci		return !isInUse();
83e5c31af7Sopenharmony_ci	}
84e5c31af7Sopenharmony_ci
85e5c31af7Sopenharmony_ci	bool Invalidate()
86e5c31af7Sopenharmony_ci	{
87e5c31af7Sopenharmony_ci		bool wasInUse = isInUse();
88e5c31af7Sopenharmony_ci		if (m_picBuf)
89e5c31af7Sopenharmony_ci		{
90e5c31af7Sopenharmony_ci			m_picBuf->Release();
91e5c31af7Sopenharmony_ci			m_picBuf = NULL;
92e5c31af7Sopenharmony_ci		}
93e5c31af7Sopenharmony_ci
94e5c31af7Sopenharmony_ci		m_reserved = m_inUse = false;
95e5c31af7Sopenharmony_ci
96e5c31af7Sopenharmony_ci		return wasInUse;
97e5c31af7Sopenharmony_ci	}
98e5c31af7Sopenharmony_ci
99e5c31af7Sopenharmony_ci	vkPicBuffBase* getPictureResource()
100e5c31af7Sopenharmony_ci	{
101e5c31af7Sopenharmony_ci		return m_picBuf;
102e5c31af7Sopenharmony_ci	}
103e5c31af7Sopenharmony_ci
104e5c31af7Sopenharmony_ci	vkPicBuffBase* setPictureResource(vkPicBuffBase* picBuf, int32_t age = 0)
105e5c31af7Sopenharmony_ci	{
106e5c31af7Sopenharmony_ci		vkPicBuffBase* oldPic = m_picBuf;
107e5c31af7Sopenharmony_ci
108e5c31af7Sopenharmony_ci		if (picBuf)
109e5c31af7Sopenharmony_ci		{
110e5c31af7Sopenharmony_ci			picBuf->AddRef();
111e5c31af7Sopenharmony_ci		}
112e5c31af7Sopenharmony_ci		m_picBuf = picBuf;
113e5c31af7Sopenharmony_ci
114e5c31af7Sopenharmony_ci		if (oldPic)
115e5c31af7Sopenharmony_ci		{
116e5c31af7Sopenharmony_ci			oldPic->Release();
117e5c31af7Sopenharmony_ci		}
118e5c31af7Sopenharmony_ci
119e5c31af7Sopenharmony_ci		m_pictureId = age;
120e5c31af7Sopenharmony_ci		return oldPic;
121e5c31af7Sopenharmony_ci	}
122e5c31af7Sopenharmony_ci
123e5c31af7Sopenharmony_ci	void Reserve()
124e5c31af7Sopenharmony_ci	{
125e5c31af7Sopenharmony_ci		m_reserved = true;
126e5c31af7Sopenharmony_ci	}
127e5c31af7Sopenharmony_ci
128e5c31af7Sopenharmony_ci	void MarkInUse(int32_t age = 0)
129e5c31af7Sopenharmony_ci	{
130e5c31af7Sopenharmony_ci		m_pictureId = age;
131e5c31af7Sopenharmony_ci		m_inUse		= true;
132e5c31af7Sopenharmony_ci	}
133e5c31af7Sopenharmony_ci
134e5c31af7Sopenharmony_ci	int32_t getAge()
135e5c31af7Sopenharmony_ci	{
136e5c31af7Sopenharmony_ci		return m_pictureId;
137e5c31af7Sopenharmony_ci	}
138e5c31af7Sopenharmony_ci
139e5c31af7Sopenharmony_ciprivate:
140e5c31af7Sopenharmony_ci	int32_t		   m_pictureId; // PictureID at map time (age)
141e5c31af7Sopenharmony_ci	vkPicBuffBase* m_picBuf; // Associated resource
142e5c31af7Sopenharmony_ci
143e5c31af7Sopenharmony_ci	deUint32	   m_reserved : 1;
144e5c31af7Sopenharmony_ci	deUint32	   m_inUse : 1;
145e5c31af7Sopenharmony_ci};
146e5c31af7Sopenharmony_ci
147e5c31af7Sopenharmony_ciclass DpbSlots
148e5c31af7Sopenharmony_ci{
149e5c31af7Sopenharmony_cipublic:
150e5c31af7Sopenharmony_ci	explicit DpbSlots(deUint8 dpbMaxSize)
151e5c31af7Sopenharmony_ci		: m_dpbMaxSize(0)
152e5c31af7Sopenharmony_ci		, m_slotInUseMask(0)
153e5c31af7Sopenharmony_ci		, m_dpb(m_dpbMaxSize)
154e5c31af7Sopenharmony_ci		, m_dpbSlotsAvailable()
155e5c31af7Sopenharmony_ci	{
156e5c31af7Sopenharmony_ci		Init(dpbMaxSize, false);
157e5c31af7Sopenharmony_ci	}
158e5c31af7Sopenharmony_ci
159e5c31af7Sopenharmony_ci	int32_t Init(deUint8 newDpbMaxSize, bool reconfigure)
160e5c31af7Sopenharmony_ci	{
161e5c31af7Sopenharmony_ci		DE_ASSERT(newDpbMaxSize <= VkParserPerFrameDecodeParameters::MAX_DPB_REF_AND_SETUP_SLOTS);
162e5c31af7Sopenharmony_ci
163e5c31af7Sopenharmony_ci		if (!reconfigure)
164e5c31af7Sopenharmony_ci		{
165e5c31af7Sopenharmony_ci			Deinit();
166e5c31af7Sopenharmony_ci		}
167e5c31af7Sopenharmony_ci
168e5c31af7Sopenharmony_ci		if (reconfigure && (newDpbMaxSize < m_dpbMaxSize))
169e5c31af7Sopenharmony_ci		{
170e5c31af7Sopenharmony_ci			return m_dpbMaxSize;
171e5c31af7Sopenharmony_ci		}
172e5c31af7Sopenharmony_ci
173e5c31af7Sopenharmony_ci		deUint8 oldDpbMaxSize = reconfigure ? m_dpbMaxSize : 0;
174e5c31af7Sopenharmony_ci		m_dpbMaxSize		  = newDpbMaxSize;
175e5c31af7Sopenharmony_ci
176e5c31af7Sopenharmony_ci		m_dpb.resize(m_dpbMaxSize);
177e5c31af7Sopenharmony_ci
178e5c31af7Sopenharmony_ci		for (deUint32 ndx = oldDpbMaxSize; ndx < m_dpbMaxSize; ndx++)
179e5c31af7Sopenharmony_ci		{
180e5c31af7Sopenharmony_ci			m_dpb[ndx].Invalidate();
181e5c31af7Sopenharmony_ci		}
182e5c31af7Sopenharmony_ci
183e5c31af7Sopenharmony_ci		for (deUint8 dpbIndx = oldDpbMaxSize; dpbIndx < m_dpbMaxSize; dpbIndx++)
184e5c31af7Sopenharmony_ci		{
185e5c31af7Sopenharmony_ci			m_dpbSlotsAvailable.push(dpbIndx);
186e5c31af7Sopenharmony_ci		}
187e5c31af7Sopenharmony_ci
188e5c31af7Sopenharmony_ci		return m_dpbMaxSize;
189e5c31af7Sopenharmony_ci	}
190e5c31af7Sopenharmony_ci
191e5c31af7Sopenharmony_ci	void Deinit()
192e5c31af7Sopenharmony_ci	{
193e5c31af7Sopenharmony_ci		for (deUint32 ndx = 0; ndx < m_dpbMaxSize; ndx++)
194e5c31af7Sopenharmony_ci		{
195e5c31af7Sopenharmony_ci			m_dpb[ndx].Invalidate();
196e5c31af7Sopenharmony_ci		}
197e5c31af7Sopenharmony_ci
198e5c31af7Sopenharmony_ci		while (!m_dpbSlotsAvailable.empty())
199e5c31af7Sopenharmony_ci		{
200e5c31af7Sopenharmony_ci			m_dpbSlotsAvailable.pop();
201e5c31af7Sopenharmony_ci		}
202e5c31af7Sopenharmony_ci
203e5c31af7Sopenharmony_ci		m_dpbMaxSize	= 0;
204e5c31af7Sopenharmony_ci		m_slotInUseMask = 0;
205e5c31af7Sopenharmony_ci	}
206e5c31af7Sopenharmony_ci
207e5c31af7Sopenharmony_ci	~DpbSlots()
208e5c31af7Sopenharmony_ci	{
209e5c31af7Sopenharmony_ci		Deinit();
210e5c31af7Sopenharmony_ci	}
211e5c31af7Sopenharmony_ci
212e5c31af7Sopenharmony_ci	int8_t AllocateSlot()
213e5c31af7Sopenharmony_ci	{
214e5c31af7Sopenharmony_ci		if (m_dpbSlotsAvailable.empty())
215e5c31af7Sopenharmony_ci		{
216e5c31af7Sopenharmony_ci			DE_ASSERT(!"No more h.264/5 DPB slots are available");
217e5c31af7Sopenharmony_ci			return -1;
218e5c31af7Sopenharmony_ci		}
219e5c31af7Sopenharmony_ci		int8_t slot = (int8_t)m_dpbSlotsAvailable.front();
220e5c31af7Sopenharmony_ci		DE_ASSERT((slot >= 0) && ((deUint8)slot < m_dpbMaxSize));
221e5c31af7Sopenharmony_ci		m_slotInUseMask |= (1 << slot);
222e5c31af7Sopenharmony_ci		m_dpbSlotsAvailable.pop();
223e5c31af7Sopenharmony_ci		m_dpb[slot].Reserve();
224e5c31af7Sopenharmony_ci		return slot;
225e5c31af7Sopenharmony_ci	}
226e5c31af7Sopenharmony_ci
227e5c31af7Sopenharmony_ci	void FreeSlot(int8_t slot)
228e5c31af7Sopenharmony_ci	{
229e5c31af7Sopenharmony_ci		DE_ASSERT((deUint8)slot < m_dpbMaxSize);
230e5c31af7Sopenharmony_ci		DE_ASSERT(m_dpb[slot].isInUse());
231e5c31af7Sopenharmony_ci		DE_ASSERT(m_slotInUseMask & (1 << slot));
232e5c31af7Sopenharmony_ci
233e5c31af7Sopenharmony_ci		m_dpb[slot].Invalidate();
234e5c31af7Sopenharmony_ci		m_dpbSlotsAvailable.push(slot);
235e5c31af7Sopenharmony_ci		m_slotInUseMask &= ~(1 << slot);
236e5c31af7Sopenharmony_ci	}
237e5c31af7Sopenharmony_ci
238e5c31af7Sopenharmony_ci	DpbSlot& operator[](deUint32 slot)
239e5c31af7Sopenharmony_ci	{
240e5c31af7Sopenharmony_ci		DE_ASSERT(slot < m_dpbMaxSize);
241e5c31af7Sopenharmony_ci		return m_dpb[slot];
242e5c31af7Sopenharmony_ci	}
243e5c31af7Sopenharmony_ci
244e5c31af7Sopenharmony_ci	// Return the remapped index given an external decode render target index
245e5c31af7Sopenharmony_ci	int8_t GetSlotOfPictureResource(vkPicBuffBase* pPic)
246e5c31af7Sopenharmony_ci	{
247e5c31af7Sopenharmony_ci		for (int8_t i = 0; i < (int8_t)m_dpbMaxSize; i++)
248e5c31af7Sopenharmony_ci		{
249e5c31af7Sopenharmony_ci			if ((m_slotInUseMask & (1 << i)) && m_dpb[i].isInUse() && (pPic == m_dpb[i].getPictureResource()))
250e5c31af7Sopenharmony_ci			{
251e5c31af7Sopenharmony_ci				return i;
252e5c31af7Sopenharmony_ci			}
253e5c31af7Sopenharmony_ci		}
254e5c31af7Sopenharmony_ci		return -1; // not found
255e5c31af7Sopenharmony_ci	}
256e5c31af7Sopenharmony_ci
257e5c31af7Sopenharmony_ci	void MapPictureResource(vkPicBuffBase* pPic, deUint8 dpbSlot, int32_t age = 0)
258e5c31af7Sopenharmony_ci	{
259e5c31af7Sopenharmony_ci		for (deUint8 slot = 0; slot < m_dpbMaxSize; slot++)
260e5c31af7Sopenharmony_ci		{
261e5c31af7Sopenharmony_ci			if (slot == dpbSlot)
262e5c31af7Sopenharmony_ci			{
263e5c31af7Sopenharmony_ci				m_dpb[slot].setPictureResource(pPic, age);
264e5c31af7Sopenharmony_ci			}
265e5c31af7Sopenharmony_ci			else if (pPic)
266e5c31af7Sopenharmony_ci			{
267e5c31af7Sopenharmony_ci				if (m_dpb[slot].getPictureResource() == pPic)
268e5c31af7Sopenharmony_ci				{
269e5c31af7Sopenharmony_ci					FreeSlot(slot);
270e5c31af7Sopenharmony_ci				}
271e5c31af7Sopenharmony_ci			}
272e5c31af7Sopenharmony_ci		}
273e5c31af7Sopenharmony_ci	}
274e5c31af7Sopenharmony_ci
275e5c31af7Sopenharmony_ci	deUint32 getSlotInUseMask()
276e5c31af7Sopenharmony_ci	{
277e5c31af7Sopenharmony_ci		return m_slotInUseMask;
278e5c31af7Sopenharmony_ci	}
279e5c31af7Sopenharmony_ci
280e5c31af7Sopenharmony_ci	deUint32 getMaxSize()
281e5c31af7Sopenharmony_ci	{
282e5c31af7Sopenharmony_ci		return m_dpbMaxSize;
283e5c31af7Sopenharmony_ci	}
284e5c31af7Sopenharmony_ci
285e5c31af7Sopenharmony_ciprivate:
286e5c31af7Sopenharmony_ci	deUint8				 m_dpbMaxSize;
287e5c31af7Sopenharmony_ci	deUint32			 m_slotInUseMask;
288e5c31af7Sopenharmony_ci	std::vector<DpbSlot> m_dpb;
289e5c31af7Sopenharmony_ci	std::queue<deUint8>	 m_dpbSlotsAvailable;
290e5c31af7Sopenharmony_ci};
291e5c31af7Sopenharmony_ci
292e5c31af7Sopenharmony_ciclass VulkanVideoSession : public VkVideoRefCountBase
293e5c31af7Sopenharmony_ci{
294e5c31af7Sopenharmony_ci	enum
295e5c31af7Sopenharmony_ci	{
296e5c31af7Sopenharmony_ci		MAX_BOUND_MEMORY = 9
297e5c31af7Sopenharmony_ci	};
298e5c31af7Sopenharmony_ci
299e5c31af7Sopenharmony_cipublic:
300e5c31af7Sopenharmony_ci	static VkResult Create(DeviceContext&						devCtx,
301e5c31af7Sopenharmony_ci						   deUint32								videoQueueFamily,
302e5c31af7Sopenharmony_ci						   VkVideoCoreProfile*					pVideoProfile,
303e5c31af7Sopenharmony_ci						   VkFormat								pictureFormat,
304e5c31af7Sopenharmony_ci						   const VkExtent2D&					maxCodedExtent,
305e5c31af7Sopenharmony_ci						   VkFormat								referencePicturesFormat,
306e5c31af7Sopenharmony_ci						   deUint32								maxDpbSlots,
307e5c31af7Sopenharmony_ci						   deUint32								maxActiveReferencePictures,
308e5c31af7Sopenharmony_ci						   VkSharedBaseObj<VulkanVideoSession>& videoSession);
309e5c31af7Sopenharmony_ci
310e5c31af7Sopenharmony_ci	bool			IsCompatible(VkDevice			 device,
311e5c31af7Sopenharmony_ci								 deUint32			 videoQueueFamily,
312e5c31af7Sopenharmony_ci								 VkVideoCoreProfile* pVideoProfile,
313e5c31af7Sopenharmony_ci								 VkFormat			 pictureFormat,
314e5c31af7Sopenharmony_ci								 const VkExtent2D&	 maxCodedExtent,
315e5c31af7Sopenharmony_ci								 VkFormat			 referencePicturesFormat,
316e5c31af7Sopenharmony_ci								 deUint32			 maxDpbSlots,
317e5c31af7Sopenharmony_ci								 deUint32			 maxActiveReferencePictures)
318e5c31af7Sopenharmony_ci	{
319e5c31af7Sopenharmony_ci		if (*pVideoProfile != m_profile)
320e5c31af7Sopenharmony_ci		{
321e5c31af7Sopenharmony_ci			return false;
322e5c31af7Sopenharmony_ci		}
323e5c31af7Sopenharmony_ci
324e5c31af7Sopenharmony_ci		if (maxCodedExtent.width > m_createInfo.maxCodedExtent.width)
325e5c31af7Sopenharmony_ci		{
326e5c31af7Sopenharmony_ci			return false;
327e5c31af7Sopenharmony_ci		}
328e5c31af7Sopenharmony_ci
329e5c31af7Sopenharmony_ci		if (maxCodedExtent.height > m_createInfo.maxCodedExtent.height)
330e5c31af7Sopenharmony_ci		{
331e5c31af7Sopenharmony_ci			return false;
332e5c31af7Sopenharmony_ci		}
333e5c31af7Sopenharmony_ci
334e5c31af7Sopenharmony_ci		if (maxDpbSlots > m_createInfo.maxDpbSlots)
335e5c31af7Sopenharmony_ci		{
336e5c31af7Sopenharmony_ci			return false;
337e5c31af7Sopenharmony_ci		}
338e5c31af7Sopenharmony_ci
339e5c31af7Sopenharmony_ci		if (maxActiveReferencePictures > m_createInfo.maxActiveReferencePictures)
340e5c31af7Sopenharmony_ci		{
341e5c31af7Sopenharmony_ci			return false;
342e5c31af7Sopenharmony_ci		}
343e5c31af7Sopenharmony_ci
344e5c31af7Sopenharmony_ci		if (m_createInfo.referencePictureFormat != referencePicturesFormat)
345e5c31af7Sopenharmony_ci		{
346e5c31af7Sopenharmony_ci			return false;
347e5c31af7Sopenharmony_ci		}
348e5c31af7Sopenharmony_ci
349e5c31af7Sopenharmony_ci		if (m_createInfo.pictureFormat != pictureFormat)
350e5c31af7Sopenharmony_ci		{
351e5c31af7Sopenharmony_ci			return false;
352e5c31af7Sopenharmony_ci		}
353e5c31af7Sopenharmony_ci
354e5c31af7Sopenharmony_ci		if (m_devCtx.device != device)
355e5c31af7Sopenharmony_ci		{
356e5c31af7Sopenharmony_ci			return false;
357e5c31af7Sopenharmony_ci		}
358e5c31af7Sopenharmony_ci
359e5c31af7Sopenharmony_ci		if (m_createInfo.queueFamilyIndex != videoQueueFamily)
360e5c31af7Sopenharmony_ci		{
361e5c31af7Sopenharmony_ci			return false;
362e5c31af7Sopenharmony_ci		}
363e5c31af7Sopenharmony_ci
364e5c31af7Sopenharmony_ci		return true;
365e5c31af7Sopenharmony_ci	}
366e5c31af7Sopenharmony_ci
367e5c31af7Sopenharmony_ci	int32_t AddRef() override
368e5c31af7Sopenharmony_ci	{
369e5c31af7Sopenharmony_ci		return ++m_refCount;
370e5c31af7Sopenharmony_ci	}
371e5c31af7Sopenharmony_ci
372e5c31af7Sopenharmony_ci	int32_t Release() override
373e5c31af7Sopenharmony_ci	{
374e5c31af7Sopenharmony_ci		deUint32 ret = --m_refCount;
375e5c31af7Sopenharmony_ci		// Destroy the device if refcount reaches zero
376e5c31af7Sopenharmony_ci		if (ret == 0)
377e5c31af7Sopenharmony_ci		{
378e5c31af7Sopenharmony_ci			delete this;
379e5c31af7Sopenharmony_ci		}
380e5c31af7Sopenharmony_ci		return ret;
381e5c31af7Sopenharmony_ci	}
382e5c31af7Sopenharmony_ci
383e5c31af7Sopenharmony_ci	VkVideoSessionKHR GetVideoSession() const
384e5c31af7Sopenharmony_ci	{
385e5c31af7Sopenharmony_ci		return m_videoSession;
386e5c31af7Sopenharmony_ci	}
387e5c31af7Sopenharmony_ci
388e5c31af7Sopenharmony_ciprivate:
389e5c31af7Sopenharmony_ci	VulkanVideoSession(DeviceContext&	   devCtx,
390e5c31af7Sopenharmony_ci					   VkVideoCoreProfile* pVideoProfile)
391e5c31af7Sopenharmony_ci		: m_refCount(0), m_profile(*pVideoProfile), m_devCtx(devCtx), m_videoSession(VkVideoSessionKHR(0))
392e5c31af7Sopenharmony_ci	{
393e5c31af7Sopenharmony_ci		deMemset(&m_createInfo, 0, sizeof(VkVideoSessionCreateInfoKHR));
394e5c31af7Sopenharmony_ci		m_createInfo.sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_CREATE_INFO_KHR;
395e5c31af7Sopenharmony_ci
396e5c31af7Sopenharmony_ci		for (auto & binding : m_memoryBound)
397e5c31af7Sopenharmony_ci		{
398e5c31af7Sopenharmony_ci			binding = VK_NULL_HANDLE;
399e5c31af7Sopenharmony_ci		}
400e5c31af7Sopenharmony_ci	}
401e5c31af7Sopenharmony_ci
402e5c31af7Sopenharmony_ci	~VulkanVideoSession() override
403e5c31af7Sopenharmony_ci	{
404e5c31af7Sopenharmony_ci		auto& vk = m_devCtx.getDeviceDriver();
405e5c31af7Sopenharmony_ci		if (!!m_videoSession)
406e5c31af7Sopenharmony_ci		{
407e5c31af7Sopenharmony_ci			vk.destroyVideoSessionKHR(m_devCtx.device, m_videoSession, NULL);
408e5c31af7Sopenharmony_ci			m_videoSession = VK_NULL_HANDLE;
409e5c31af7Sopenharmony_ci		}
410e5c31af7Sopenharmony_ci
411e5c31af7Sopenharmony_ci		for (deUint32 memIdx = 0; memIdx < MAX_BOUND_MEMORY; memIdx++)
412e5c31af7Sopenharmony_ci		{
413e5c31af7Sopenharmony_ci			if (m_memoryBound[memIdx] != VK_NULL_HANDLE)
414e5c31af7Sopenharmony_ci			{
415e5c31af7Sopenharmony_ci				vk.freeMemory(m_devCtx.device, m_memoryBound[memIdx], 0);
416e5c31af7Sopenharmony_ci				m_memoryBound[memIdx] = VK_NULL_HANDLE;
417e5c31af7Sopenharmony_ci			}
418e5c31af7Sopenharmony_ci		}
419e5c31af7Sopenharmony_ci	}
420e5c31af7Sopenharmony_ci
421e5c31af7Sopenharmony_ciprivate:
422e5c31af7Sopenharmony_ci	std::atomic<int32_t>		m_refCount;
423e5c31af7Sopenharmony_ci	VkVideoCoreProfile			m_profile;
424e5c31af7Sopenharmony_ci	DeviceContext&				m_devCtx;
425e5c31af7Sopenharmony_ci	VkVideoSessionCreateInfoKHR m_createInfo;
426e5c31af7Sopenharmony_ci	VkVideoSessionKHR			m_videoSession;
427e5c31af7Sopenharmony_ci	VkDeviceMemory				m_memoryBound[MAX_BOUND_MEMORY];
428e5c31af7Sopenharmony_ci};
429e5c31af7Sopenharmony_ci
430e5c31af7Sopenharmony_ciclass VkParserVideoPictureParameters : public VkVideoRefCountBase
431e5c31af7Sopenharmony_ci{
432e5c31af7Sopenharmony_cipublic:
433e5c31af7Sopenharmony_ci	static const deUint32				   MAX_VPS_IDS = 16;
434e5c31af7Sopenharmony_ci	static const deUint32				   MAX_SPS_IDS = 32;
435e5c31af7Sopenharmony_ci	static const deUint32				   MAX_PPS_IDS = 256;
436e5c31af7Sopenharmony_ci
437e5c31af7Sopenharmony_ci	//! Increment the reference count by 1.
438e5c31af7Sopenharmony_ci	virtual int32_t						   AddRef();
439e5c31af7Sopenharmony_ci
440e5c31af7Sopenharmony_ci	//! Decrement the reference count by 1. When the reference count
441e5c31af7Sopenharmony_ci	//! goes to 0 the object is automatically destroyed.
442e5c31af7Sopenharmony_ci	virtual int32_t						   Release();
443e5c31af7Sopenharmony_ci
444e5c31af7Sopenharmony_ci	static VkParserVideoPictureParameters* VideoPictureParametersFromBase(VkVideoRefCountBase* pBase)
445e5c31af7Sopenharmony_ci	{
446e5c31af7Sopenharmony_ci		if (!pBase)
447e5c31af7Sopenharmony_ci		{
448e5c31af7Sopenharmony_ci			return NULL;
449e5c31af7Sopenharmony_ci		}
450e5c31af7Sopenharmony_ci		VkParserVideoPictureParameters* pPictureParameters = static_cast<VkParserVideoPictureParameters*>(pBase);
451e5c31af7Sopenharmony_ci		if (m_refClassId == pPictureParameters->m_classId)
452e5c31af7Sopenharmony_ci		{
453e5c31af7Sopenharmony_ci			return pPictureParameters;
454e5c31af7Sopenharmony_ci		}
455e5c31af7Sopenharmony_ci		DE_ASSERT(false && "Invalid VkParserVideoPictureParameters from base");
456e5c31af7Sopenharmony_ci		return nullptr;
457e5c31af7Sopenharmony_ci	}
458e5c31af7Sopenharmony_ci
459e5c31af7Sopenharmony_ci	static VkResult AddPictureParameters(DeviceContext&									  deviceContext,
460e5c31af7Sopenharmony_ci										 VkSharedBaseObj<VulkanVideoSession>&			  videoSession,
461e5c31af7Sopenharmony_ci										 VkSharedBaseObj<StdVideoPictureParametersSet>&	  stdPictureParametersSet,
462e5c31af7Sopenharmony_ci										 VkSharedBaseObj<VkParserVideoPictureParameters>& currentVideoPictureParameters);
463e5c31af7Sopenharmony_ci
464e5c31af7Sopenharmony_ci	static bool		CheckStdObjectBeforeUpdate(VkSharedBaseObj<StdVideoPictureParametersSet>&	pictureParametersSet,
465e5c31af7Sopenharmony_ci											   VkSharedBaseObj<VkParserVideoPictureParameters>& currentVideoPictureParameters);
466e5c31af7Sopenharmony_ci
467e5c31af7Sopenharmony_ci	static VkResult Create(DeviceContext&									deviceContext,
468e5c31af7Sopenharmony_ci						   VkSharedBaseObj<VkParserVideoPictureParameters>& templatePictureParameters,
469e5c31af7Sopenharmony_ci						   VkSharedBaseObj<VkParserVideoPictureParameters>& videoPictureParameters);
470e5c31af7Sopenharmony_ci
471e5c31af7Sopenharmony_ci	static int32_t	PopulateH264UpdateFields(const StdVideoPictureParametersSet*		   pStdPictureParametersSet,
472e5c31af7Sopenharmony_ci											 VkVideoDecodeH264SessionParametersAddInfoKHR& h264SessionParametersAddInfo);
473e5c31af7Sopenharmony_ci
474e5c31af7Sopenharmony_ci	static int32_t	PopulateH265UpdateFields(const StdVideoPictureParametersSet*		   pStdPictureParametersSet,
475e5c31af7Sopenharmony_ci											 VkVideoDecodeH265SessionParametersAddInfoKHR& h265SessionParametersAddInfo);
476e5c31af7Sopenharmony_ci
477e5c31af7Sopenharmony_ci	VkResult		CreateParametersObject(VkSharedBaseObj<VulkanVideoSession>& videoSession,
478e5c31af7Sopenharmony_ci										   const StdVideoPictureParametersSet*	pStdVideoPictureParametersSet,
479e5c31af7Sopenharmony_ci										   VkParserVideoPictureParameters*		pTemplatePictureParameters);
480e5c31af7Sopenharmony_ci
481e5c31af7Sopenharmony_ci	VkResult		UpdateParametersObject(StdVideoPictureParametersSet* pStdVideoPictureParametersSet);
482e5c31af7Sopenharmony_ci
483e5c31af7Sopenharmony_ci	VkResult		HandleNewPictureParametersSet(VkSharedBaseObj<VulkanVideoSession>& videoSession,
484e5c31af7Sopenharmony_ci												  StdVideoPictureParametersSet*		   pStdVideoPictureParametersSet);
485e5c31af7Sopenharmony_ci
486e5c31af7Sopenharmony_ci	operator VkVideoSessionParametersKHR() const
487e5c31af7Sopenharmony_ci	{
488e5c31af7Sopenharmony_ci		DE_ASSERT(m_sessionParameters != VK_NULL_HANDLE);
489e5c31af7Sopenharmony_ci		return m_sessionParameters;
490e5c31af7Sopenharmony_ci	}
491e5c31af7Sopenharmony_ci
492e5c31af7Sopenharmony_ci	VkVideoSessionParametersKHR GetVideoSessionParametersKHR() const
493e5c31af7Sopenharmony_ci	{
494e5c31af7Sopenharmony_ci		DE_ASSERT(m_sessionParameters != VK_NULL_HANDLE);
495e5c31af7Sopenharmony_ci		return m_sessionParameters;
496e5c31af7Sopenharmony_ci	}
497e5c31af7Sopenharmony_ci
498e5c31af7Sopenharmony_ci	int32_t GetId() const
499e5c31af7Sopenharmony_ci	{
500e5c31af7Sopenharmony_ci		return m_Id;
501e5c31af7Sopenharmony_ci	}
502e5c31af7Sopenharmony_ci
503e5c31af7Sopenharmony_ci	bool HasVpsId(deUint32 vpsId) const
504e5c31af7Sopenharmony_ci	{
505e5c31af7Sopenharmony_ci		DE_ASSERT(vpsId < MAX_VPS_IDS);
506e5c31af7Sopenharmony_ci		return m_vpsIdsUsed[vpsId];
507e5c31af7Sopenharmony_ci	}
508e5c31af7Sopenharmony_ci
509e5c31af7Sopenharmony_ci	bool HasSpsId(deUint32 spsId) const
510e5c31af7Sopenharmony_ci	{
511e5c31af7Sopenharmony_ci		DE_ASSERT(spsId < MAX_SPS_IDS);
512e5c31af7Sopenharmony_ci		return m_spsIdsUsed[spsId];
513e5c31af7Sopenharmony_ci	}
514e5c31af7Sopenharmony_ci
515e5c31af7Sopenharmony_ci	bool HasPpsId(deUint32 ppsId) const
516e5c31af7Sopenharmony_ci	{
517e5c31af7Sopenharmony_ci		DE_ASSERT(ppsId < MAX_PPS_IDS);
518e5c31af7Sopenharmony_ci		return m_ppsIdsUsed[ppsId];
519e5c31af7Sopenharmony_ci	}
520e5c31af7Sopenharmony_ci
521e5c31af7Sopenharmony_ci	bool	 UpdatePictureParametersHierarchy(VkSharedBaseObj<StdVideoPictureParametersSet>& pictureParametersObject);
522e5c31af7Sopenharmony_ci
523e5c31af7Sopenharmony_ci	VkResult AddPictureParametersToQueue(VkSharedBaseObj<StdVideoPictureParametersSet>& pictureParametersSet);
524e5c31af7Sopenharmony_ci	int32_t	 FlushPictureParametersQueue(VkSharedBaseObj<VulkanVideoSession>& videoSession);
525e5c31af7Sopenharmony_ci
526e5c31af7Sopenharmony_ciprotected:
527e5c31af7Sopenharmony_ci	VkParserVideoPictureParameters(DeviceContext&									deviceContext,
528e5c31af7Sopenharmony_ci								   VkSharedBaseObj<VkParserVideoPictureParameters>& templatePictureParameters)
529e5c31af7Sopenharmony_ci		: m_classId(m_refClassId), m_Id(-1), m_refCount(0), m_deviceContext(deviceContext), m_videoSession(), m_sessionParameters(VK_NULL_HANDLE), m_templatePictureParameters(templatePictureParameters)
530e5c31af7Sopenharmony_ci	{
531e5c31af7Sopenharmony_ci	}
532e5c31af7Sopenharmony_ci
533e5c31af7Sopenharmony_ci	virtual ~VkParserVideoPictureParameters();
534e5c31af7Sopenharmony_ci
535e5c31af7Sopenharmony_ciprivate:
536e5c31af7Sopenharmony_ci	static const char*										  m_refClassId;
537e5c31af7Sopenharmony_ci	static int32_t											  m_currentId;
538e5c31af7Sopenharmony_ci	const char*												  m_classId;
539e5c31af7Sopenharmony_ci	int32_t													  m_Id;
540e5c31af7Sopenharmony_ci	std::atomic<int32_t>									  m_refCount;
541e5c31af7Sopenharmony_ci	DeviceContext&											  m_deviceContext;
542e5c31af7Sopenharmony_ci	VkSharedBaseObj<VulkanVideoSession>						  m_videoSession;
543e5c31af7Sopenharmony_ci	VkVideoSessionParametersKHR								  m_sessionParameters;
544e5c31af7Sopenharmony_ci	std::bitset<MAX_VPS_IDS>								  m_vpsIdsUsed;
545e5c31af7Sopenharmony_ci	std::bitset<MAX_SPS_IDS>								  m_spsIdsUsed;
546e5c31af7Sopenharmony_ci	std::bitset<MAX_PPS_IDS>								  m_ppsIdsUsed;
547e5c31af7Sopenharmony_ci	int														  m_updateCount{0};
548e5c31af7Sopenharmony_ci	VkSharedBaseObj<VkParserVideoPictureParameters>			  m_templatePictureParameters; // needed only for the create
549e5c31af7Sopenharmony_ci
550e5c31af7Sopenharmony_ci	std::queue<VkSharedBaseObj<StdVideoPictureParametersSet>> m_pictureParametersQueue;
551e5c31af7Sopenharmony_ci	VkSharedBaseObj<StdVideoPictureParametersSet>			  m_lastPictParamsQueue[StdVideoPictureParametersSet::NUM_OF_TYPES];
552e5c31af7Sopenharmony_ci};
553e5c31af7Sopenharmony_ci
554e5c31af7Sopenharmony_cistruct nvVideoDecodeH264DpbSlotInfo
555e5c31af7Sopenharmony_ci{
556e5c31af7Sopenharmony_ci	VkVideoDecodeH264DpbSlotInfoKHR dpbSlotInfo;
557e5c31af7Sopenharmony_ci	StdVideoDecodeH264ReferenceInfo stdReferenceInfo;
558e5c31af7Sopenharmony_ci
559e5c31af7Sopenharmony_ci	nvVideoDecodeH264DpbSlotInfo()
560e5c31af7Sopenharmony_ci		: dpbSlotInfo()
561e5c31af7Sopenharmony_ci		, stdReferenceInfo()
562e5c31af7Sopenharmony_ci	{
563e5c31af7Sopenharmony_ci	}
564e5c31af7Sopenharmony_ci
565e5c31af7Sopenharmony_ci	const VkVideoDecodeH264DpbSlotInfoKHR* Init(int8_t slotIndex)
566e5c31af7Sopenharmony_ci	{
567e5c31af7Sopenharmony_ci		DE_ASSERT((slotIndex >= 0) && (slotIndex < (int8_t)VkParserPerFrameDecodeParameters::MAX_DPB_REF_AND_SETUP_SLOTS));
568e5c31af7Sopenharmony_ci		DE_UNREF(slotIndex);
569e5c31af7Sopenharmony_ci		dpbSlotInfo.sType			  = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_DPB_SLOT_INFO_KHR;
570e5c31af7Sopenharmony_ci		dpbSlotInfo.pNext			  = NULL;
571e5c31af7Sopenharmony_ci		dpbSlotInfo.pStdReferenceInfo = &stdReferenceInfo;
572e5c31af7Sopenharmony_ci		return &dpbSlotInfo;
573e5c31af7Sopenharmony_ci	}
574e5c31af7Sopenharmony_ci
575e5c31af7Sopenharmony_ci	bool IsReference() const
576e5c31af7Sopenharmony_ci	{
577e5c31af7Sopenharmony_ci		return (dpbSlotInfo.pStdReferenceInfo == &stdReferenceInfo);
578e5c31af7Sopenharmony_ci	}
579e5c31af7Sopenharmony_ci
580e5c31af7Sopenharmony_ci	operator bool() const
581e5c31af7Sopenharmony_ci	{
582e5c31af7Sopenharmony_ci		return IsReference();
583e5c31af7Sopenharmony_ci	}
584e5c31af7Sopenharmony_ci	void Invalidate()
585e5c31af7Sopenharmony_ci	{
586e5c31af7Sopenharmony_ci		memset(this, 0x00, sizeof(*this));
587e5c31af7Sopenharmony_ci	}
588e5c31af7Sopenharmony_ci};
589e5c31af7Sopenharmony_ci
590e5c31af7Sopenharmony_cistruct nvVideoDecodeH265DpbSlotInfo
591e5c31af7Sopenharmony_ci{
592e5c31af7Sopenharmony_ci	VkVideoDecodeH265DpbSlotInfoKHR dpbSlotInfo;
593e5c31af7Sopenharmony_ci	StdVideoDecodeH265ReferenceInfo stdReferenceInfo;
594e5c31af7Sopenharmony_ci
595e5c31af7Sopenharmony_ci	nvVideoDecodeH265DpbSlotInfo()
596e5c31af7Sopenharmony_ci		: dpbSlotInfo()
597e5c31af7Sopenharmony_ci		, stdReferenceInfo()
598e5c31af7Sopenharmony_ci	{
599e5c31af7Sopenharmony_ci	}
600e5c31af7Sopenharmony_ci
601e5c31af7Sopenharmony_ci	const VkVideoDecodeH265DpbSlotInfoKHR* Init(int8_t slotIndex)
602e5c31af7Sopenharmony_ci	{
603e5c31af7Sopenharmony_ci		DE_ASSERT((slotIndex >= 0) && (slotIndex < (int8_t)VkParserPerFrameDecodeParameters::MAX_DPB_REF_SLOTS));
604e5c31af7Sopenharmony_ci		DE_UNREF(slotIndex);
605e5c31af7Sopenharmony_ci		dpbSlotInfo.sType			  = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_DPB_SLOT_INFO_KHR;
606e5c31af7Sopenharmony_ci		dpbSlotInfo.pNext			  = NULL;
607e5c31af7Sopenharmony_ci		dpbSlotInfo.pStdReferenceInfo = &stdReferenceInfo;
608e5c31af7Sopenharmony_ci		return &dpbSlotInfo;
609e5c31af7Sopenharmony_ci	}
610e5c31af7Sopenharmony_ci
611e5c31af7Sopenharmony_ci	bool IsReference() const
612e5c31af7Sopenharmony_ci	{
613e5c31af7Sopenharmony_ci		return (dpbSlotInfo.pStdReferenceInfo == &stdReferenceInfo);
614e5c31af7Sopenharmony_ci	}
615e5c31af7Sopenharmony_ci
616e5c31af7Sopenharmony_ci	operator bool() const
617e5c31af7Sopenharmony_ci	{
618e5c31af7Sopenharmony_ci		return IsReference();
619e5c31af7Sopenharmony_ci	}
620e5c31af7Sopenharmony_ci
621e5c31af7Sopenharmony_ci	void Invalidate()
622e5c31af7Sopenharmony_ci	{
623e5c31af7Sopenharmony_ci		memset(this, 0x00, sizeof(*this));
624e5c31af7Sopenharmony_ci	}
625e5c31af7Sopenharmony_ci};
626e5c31af7Sopenharmony_ci
627e5c31af7Sopenharmony_ci// TODO: These optimizations from the NVIDIA sample code are not worth it for CTS.
628e5c31af7Sopenharmony_ciusing VulkanBitstreamBufferPool = VulkanVideoRefCountedPool<BitstreamBufferImpl, 64>;
629e5c31af7Sopenharmony_ci
630e5c31af7Sopenharmony_ci// A pool of bitstream buffers and a collection of command buffers for all frames in the decode sequence.
631e5c31af7Sopenharmony_ciclass NvVkDecodeFrameData
632e5c31af7Sopenharmony_ci{
633e5c31af7Sopenharmony_cipublic:
634e5c31af7Sopenharmony_ci	NvVkDecodeFrameData(const DeviceInterface& vkd, VkDevice device, deUint32 decodeQueueIdx)
635e5c31af7Sopenharmony_ci		: m_deviceInterface(vkd), m_device(device), m_decodeQueueIdx(decodeQueueIdx), m_videoCommandPool(VK_NULL_HANDLE), m_bitstreamBuffersQueue()
636e5c31af7Sopenharmony_ci	{
637e5c31af7Sopenharmony_ci	}
638e5c31af7Sopenharmony_ci
639e5c31af7Sopenharmony_ci	void deinit()
640e5c31af7Sopenharmony_ci	{
641e5c31af7Sopenharmony_ci		if (m_videoCommandPool != VK_NULL_HANDLE)
642e5c31af7Sopenharmony_ci		{
643e5c31af7Sopenharmony_ci			m_deviceInterface.freeCommandBuffers(m_device, m_videoCommandPool, (deUint32)m_commandBuffers.size(), &m_commandBuffers[0]);
644e5c31af7Sopenharmony_ci			m_deviceInterface.destroyCommandPool(m_device, m_videoCommandPool, NULL);
645e5c31af7Sopenharmony_ci			m_videoCommandPool = VK_NULL_HANDLE;
646e5c31af7Sopenharmony_ci		}
647e5c31af7Sopenharmony_ci	}
648e5c31af7Sopenharmony_ci
649e5c31af7Sopenharmony_ci	~NvVkDecodeFrameData()
650e5c31af7Sopenharmony_ci	{
651e5c31af7Sopenharmony_ci		deinit();
652e5c31af7Sopenharmony_ci	}
653e5c31af7Sopenharmony_ci
654e5c31af7Sopenharmony_ci	size_t resize(size_t maxDecodeFramesCount)
655e5c31af7Sopenharmony_ci	{
656e5c31af7Sopenharmony_ci		size_t allocatedCommandBuffers = 0;
657e5c31af7Sopenharmony_ci		if (m_videoCommandPool == VK_NULL_HANDLE)
658e5c31af7Sopenharmony_ci		{
659e5c31af7Sopenharmony_ci			VkCommandPoolCreateInfo cmdPoolInfo = {};
660e5c31af7Sopenharmony_ci			cmdPoolInfo.sType					= VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
661e5c31af7Sopenharmony_ci			cmdPoolInfo.flags					= VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
662e5c31af7Sopenharmony_ci			cmdPoolInfo.queueFamilyIndex		= m_decodeQueueIdx;
663e5c31af7Sopenharmony_ci			VK_CHECK(m_deviceInterface.createCommandPool(m_device, &cmdPoolInfo, nullptr, &m_videoCommandPool));
664e5c31af7Sopenharmony_ci
665e5c31af7Sopenharmony_ci			VkCommandBufferAllocateInfo cmdInfo = {};
666e5c31af7Sopenharmony_ci			cmdInfo.sType						= VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
667e5c31af7Sopenharmony_ci			cmdInfo.commandBufferCount			= (deUint32)maxDecodeFramesCount;
668e5c31af7Sopenharmony_ci			cmdInfo.level						= VK_COMMAND_BUFFER_LEVEL_PRIMARY;
669e5c31af7Sopenharmony_ci			cmdInfo.commandPool					= m_videoCommandPool;
670e5c31af7Sopenharmony_ci
671e5c31af7Sopenharmony_ci			m_commandBuffers.resize(maxDecodeFramesCount);
672e5c31af7Sopenharmony_ci			VK_CHECK(m_deviceInterface.allocateCommandBuffers(m_device, &cmdInfo, &m_commandBuffers[0]));
673e5c31af7Sopenharmony_ci			allocatedCommandBuffers = maxDecodeFramesCount;
674e5c31af7Sopenharmony_ci		}
675e5c31af7Sopenharmony_ci		else
676e5c31af7Sopenharmony_ci		{
677e5c31af7Sopenharmony_ci			allocatedCommandBuffers = m_commandBuffers.size();
678e5c31af7Sopenharmony_ci			DE_ASSERT(maxDecodeFramesCount <= allocatedCommandBuffers);
679e5c31af7Sopenharmony_ci		}
680e5c31af7Sopenharmony_ci
681e5c31af7Sopenharmony_ci		return allocatedCommandBuffers;
682e5c31af7Sopenharmony_ci	}
683e5c31af7Sopenharmony_ci
684e5c31af7Sopenharmony_ci	VkCommandBuffer GetCommandBuffer(deUint32 slot)
685e5c31af7Sopenharmony_ci	{
686e5c31af7Sopenharmony_ci		DE_ASSERT(slot < m_commandBuffers.size());
687e5c31af7Sopenharmony_ci		return m_commandBuffers[slot];
688e5c31af7Sopenharmony_ci	}
689e5c31af7Sopenharmony_ci
690e5c31af7Sopenharmony_ci	size_t size()
691e5c31af7Sopenharmony_ci	{
692e5c31af7Sopenharmony_ci		return m_commandBuffers.size();
693e5c31af7Sopenharmony_ci	}
694e5c31af7Sopenharmony_ci
695e5c31af7Sopenharmony_ci	VulkanBitstreamBufferPool& GetBitstreamBuffersQueue()
696e5c31af7Sopenharmony_ci	{
697e5c31af7Sopenharmony_ci		return m_bitstreamBuffersQueue;
698e5c31af7Sopenharmony_ci	}
699e5c31af7Sopenharmony_ci
700e5c31af7Sopenharmony_ciprivate:
701e5c31af7Sopenharmony_ci	const DeviceInterface&		 m_deviceInterface;
702e5c31af7Sopenharmony_ci	VkDevice					 m_device;
703e5c31af7Sopenharmony_ci	deUint32					 m_decodeQueueIdx;
704e5c31af7Sopenharmony_ci	VkCommandPool				 m_videoCommandPool;
705e5c31af7Sopenharmony_ci	std::vector<VkCommandBuffer> m_commandBuffers;
706e5c31af7Sopenharmony_ci	VulkanBitstreamBufferPool	 m_bitstreamBuffersQueue;
707e5c31af7Sopenharmony_ci};
708e5c31af7Sopenharmony_ci
709e5c31af7Sopenharmony_cistruct nvVideoH264PicParameters
710e5c31af7Sopenharmony_ci{
711e5c31af7Sopenharmony_ci	enum
712e5c31af7Sopenharmony_ci	{
713e5c31af7Sopenharmony_ci		MAX_REF_PICTURES_LIST_ENTRIES = 16
714e5c31af7Sopenharmony_ci	};
715e5c31af7Sopenharmony_ci
716e5c31af7Sopenharmony_ci	StdVideoDecodeH264PictureInfo				 stdPictureInfo;
717e5c31af7Sopenharmony_ci	VkVideoDecodeH264PictureInfoKHR				 pictureInfo;
718e5c31af7Sopenharmony_ci	VkVideoDecodeH264SessionParametersAddInfoKHR pictureParameters;
719e5c31af7Sopenharmony_ci	nvVideoDecodeH264DpbSlotInfo				 currentDpbSlotInfo;
720e5c31af7Sopenharmony_ci	nvVideoDecodeH264DpbSlotInfo				 dpbRefList[MAX_REF_PICTURES_LIST_ENTRIES];
721e5c31af7Sopenharmony_ci};
722e5c31af7Sopenharmony_ci
723e5c31af7Sopenharmony_cistruct nvVideoH265PicParameters
724e5c31af7Sopenharmony_ci{
725e5c31af7Sopenharmony_ci	enum
726e5c31af7Sopenharmony_ci	{
727e5c31af7Sopenharmony_ci		MAX_REF_PICTURES_LIST_ENTRIES = 16
728e5c31af7Sopenharmony_ci	};
729e5c31af7Sopenharmony_ci
730e5c31af7Sopenharmony_ci	StdVideoDecodeH265PictureInfo				 stdPictureInfo;
731e5c31af7Sopenharmony_ci	VkVideoDecodeH265PictureInfoKHR				 pictureInfo;
732e5c31af7Sopenharmony_ci	VkVideoDecodeH265SessionParametersAddInfoKHR pictureParameters;
733e5c31af7Sopenharmony_ci	nvVideoDecodeH265DpbSlotInfo				 dpbRefList[MAX_REF_PICTURES_LIST_ENTRIES];
734e5c31af7Sopenharmony_ci};
735e5c31af7Sopenharmony_ci
736e5c31af7Sopenharmony_cistruct NvVkDecodeFrameDataSlot
737e5c31af7Sopenharmony_ci{
738e5c31af7Sopenharmony_ci	deUint32		slot;
739e5c31af7Sopenharmony_ci	VkCommandBuffer commandBuffer;
740e5c31af7Sopenharmony_ci};
741e5c31af7Sopenharmony_ci
742e5c31af7Sopenharmony_ciclass VideoBaseDecoder final : public VkParserVideoDecodeClient
743e5c31af7Sopenharmony_ci{
744e5c31af7Sopenharmony_ci	enum
745e5c31af7Sopenharmony_ci	{
746e5c31af7Sopenharmony_ci		MAX_FRM_CNT = 32
747e5c31af7Sopenharmony_ci	};
748e5c31af7Sopenharmony_ci
749e5c31af7Sopenharmony_cipublic:
750e5c31af7Sopenharmony_ci	struct CachedDecodeParameters
751e5c31af7Sopenharmony_ci	{
752e5c31af7Sopenharmony_ci		VkParserPictureData								 pd;
753e5c31af7Sopenharmony_ci		VkParserDecodePictureInfo						 decodedPictureInfo;
754e5c31af7Sopenharmony_ci		VkParserPerFrameDecodeParameters				 pictureParams;
755e5c31af7Sopenharmony_ci		// NVIDIA API conflates picture parameters with picture parameter objects.
756e5c31af7Sopenharmony_ci		VkSharedBaseObj<VkParserVideoPictureParameters>  currentPictureParameterObject;
757e5c31af7Sopenharmony_ci		VkVideoReferenceSlotInfoKHR						 referenceSlots[VkParserPerFrameDecodeParameters::MAX_DPB_REF_AND_SETUP_SLOTS];
758e5c31af7Sopenharmony_ci		VkVideoReferenceSlotInfoKHR						 setupReferenceSlot;
759e5c31af7Sopenharmony_ci
760e5c31af7Sopenharmony_ci		VkVideoDecodeH264DpbSlotInfoKHR					 h264SlotInfo{};
761e5c31af7Sopenharmony_ci		StdVideoDecodeH264ReferenceInfo					 h264RefInfo{};
762e5c31af7Sopenharmony_ci		VkVideoDecodeH265DpbSlotInfoKHR					 h265SlotInfo{};
763e5c31af7Sopenharmony_ci		StdVideoDecodeH265ReferenceInfo					 h265RefInfo{};
764e5c31af7Sopenharmony_ci
765e5c31af7Sopenharmony_ci		nvVideoH264PicParameters						 h264PicParams;
766e5c31af7Sopenharmony_ci		nvVideoH265PicParameters						 h265PicParams;
767e5c31af7Sopenharmony_ci		NvVkDecodeFrameDataSlot							 frameDataSlot;
768e5c31af7Sopenharmony_ci		VkVideoBeginCodingInfoKHR						 decodeBeginInfo{};
769e5c31af7Sopenharmony_ci		VkBufferMemoryBarrier2KHR						 bitstreamBufferMemoryBarrier;
770e5c31af7Sopenharmony_ci		std::vector<VkImageMemoryBarrier2KHR>			 imageBarriers;
771e5c31af7Sopenharmony_ci		VulkanVideoFrameBuffer::PictureResourceInfo		 currentDpbPictureResourceInfo;
772e5c31af7Sopenharmony_ci		VulkanVideoFrameBuffer::PictureResourceInfo		 currentOutputPictureResourceInfo;
773e5c31af7Sopenharmony_ci		VkVideoPictureResourceInfoKHR					 currentOutputPictureResource;
774e5c31af7Sopenharmony_ci		VkVideoPictureResourceInfoKHR*					 pOutputPictureResource{};
775e5c31af7Sopenharmony_ci		VulkanVideoFrameBuffer::PictureResourceInfo*	 pOutputPictureResourceInfo{};
776e5c31af7Sopenharmony_ci		VulkanVideoFrameBuffer::PictureResourceInfo		 pictureResourcesInfo[VkParserPerFrameDecodeParameters::MAX_DPB_REF_AND_SETUP_SLOTS];
777e5c31af7Sopenharmony_ci
778e5c31af7Sopenharmony_ci		std::vector<VkVideoReferenceSlotInfoKHR>		 fullReferenceSlots;
779e5c31af7Sopenharmony_ci		int32_t											 picNumInDecodeOrder;
780e5c31af7Sopenharmony_ci		VulkanVideoFrameBuffer::FrameSynchronizationInfo frameSynchronizationInfo;
781e5c31af7Sopenharmony_ci
782e5c31af7Sopenharmony_ci		// When set, command buffer recording for this cached frame will reset the codec.
783e5c31af7Sopenharmony_ci		bool											 performCodecReset{false};
784e5c31af7Sopenharmony_ci
785e5c31af7Sopenharmony_ci		~CachedDecodeParameters()
786e5c31af7Sopenharmony_ci		{
787e5c31af7Sopenharmony_ci			if (pd.sideDataLen > 0)
788e5c31af7Sopenharmony_ci			{
789e5c31af7Sopenharmony_ci				DE_ASSERT(pd.pSideData);
790e5c31af7Sopenharmony_ci				delete[] pd.pSideData;
791e5c31af7Sopenharmony_ci			}
792e5c31af7Sopenharmony_ci		}
793e5c31af7Sopenharmony_ci	};
794e5c31af7Sopenharmony_ci
795e5c31af7Sopenharmony_ci	struct Parameters
796e5c31af7Sopenharmony_ci	{
797e5c31af7Sopenharmony_ci		DeviceContext*							context{};
798e5c31af7Sopenharmony_ci		const VkVideoCoreProfile*				profile{};
799e5c31af7Sopenharmony_ci		size_t									framesToCheck{};
800e5c31af7Sopenharmony_ci		bool									queryDecodeStatus{};
801e5c31af7Sopenharmony_ci		bool									outOfOrderDecoding{};
802e5c31af7Sopenharmony_ci		bool									alwaysRecreateDPB{};
803e5c31af7Sopenharmony_ci		size_t									pictureParameterUpdateTriggerHack{0};
804e5c31af7Sopenharmony_ci		VkSharedBaseObj<VulkanVideoFrameBuffer> framebuffer;
805e5c31af7Sopenharmony_ci	};
806e5c31af7Sopenharmony_ci	explicit VideoBaseDecoder(Parameters&& params);
807e5c31af7Sopenharmony_ci	~VideoBaseDecoder() override
808e5c31af7Sopenharmony_ci	{
809e5c31af7Sopenharmony_ci		Deinitialize();
810e5c31af7Sopenharmony_ci	}
811e5c31af7Sopenharmony_ci
812e5c31af7Sopenharmony_ci	int32_t					ReleaseDisplayedFrame(DecodedFrame* pDisplayedFrame);
813e5c31af7Sopenharmony_ci	VulkanVideoFrameBuffer* GetVideoFrameBuffer()
814e5c31af7Sopenharmony_ci	{
815e5c31af7Sopenharmony_ci		return m_videoFrameBuffer.Get();
816e5c31af7Sopenharmony_ci	}
817e5c31af7Sopenharmony_ci	const VkVideoCapabilitiesKHR* getVideoCaps() const
818e5c31af7Sopenharmony_ci	{
819e5c31af7Sopenharmony_ci		return &m_videoCaps;
820e5c31af7Sopenharmony_ci	}
821e5c31af7Sopenharmony_ci
822e5c31af7Sopenharmony_ci	// VkParserVideoDecodeClient callbacks
823e5c31af7Sopenharmony_ci	// Returns max number of reference frames (always at least 2 for MPEG-2)
824e5c31af7Sopenharmony_ci	int32_t			BeginSequence(const VkParserSequenceInfo* pnvsi) override;
825e5c31af7Sopenharmony_ci	// Returns a new INvidiaVulkanPicture interface
826e5c31af7Sopenharmony_ci	bool			AllocPictureBuffer(VkPicIf** ppNvidiaVulkanPicture) override;
827e5c31af7Sopenharmony_ci	// Called when a picture is ready to be decoded
828e5c31af7Sopenharmony_ci	bool			DecodePicture(VkParserPictureData* pNvidiaVulkanParserPictureData) override;
829e5c31af7Sopenharmony_ci	// Called when the stream parameters have changed
830e5c31af7Sopenharmony_ci	bool			UpdatePictureParameters(VkSharedBaseObj<StdVideoPictureParametersSet>& pictureParametersObject, /* in */
831e5c31af7Sopenharmony_ci											VkSharedBaseObj<VkVideoRefCountBase>&		   client /* out */) override;
832e5c31af7Sopenharmony_ci	// Called when a picture is ready to be displayed
833e5c31af7Sopenharmony_ci	bool			DisplayPicture(VkPicIf* pNvidiaVulkanPicture, int64_t llPTS) override;
834e5c31af7Sopenharmony_ci	// Called for custom NAL parsing (not required)
835e5c31af7Sopenharmony_ci	void			UnhandledNALU(const deUint8* pbData, size_t cbData) override;
836e5c31af7Sopenharmony_ci
837e5c31af7Sopenharmony_ci	virtual int32_t StartVideoSequence(const VkParserDetectedVideoFormat* pVideoFormat);
838e5c31af7Sopenharmony_ci	virtual int32_t DecodePictureWithParameters(de::MovePtr<CachedDecodeParameters>& params);
839e5c31af7Sopenharmony_ci	VkDeviceSize	GetBitstreamBuffer(VkDeviceSize							   size,
840e5c31af7Sopenharmony_ci									   VkDeviceSize							   minBitstreamBufferOffsetAlignment,
841e5c31af7Sopenharmony_ci									   VkDeviceSize							   minBitstreamBufferSizeAlignment,
842e5c31af7Sopenharmony_ci									   const deUint8*						   pInitializeBufferMemory,
843e5c31af7Sopenharmony_ci									   VkDeviceSize							   initializeBufferMemorySize,
844e5c31af7Sopenharmony_ci									   VkSharedBaseObj<VulkanBitstreamBuffer>& bitstreamBuffer) override;
845e5c31af7Sopenharmony_ci
846e5c31af7Sopenharmony_ci
847e5c31af7Sopenharmony_ci	// Parser methods
848e5c31af7Sopenharmony_ci	bool			DecodePicture(VkParserPictureData* pParserPictureData, vkPicBuffBase* pVkPicBuff, VkParserDecodePictureInfo*);
849e5c31af7Sopenharmony_ci	deUint32		FillDpbH264State(const VkParserPictureData*			pd,
850e5c31af7Sopenharmony_ci									 const VkParserH264DpbEntry*		dpbIn,
851e5c31af7Sopenharmony_ci									 deUint32							maxDpbInSlotsInUse,
852e5c31af7Sopenharmony_ci									 nvVideoDecodeH264DpbSlotInfo*		pDpbRefList,
853e5c31af7Sopenharmony_ci									 deUint32							maxRefPictures,
854e5c31af7Sopenharmony_ci									 VkVideoReferenceSlotInfoKHR*		pReferenceSlots,
855e5c31af7Sopenharmony_ci									 int8_t*							pGopReferenceImagesIndexes,
856e5c31af7Sopenharmony_ci									 StdVideoDecodeH264PictureInfoFlags currPicFlags,
857e5c31af7Sopenharmony_ci									 int32_t*							pCurrAllocatedSlotIndex);
858e5c31af7Sopenharmony_ci	deUint32		FillDpbH265State(const VkParserPictureData*		pd,
859e5c31af7Sopenharmony_ci									 const VkParserHevcPictureData* pin,
860e5c31af7Sopenharmony_ci									 nvVideoDecodeH265DpbSlotInfo*	pDpbSlotInfo,
861e5c31af7Sopenharmony_ci									 StdVideoDecodeH265PictureInfo* pStdPictureInfo,
862e5c31af7Sopenharmony_ci									 deUint32						maxRefPictures,
863e5c31af7Sopenharmony_ci									 VkVideoReferenceSlotInfoKHR*	pReferenceSlots,
864e5c31af7Sopenharmony_ci									 int8_t*						pGopReferenceImagesIndexes,
865e5c31af7Sopenharmony_ci									 int32_t*						pCurrAllocatedSlotIndex);
866e5c31af7Sopenharmony_ci
867e5c31af7Sopenharmony_ci	int8_t			AllocateDpbSlotForCurrentH264(vkPicBuffBase*					 pPic,
868e5c31af7Sopenharmony_ci												  StdVideoDecodeH264PictureInfoFlags currPicFlags,
869e5c31af7Sopenharmony_ci												  int8_t							 presetDpbSlot);
870e5c31af7Sopenharmony_ci	int8_t			AllocateDpbSlotForCurrentH265(vkPicBuffBase* pPic, bool isReference, int8_t presetDpbSlot);
871e5c31af7Sopenharmony_ci	int8_t			GetPicIdx(vkPicBuffBase* pNvidiaVulkanPictureBase);
872e5c31af7Sopenharmony_ci	int8_t			GetPicIdx(VkPicIf* pNvidiaVulkanPicture);
873e5c31af7Sopenharmony_ci	int8_t			GetPicDpbSlot(int8_t picIndex);
874e5c31af7Sopenharmony_ci	int8_t			SetPicDpbSlot(int8_t picIndex, int8_t dpbSlot);
875e5c31af7Sopenharmony_ci	deUint32		ResetPicDpbSlots(deUint32 picIndexSlotValidMask);
876e5c31af7Sopenharmony_ci	bool			GetFieldPicFlag(int8_t picIndex);
877e5c31af7Sopenharmony_ci	bool			SetFieldPicFlag(int8_t picIndex, bool fieldPicFlag);
878e5c31af7Sopenharmony_ci
879e5c31af7Sopenharmony_ci	void			Deinitialize();
880e5c31af7Sopenharmony_ci	int32_t			GetCurrentFrameData(deUint32 slotId, NvVkDecodeFrameDataSlot& frameDataSlot)
881e5c31af7Sopenharmony_ci	{
882e5c31af7Sopenharmony_ci		if (slotId < m_decodeFramesData.size())
883e5c31af7Sopenharmony_ci		{
884e5c31af7Sopenharmony_ci			frameDataSlot.commandBuffer = m_decodeFramesData.GetCommandBuffer(slotId);
885e5c31af7Sopenharmony_ci			frameDataSlot.slot			= slotId;
886e5c31af7Sopenharmony_ci			return slotId;
887e5c31af7Sopenharmony_ci		}
888e5c31af7Sopenharmony_ci		return -1;
889e5c31af7Sopenharmony_ci	}
890e5c31af7Sopenharmony_ci
891e5c31af7Sopenharmony_ci	void			ApplyPictureParameters(de::MovePtr<CachedDecodeParameters>& cachedParameters);
892e5c31af7Sopenharmony_ci	void			WaitForFrameFences(de::MovePtr<CachedDecodeParameters>& cachedParameters);
893e5c31af7Sopenharmony_ci	void			RecordCommandBuffer(de::MovePtr<CachedDecodeParameters>& cachedParameters);
894e5c31af7Sopenharmony_ci	void			SubmitQueue(de::MovePtr<CachedDecodeParameters>& cachedParameters);
895e5c31af7Sopenharmony_ci	void			QueryDecodeResults(de::MovePtr<CachedDecodeParameters>& cachedParameters);
896e5c31af7Sopenharmony_ci	void			decodeFramesOutOfOrder();
897e5c31af7Sopenharmony_ci
898e5c31af7Sopenharmony_ci	DeviceContext*					m_deviceContext{};
899e5c31af7Sopenharmony_ci	VkVideoCoreProfile				m_profile{};
900e5c31af7Sopenharmony_ci	deUint32						m_framesToCheck{};
901e5c31af7Sopenharmony_ci	// Parser fields
902e5c31af7Sopenharmony_ci	int32_t							m_nCurrentPictureID{};
903e5c31af7Sopenharmony_ci	deUint32						m_dpbSlotsMask{};
904e5c31af7Sopenharmony_ci	deUint32						m_fieldPicFlagMask{};
905e5c31af7Sopenharmony_ci	DpbSlots						m_dpb;
906e5c31af7Sopenharmony_ci	std::array<int8_t, MAX_FRM_CNT> m_pictureToDpbSlotMap;
907e5c31af7Sopenharmony_ci	VkFormat						m_dpbImageFormat{VK_FORMAT_UNDEFINED};
908e5c31af7Sopenharmony_ci	VkFormat						m_outImageFormat{VK_FORMAT_UNDEFINED};
909e5c31af7Sopenharmony_ci	deUint32						m_maxNumDecodeSurfaces{1};
910e5c31af7Sopenharmony_ci	deUint32						m_maxNumDpbSlots{1};
911e5c31af7Sopenharmony_ci	vector<AllocationPtr>			m_videoDecodeSessionAllocs;
912e5c31af7Sopenharmony_ci	deUint32						m_numDecodeSurfaces{};
913e5c31af7Sopenharmony_ci	Move<VkCommandPool>				m_videoCommandPool{};
914e5c31af7Sopenharmony_ci	VkVideoCapabilitiesKHR			m_videoCaps{};
915e5c31af7Sopenharmony_ci	VkVideoDecodeCapabilitiesKHR	m_decodeCaps{};
916e5c31af7Sopenharmony_ci	VkVideoCodecOperationFlagsKHR	m_supportedVideoCodecs{};
917e5c31af7Sopenharmony_ci	inline bool						dpbAndOutputCoincide() const
918e5c31af7Sopenharmony_ci	{
919e5c31af7Sopenharmony_ci		return m_decodeCaps.flags & VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR;
920e5c31af7Sopenharmony_ci	}
921e5c31af7Sopenharmony_ci
922e5c31af7Sopenharmony_ci	VkSharedBaseObj<VulkanVideoSession>							m_videoSession{};
923e5c31af7Sopenharmony_ci	VkSharedBaseObj<VulkanVideoFrameBuffer>						m_videoFrameBuffer{};
924e5c31af7Sopenharmony_ci	NvVkDecodeFrameData											m_decodeFramesData;
925e5c31af7Sopenharmony_ci
926e5c31af7Sopenharmony_ci	// This is only used by the frame buffer, to set picture number in decode order.
927e5c31af7Sopenharmony_ci	// The framebuffer should manage this state ideally.
928e5c31af7Sopenharmony_ci	int32_t														m_decodePicCount{};
929e5c31af7Sopenharmony_ci
930e5c31af7Sopenharmony_ci	VkParserDetectedVideoFormat									m_videoFormat{};
931e5c31af7Sopenharmony_ci
932e5c31af7Sopenharmony_ci	VkSharedBaseObj<VkParserVideoPictureParameters>				m_currentPictureParameters{};
933e5c31af7Sopenharmony_ci	int															m_pictureParameterUpdateCount{0};
934e5c31af7Sopenharmony_ci	// Due to the design of the NVIDIA decoder client library, there is not a clean way to reset parameter objects
935e5c31af7Sopenharmony_ci	// in between GOPs. This becomes a problem when the session object needs to change, and then the parameter
936e5c31af7Sopenharmony_ci	// objects get stored in the wrong session. This field contains a nonnegative integer, such that when it
937e5c31af7Sopenharmony_ci	// becomes equal to m_pictureParameterUpdateCount, it will forcibly reset the current picture parameters.
938e5c31af7Sopenharmony_ci	// This could be more general by taking a modulo formula, or a list of trigger numbers. But it is currently
939e5c31af7Sopenharmony_ci	// only required for the h264_resolution_change_dpb test plan, so no need for complication.
940e5c31af7Sopenharmony_ci	int															m_resetPictureParametersFrameTriggerHack{};
941e5c31af7Sopenharmony_ci	void triggerPictureParameterSequenceCount()
942e5c31af7Sopenharmony_ci	{
943e5c31af7Sopenharmony_ci		++m_pictureParameterUpdateCount;
944e5c31af7Sopenharmony_ci		if (m_resetPictureParametersFrameTriggerHack > 0 && m_pictureParameterUpdateCount == m_resetPictureParametersFrameTriggerHack)
945e5c31af7Sopenharmony_ci		{
946e5c31af7Sopenharmony_ci			m_currentPictureParameters = nullptr;
947e5c31af7Sopenharmony_ci		}
948e5c31af7Sopenharmony_ci	}
949e5c31af7Sopenharmony_ci
950e5c31af7Sopenharmony_ci	bool														m_queryResultWithStatus{false};
951e5c31af7Sopenharmony_ci	bool														m_outOfOrderDecoding{false};
952e5c31af7Sopenharmony_ci	bool														m_alwaysRecreateDPB{false};
953e5c31af7Sopenharmony_ci	vector<VkParserPerFrameDecodeParameters*>					m_pPerFrameDecodeParameters;
954e5c31af7Sopenharmony_ci	vector<VkParserDecodePictureInfo*>							m_pVulkanParserDecodePictureInfo;
955e5c31af7Sopenharmony_ci	vector<NvVkDecodeFrameData*>								m_pFrameDatas;
956e5c31af7Sopenharmony_ci	vector<VkBufferMemoryBarrier2KHR>							m_bitstreamBufferMemoryBarriers;
957e5c31af7Sopenharmony_ci	vector<vector<VkImageMemoryBarrier2KHR>>					m_imageBarriersVec;
958e5c31af7Sopenharmony_ci	vector<VulkanVideoFrameBuffer::FrameSynchronizationInfo>	m_frameSynchronizationInfos;
959e5c31af7Sopenharmony_ci	vector<VkCommandBufferSubmitInfoKHR>						m_commandBufferSubmitInfos;
960e5c31af7Sopenharmony_ci	vector<VkVideoBeginCodingInfoKHR>							m_decodeBeginInfos;
961e5c31af7Sopenharmony_ci	vector<vector<VulkanVideoFrameBuffer::PictureResourceInfo>> m_pictureResourcesInfos;
962e5c31af7Sopenharmony_ci	vector<VkDependencyInfoKHR>									m_dependencyInfos;
963e5c31af7Sopenharmony_ci	vector<VkVideoEndCodingInfoKHR>								m_decodeEndInfos;
964e5c31af7Sopenharmony_ci	vector<VkSubmitInfo2KHR>									m_submitInfos;
965e5c31af7Sopenharmony_ci	vector<VkFence>												m_frameCompleteFences;
966e5c31af7Sopenharmony_ci	vector<VkFence>												m_frameConsumerDoneFences;
967e5c31af7Sopenharmony_ci	vector<VkSemaphoreSubmitInfoKHR>							m_frameCompleteSemaphoreSubmitInfos;
968e5c31af7Sopenharmony_ci	vector<VkSemaphoreSubmitInfoKHR>							m_frameConsumerDoneSemaphoreSubmitInfos;
969e5c31af7Sopenharmony_ci
970e5c31af7Sopenharmony_ci	std::vector<de::MovePtr<CachedDecodeParameters>>			m_cachedDecodeParams;
971e5c31af7Sopenharmony_ci
972e5c31af7Sopenharmony_ci	VkParserSequenceInfo										m_nvsi{};
973e5c31af7Sopenharmony_ci	deUint32													m_maxStreamBufferSize{};
974e5c31af7Sopenharmony_ci	deUint32													m_numBitstreamBuffersToPreallocate{8}; // TODO: Review
975e5c31af7Sopenharmony_ci	bool														m_useImageArray{false};
976e5c31af7Sopenharmony_ci	bool														m_useImageViewArray{false};
977e5c31af7Sopenharmony_ci	bool														m_useSeparateOutputImages{false};
978e5c31af7Sopenharmony_ci	bool														m_resetDecoder{false};
979e5c31af7Sopenharmony_ci};
980e5c31af7Sopenharmony_ci
981e5c31af7Sopenharmony_ci} // namespace video
982e5c31af7Sopenharmony_ci} // namespace vkt
983e5c31af7Sopenharmony_ci
984e5c31af7Sopenharmony_ci#endif // _VKTVIDEOBASEDECODEUTILS_HPP
985