1e5c31af7Sopenharmony_ci#ifndef _VKTVIDEOFRAMEBUFFER_HPP
2e5c31af7Sopenharmony_ci#define _VKTVIDEOFRAMEBUFFER_HPP
3e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------
4e5c31af7Sopenharmony_ci* Vulkan Conformance Tests
5e5c31af7Sopenharmony_ci* ------------------------
6e5c31af7Sopenharmony_ci*
7e5c31af7Sopenharmony_ci* Copyright (c) 2023 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* \file
23e5c31af7Sopenharmony_ci* \brief Video framebuffer
24e5c31af7Sopenharmony_ci*//*--------------------------------------------------------------------*/
25e5c31af7Sopenharmony_ci/*
26e5c31af7Sopenharmony_ci* Copyright 2020 NVIDIA Corporation.
27e5c31af7Sopenharmony_ci*
28e5c31af7Sopenharmony_ci* Licensed under the Apache License, Version 2.0 (the "License");
29e5c31af7Sopenharmony_ci* you may not use this file except in compliance with the License.
30e5c31af7Sopenharmony_ci* You may obtain a copy of the License at
31e5c31af7Sopenharmony_ci*
32e5c31af7Sopenharmony_ci*    http://www.apache.org/licenses/LICENSE-2.0
33e5c31af7Sopenharmony_ci*
34e5c31af7Sopenharmony_ci* Unless required by applicable law or agreed to in writing, software
35e5c31af7Sopenharmony_ci* distributed under the License is distributed on an "AS IS" BASIS,
36e5c31af7Sopenharmony_ci* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
37e5c31af7Sopenharmony_ci* See the License for the specific language governing permissions and
38e5c31af7Sopenharmony_ci* limitations under the License.
39e5c31af7Sopenharmony_ci*/
40e5c31af7Sopenharmony_ci#include "deDefs.hpp"
41e5c31af7Sopenharmony_ci#include "vktVideoTestUtils.hpp"
42e5c31af7Sopenharmony_ci#include "extNvidiaVideoParserIf.hpp"
43e5c31af7Sopenharmony_ci
44e5c31af7Sopenharmony_cinamespace vkt
45e5c31af7Sopenharmony_ci{
46e5c31af7Sopenharmony_cinamespace video
47e5c31af7Sopenharmony_ci{
48e5c31af7Sopenharmony_ci
49e5c31af7Sopenharmony_ciusing ImagePtr =de::MovePtr<ImageWithMemory>;
50e5c31af7Sopenharmony_ci
51e5c31af7Sopenharmony_ciclass VkImageResource : public VkVideoRefCountBase
52e5c31af7Sopenharmony_ci{
53e5c31af7Sopenharmony_cipublic:
54e5c31af7Sopenharmony_ci	static VkResult Create(DeviceContext&					 vkDevCtx,
55e5c31af7Sopenharmony_ci						   const VkImageCreateInfo*			 pImageCreateInfo,
56e5c31af7Sopenharmony_ci						   VkSharedBaseObj<VkImageResource>& imageResource);
57e5c31af7Sopenharmony_ci
58e5c31af7Sopenharmony_ci	int32_t AddRef() override
59e5c31af7Sopenharmony_ci	{
60e5c31af7Sopenharmony_ci		return ++m_refCount;
61e5c31af7Sopenharmony_ci	}
62e5c31af7Sopenharmony_ci
63e5c31af7Sopenharmony_ci	int32_t Release() override
64e5c31af7Sopenharmony_ci	{
65e5c31af7Sopenharmony_ci		deUint32 ret = --m_refCount;
66e5c31af7Sopenharmony_ci		// Destroy the device if ref-count reaches zero
67e5c31af7Sopenharmony_ci		if (ret == 0)
68e5c31af7Sopenharmony_ci		{
69e5c31af7Sopenharmony_ci			delete this;
70e5c31af7Sopenharmony_ci		}
71e5c31af7Sopenharmony_ci		return ret;
72e5c31af7Sopenharmony_ci	}
73e5c31af7Sopenharmony_ci
74e5c31af7Sopenharmony_ci	VkImage GetImage() const
75e5c31af7Sopenharmony_ci	{
76e5c31af7Sopenharmony_ci		return m_imageWithMemory->get();
77e5c31af7Sopenharmony_ci	}
78e5c31af7Sopenharmony_ci
79e5c31af7Sopenharmony_ci	const VkImageCreateInfo& GetImageCreateInfo() const
80e5c31af7Sopenharmony_ci	{
81e5c31af7Sopenharmony_ci		return m_imageCreateInfo;
82e5c31af7Sopenharmony_ci	}
83e5c31af7Sopenharmony_ci
84e5c31af7Sopenharmony_ciprivate:
85e5c31af7Sopenharmony_ci	std::atomic<int32_t>	m_refCount;
86e5c31af7Sopenharmony_ci	const VkImageCreateInfo m_imageCreateInfo;
87e5c31af7Sopenharmony_ci	ImagePtr				m_imageWithMemory;
88e5c31af7Sopenharmony_ci
89e5c31af7Sopenharmony_ci	VkImageResource(DeviceContext&							 vkDevCtx,
90e5c31af7Sopenharmony_ci					const VkImageCreateInfo*				 pImageCreateInfo)
91e5c31af7Sopenharmony_ci		: m_refCount(0), m_imageCreateInfo(*pImageCreateInfo)
92e5c31af7Sopenharmony_ci	{
93e5c31af7Sopenharmony_ci		m_imageWithMemory = ImagePtr(new ImageWithMemory(vkDevCtx.getDeviceDriver(), vkDevCtx.device, vkDevCtx.allocator(), *pImageCreateInfo, MemoryRequirement::Local));
94e5c31af7Sopenharmony_ci	}
95e5c31af7Sopenharmony_ci};
96e5c31af7Sopenharmony_ci
97e5c31af7Sopenharmony_ciclass VkImageResourceView : public VkVideoRefCountBase
98e5c31af7Sopenharmony_ci{
99e5c31af7Sopenharmony_cipublic:
100e5c31af7Sopenharmony_ci	static VkResult Create(DeviceContext&						 vkDevCtx,
101e5c31af7Sopenharmony_ci						   VkSharedBaseObj<VkImageResource>&	 imageResource,
102e5c31af7Sopenharmony_ci						   VkImageSubresourceRange&				 imageSubresourceRange,
103e5c31af7Sopenharmony_ci						   VkSharedBaseObj<VkImageResourceView>& imageResourceView);
104e5c31af7Sopenharmony_ci
105e5c31af7Sopenharmony_ci	virtual int32_t AddRef()
106e5c31af7Sopenharmony_ci	{
107e5c31af7Sopenharmony_ci		return ++m_refCount;
108e5c31af7Sopenharmony_ci	}
109e5c31af7Sopenharmony_ci
110e5c31af7Sopenharmony_ci	virtual int32_t Release()
111e5c31af7Sopenharmony_ci	{
112e5c31af7Sopenharmony_ci		deUint32 ret = --m_refCount;
113e5c31af7Sopenharmony_ci		// Destroy the device if ref-count reaches zero
114e5c31af7Sopenharmony_ci		if (ret == 0)
115e5c31af7Sopenharmony_ci		{
116e5c31af7Sopenharmony_ci			delete this;
117e5c31af7Sopenharmony_ci		}
118e5c31af7Sopenharmony_ci		return ret;
119e5c31af7Sopenharmony_ci	}
120e5c31af7Sopenharmony_ci
121e5c31af7Sopenharmony_ci	operator VkImageView() const
122e5c31af7Sopenharmony_ci	{
123e5c31af7Sopenharmony_ci		return m_imageView;
124e5c31af7Sopenharmony_ci	}
125e5c31af7Sopenharmony_ci	VkImageView GetImageView() const
126e5c31af7Sopenharmony_ci	{
127e5c31af7Sopenharmony_ci		return m_imageView;
128e5c31af7Sopenharmony_ci	}
129e5c31af7Sopenharmony_ci
130e5c31af7Sopenharmony_ci	const VkSharedBaseObj<VkImageResource>& GetImageResource()
131e5c31af7Sopenharmony_ci	{
132e5c31af7Sopenharmony_ci		return m_imageResource;
133e5c31af7Sopenharmony_ci	}
134e5c31af7Sopenharmony_ci
135e5c31af7Sopenharmony_ciprivate:
136e5c31af7Sopenharmony_ci	std::atomic<int32_t>			 m_refCount;
137e5c31af7Sopenharmony_ci	DeviceContext&					 m_vkDevCtx;
138e5c31af7Sopenharmony_ci	VkSharedBaseObj<VkImageResource> m_imageResource;
139e5c31af7Sopenharmony_ci	VkImageView						 m_imageView;
140e5c31af7Sopenharmony_ci
141e5c31af7Sopenharmony_ci	VkImageResourceView(DeviceContext&					  vkDevCtx,
142e5c31af7Sopenharmony_ci						VkSharedBaseObj<VkImageResource>& imageResource,
143e5c31af7Sopenharmony_ci						VkImageView						  imageView,
144e5c31af7Sopenharmony_ci						VkImageSubresourceRange&		  /*imageSubresourceRange*/)
145e5c31af7Sopenharmony_ci		: m_refCount(0), m_vkDevCtx(vkDevCtx), m_imageResource(imageResource), m_imageView(imageView)
146e5c31af7Sopenharmony_ci	{
147e5c31af7Sopenharmony_ci	}
148e5c31af7Sopenharmony_ci
149e5c31af7Sopenharmony_ci	virtual ~VkImageResourceView();
150e5c31af7Sopenharmony_ci};
151e5c31af7Sopenharmony_ci
152e5c31af7Sopenharmony_cistruct DecodedFrame
153e5c31af7Sopenharmony_ci{
154e5c31af7Sopenharmony_ci	int32_t								 pictureIndex;
155e5c31af7Sopenharmony_ci	uint32_t							 imageLayerIndex; // The layer of a multi-layered images. Always "0" for single layered images
156e5c31af7Sopenharmony_ci	int32_t								 displayWidth;
157e5c31af7Sopenharmony_ci	int32_t								 displayHeight;
158e5c31af7Sopenharmony_ci	VkSharedBaseObj<VkImageResourceView> decodedImageView;
159e5c31af7Sopenharmony_ci	VkSharedBaseObj<VkImageResourceView> outputImageView;
160e5c31af7Sopenharmony_ci	VkFence								 frameCompleteFence; // If valid, the fence is signaled when the decoder is done decoding the frame.
161e5c31af7Sopenharmony_ci	VkFence								 frameConsumerDoneFence; // If valid, the fence is signaled when the consumer (graphics, compute or display) is done using the frame.
162e5c31af7Sopenharmony_ci	VkSemaphore							 frameCompleteSemaphore; // If valid, the semaphore is signaled when the decoder is done decoding the frame.
163e5c31af7Sopenharmony_ci	VkSemaphore							 frameConsumerDoneSemaphore; // If valid, the semaphore is signaled when the consumer (graphics, compute or display) is done using the frame.
164e5c31af7Sopenharmony_ci	VkQueryPool							 queryPool; // queryPool handle used for the video queries.
165e5c31af7Sopenharmony_ci	int32_t								 startQueryId; // query Id used for the this frame.
166e5c31af7Sopenharmony_ci	deUint32							 numQueries; // usually one query per frame
167e5c31af7Sopenharmony_ci	// If multiple queues are available, submittedVideoQueueIndex is the queue index that the video frame was submitted to.
168e5c31af7Sopenharmony_ci	// if only one queue is available, submittedVideoQueueIndex will always have a value of "0".
169e5c31af7Sopenharmony_ci	int32_t								 submittedVideoQueueIndex;
170e5c31af7Sopenharmony_ci	uint64_t							 timestamp;
171e5c31af7Sopenharmony_ci	deUint32							 hasConsummerSignalFence : 1;
172e5c31af7Sopenharmony_ci	deUint32							 hasConsummerSignalSemaphore : 1;
173e5c31af7Sopenharmony_ci	// For debugging
174e5c31af7Sopenharmony_ci	int32_t								 decodeOrder;
175e5c31af7Sopenharmony_ci	int32_t								 displayOrder;
176e5c31af7Sopenharmony_ci
177e5c31af7Sopenharmony_ci	void								 Reset()
178e5c31af7Sopenharmony_ci	{
179e5c31af7Sopenharmony_ci		pictureIndex				= -1;
180e5c31af7Sopenharmony_ci		imageLayerIndex				= 0;
181e5c31af7Sopenharmony_ci		displayWidth				= 0;
182e5c31af7Sopenharmony_ci		displayHeight				= 0;
183e5c31af7Sopenharmony_ci		decodedImageView			= nullptr;
184e5c31af7Sopenharmony_ci		outputImageView				= nullptr;
185e5c31af7Sopenharmony_ci		frameCompleteFence			= VK_NULL_HANDLE;
186e5c31af7Sopenharmony_ci		frameConsumerDoneFence		= VK_NULL_HANDLE;
187e5c31af7Sopenharmony_ci		frameCompleteSemaphore		= VK_NULL_HANDLE;
188e5c31af7Sopenharmony_ci		frameConsumerDoneSemaphore	= VK_NULL_HANDLE;
189e5c31af7Sopenharmony_ci		queryPool					= VK_NULL_HANDLE;
190e5c31af7Sopenharmony_ci		startQueryId				= 0;
191e5c31af7Sopenharmony_ci		numQueries					= 0;
192e5c31af7Sopenharmony_ci		submittedVideoQueueIndex	= 0;
193e5c31af7Sopenharmony_ci		timestamp					= 0;
194e5c31af7Sopenharmony_ci		hasConsummerSignalFence		= false;
195e5c31af7Sopenharmony_ci		hasConsummerSignalSemaphore = false;
196e5c31af7Sopenharmony_ci		// For debugging
197e5c31af7Sopenharmony_ci		decodeOrder					= 0;
198e5c31af7Sopenharmony_ci		displayOrder				= 0;
199e5c31af7Sopenharmony_ci	}
200e5c31af7Sopenharmony_ci};
201e5c31af7Sopenharmony_ci
202e5c31af7Sopenharmony_cistruct DecodedFrameRelease
203e5c31af7Sopenharmony_ci{
204e5c31af7Sopenharmony_ci	int32_t			 pictureIndex;
205e5c31af7Sopenharmony_ci	VkVideotimestamp timestamp;
206e5c31af7Sopenharmony_ci	deUint32		 hasConsummerSignalFence : 1;
207e5c31af7Sopenharmony_ci	deUint32		 hasConsummerSignalSemaphore : 1;
208e5c31af7Sopenharmony_ci	// For debugging
209e5c31af7Sopenharmony_ci	int32_t			 decodeOrder;
210e5c31af7Sopenharmony_ci	int32_t			 displayOrder;
211e5c31af7Sopenharmony_ci};
212e5c31af7Sopenharmony_ci
213e5c31af7Sopenharmony_ciclass VulkanVideoFrameBuffer : public IVulkanVideoFrameBufferParserCb
214e5c31af7Sopenharmony_ci{
215e5c31af7Sopenharmony_cipublic:
216e5c31af7Sopenharmony_ci	// Synchronization
217e5c31af7Sopenharmony_ci	struct FrameSynchronizationInfo
218e5c31af7Sopenharmony_ci	{
219e5c31af7Sopenharmony_ci		VkFence		frameCompleteFence{VK_NULL_HANDLE};
220e5c31af7Sopenharmony_ci		VkSemaphore frameCompleteSemaphore{VK_NULL_HANDLE};
221e5c31af7Sopenharmony_ci		VkFence		frameConsumerDoneFence{VK_NULL_HANDLE};
222e5c31af7Sopenharmony_ci		VkSemaphore frameConsumerDoneSemaphore{VK_NULL_HANDLE};
223e5c31af7Sopenharmony_ci		VkQueryPool queryPool{VK_NULL_HANDLE};
224e5c31af7Sopenharmony_ci		int32_t		startQueryId;
225e5c31af7Sopenharmony_ci		deUint32	numQueries;
226e5c31af7Sopenharmony_ci		deUint32	hasFrameCompleteSignalFence : 1;
227e5c31af7Sopenharmony_ci		deUint32	hasFrameCompleteSignalSemaphore : 1;
228e5c31af7Sopenharmony_ci	};
229e5c31af7Sopenharmony_ci
230e5c31af7Sopenharmony_ci	struct ReferencedObjectsInfo
231e5c31af7Sopenharmony_ci	{
232e5c31af7Sopenharmony_ci
233e5c31af7Sopenharmony_ci		// The bitstream Buffer
234e5c31af7Sopenharmony_ci		const VkVideoRefCountBase* pBitstreamData;
235e5c31af7Sopenharmony_ci		// PPS
236e5c31af7Sopenharmony_ci		const VkVideoRefCountBase* pStdPps;
237e5c31af7Sopenharmony_ci		// SPS
238e5c31af7Sopenharmony_ci		const VkVideoRefCountBase* pStdSps;
239e5c31af7Sopenharmony_ci		// VPS
240e5c31af7Sopenharmony_ci		const VkVideoRefCountBase* pStdVps;
241e5c31af7Sopenharmony_ci
242e5c31af7Sopenharmony_ci		ReferencedObjectsInfo(const VkVideoRefCountBase* pBitstreamDataRef,
243e5c31af7Sopenharmony_ci							  const VkVideoRefCountBase* pStdPpsRef,
244e5c31af7Sopenharmony_ci							  const VkVideoRefCountBase* pStdSpsRef,
245e5c31af7Sopenharmony_ci							  const VkVideoRefCountBase* pStdVpsRef = nullptr)
246e5c31af7Sopenharmony_ci			: pBitstreamData(pBitstreamDataRef)
247e5c31af7Sopenharmony_ci			, pStdPps(pStdPpsRef)
248e5c31af7Sopenharmony_ci			, pStdSps(pStdSpsRef)
249e5c31af7Sopenharmony_ci			, pStdVps(pStdVpsRef)
250e5c31af7Sopenharmony_ci		{
251e5c31af7Sopenharmony_ci		}
252e5c31af7Sopenharmony_ci	};
253e5c31af7Sopenharmony_ci
254e5c31af7Sopenharmony_ci	struct PictureResourceInfo
255e5c31af7Sopenharmony_ci	{
256e5c31af7Sopenharmony_ci		VkImage		  image;
257e5c31af7Sopenharmony_ci		VkFormat	  imageFormat;
258e5c31af7Sopenharmony_ci		VkImageLayout currentImageLayout;
259e5c31af7Sopenharmony_ci	};
260e5c31af7Sopenharmony_ci
261e5c31af7Sopenharmony_ci	virtual int32_t InitImagePool(const VkVideoProfileInfoKHR* pDecodeProfile,
262e5c31af7Sopenharmony_ci								  deUint32					   numImages,
263e5c31af7Sopenharmony_ci								  VkFormat					   dpbImageFormat,
264e5c31af7Sopenharmony_ci								  VkFormat					   outImageFormat,
265e5c31af7Sopenharmony_ci								  const VkExtent2D&			   codedExtent,
266e5c31af7Sopenharmony_ci								  const VkExtent2D&			   maxImageExtent,
267e5c31af7Sopenharmony_ci								  VkImageUsageFlags			   dpbImageUsage,
268e5c31af7Sopenharmony_ci								  VkImageUsageFlags			   outImageUsage,
269e5c31af7Sopenharmony_ci								  deUint32					   queueFamilyIndex,
270e5c31af7Sopenharmony_ci								  bool						   useImageArray		  = false,
271e5c31af7Sopenharmony_ci								  bool						   useImageViewArray	  = false,
272e5c31af7Sopenharmony_ci								  bool						   useSeparateOutputImage = false,
273e5c31af7Sopenharmony_ci								  bool						   useLinearOutput		  = false)																																																						= 0;
274e5c31af7Sopenharmony_ci
275e5c31af7Sopenharmony_ci	virtual int32_t QueuePictureForDecode(int8_t picId, VkParserDecodePictureInfo* pDecodePictureInfo, ReferencedObjectsInfo* pReferencedObjectsInfo, FrameSynchronizationInfo* pFrameSynchronizationInfo)																			= 0;
276e5c31af7Sopenharmony_ci	virtual int32_t DequeueDecodedPicture(DecodedFrame* pDecodedFrame)																																																				= 0;
277e5c31af7Sopenharmony_ci	virtual int32_t ReleaseDisplayedPicture(DecodedFrameRelease** pDecodedFramesRelease, deUint32 numFramesToRelease)																																								= 0;
278e5c31af7Sopenharmony_ci	virtual int32_t GetDpbImageResourcesByIndex(deUint32 numResources, const int8_t* referenceSlotIndexes, VkVideoPictureResourceInfoKHR* pictureResources, PictureResourceInfo* pictureResourcesInfo, VkImageLayout newDpbImageLayerLayout = VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR) = 0;
279e5c31af7Sopenharmony_ci	virtual int32_t GetCurrentImageResourceByIndex(int8_t						  referenceSlotIndex,
280e5c31af7Sopenharmony_ci												   VkVideoPictureResourceInfoKHR* dpbPictureResource,
281e5c31af7Sopenharmony_ci												   PictureResourceInfo*			  dpbPictureResourceInfo,
282e5c31af7Sopenharmony_ci												   VkImageLayout				  newDpbImageLayerLayout	= VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR,
283e5c31af7Sopenharmony_ci												   VkVideoPictureResourceInfoKHR* outputPictureResource		= nullptr,
284e5c31af7Sopenharmony_ci												   PictureResourceInfo*			  outputPictureResourceInfo = nullptr,
285e5c31af7Sopenharmony_ci												   VkImageLayout				  newOutputImageLayerLayout = VK_IMAGE_LAYOUT_MAX_ENUM)																																								= 0;
286e5c31af7Sopenharmony_ci	virtual int32_t ReleaseImageResources(deUint32 numResources, const deUint32* indexes)																																															= 0;
287e5c31af7Sopenharmony_ci	virtual int32_t SetPicNumInDecodeOrder(int32_t picId, int32_t picNumInDecodeOrder)																																																= 0;
288e5c31af7Sopenharmony_ci	virtual int32_t SetPicNumInDisplayOrder(int32_t picId, int32_t picNumInDisplayOrder)																																															= 0;
289e5c31af7Sopenharmony_ci	virtual size_t	GetSize()																																																														= 0;
290e5c31af7Sopenharmony_ci	virtual size_t	GetDisplayedFrameCount() const																																																									= 0;
291e5c31af7Sopenharmony_ci
292e5c31af7Sopenharmony_ci	virtual ~VulkanVideoFrameBuffer()
293e5c31af7Sopenharmony_ci	{
294e5c31af7Sopenharmony_ci	}
295e5c31af7Sopenharmony_ci
296e5c31af7Sopenharmony_ci	static VkResult Create(DeviceContext*							devCtx,
297e5c31af7Sopenharmony_ci						   bool										supportsQueries,
298e5c31af7Sopenharmony_ci						   VkSharedBaseObj<VulkanVideoFrameBuffer>& vkVideoFrameBuffer);
299e5c31af7Sopenharmony_ci};
300e5c31af7Sopenharmony_ci
301e5c31af7Sopenharmony_ci} // namespace video
302e5c31af7Sopenharmony_ci} // namespace vkt
303e5c31af7Sopenharmony_ci
304e5c31af7Sopenharmony_ci#endif // _VKTVIDEOFRAMEBUFFER_HPP
305