1e5c31af7Sopenharmony_ci#ifndef _VKDEVICEPROPERTIES_HPP
2e5c31af7Sopenharmony_ci#define _VKDEVICEPROPERTIES_HPP
3e5c31af7Sopenharmony_ci/*-------------------------------------------------------------------------
4e5c31af7Sopenharmony_ci * Vulkan CTS Framework
5e5c31af7Sopenharmony_ci * --------------------
6e5c31af7Sopenharmony_ci *
7e5c31af7Sopenharmony_ci * Copyright (c) 2019 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 Vulkan DeviceProperties class utility.
24e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/
25e5c31af7Sopenharmony_ci
26e5c31af7Sopenharmony_ci#include <map>
27e5c31af7Sopenharmony_ci#include <string>
28e5c31af7Sopenharmony_ci#include <utility>
29e5c31af7Sopenharmony_ci#include <vector>
30e5c31af7Sopenharmony_ci
31e5c31af7Sopenharmony_ci#include "deMemory.h"
32e5c31af7Sopenharmony_ci#include "vkDefs.hpp"
33e5c31af7Sopenharmony_ci
34e5c31af7Sopenharmony_cinamespace vk
35e5c31af7Sopenharmony_ci{
36e5c31af7Sopenharmony_ci
37e5c31af7Sopenharmony_ci// Structure describing vulkan property structure
38e5c31af7Sopenharmony_cistruct PropertyDesc
39e5c31af7Sopenharmony_ci{
40e5c31af7Sopenharmony_ci	VkStructureType		sType;
41e5c31af7Sopenharmony_ci	const char*			name;
42e5c31af7Sopenharmony_ci	const deUint32		specVersion;
43e5c31af7Sopenharmony_ci	const deUint32		typeId;
44e5c31af7Sopenharmony_ci};
45e5c31af7Sopenharmony_ci
46e5c31af7Sopenharmony_ci// Structure containg all property blobs - this simplifies generated code
47e5c31af7Sopenharmony_cistruct AllPropertiesBlobs
48e5c31af7Sopenharmony_ci{
49e5c31af7Sopenharmony_ci	VkPhysicalDeviceVulkan11Properties& vk11;
50e5c31af7Sopenharmony_ci	VkPhysicalDeviceVulkan12Properties& vk12;
51e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC
52e5c31af7Sopenharmony_ci	VkPhysicalDeviceVulkan13Properties& vk13;
53e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC
54e5c31af7Sopenharmony_ci	// add blobs from future vulkan versions here
55e5c31af7Sopenharmony_ci};
56e5c31af7Sopenharmony_ci
57e5c31af7Sopenharmony_ci// Base class for all PropertyStructWrapper specialization
58e5c31af7Sopenharmony_cistruct PropertyStructWrapperBase
59e5c31af7Sopenharmony_ci{
60e5c31af7Sopenharmony_ci	virtual					~PropertyStructWrapperBase	(void) {}
61e5c31af7Sopenharmony_ci	virtual void			initializePropertyFromBlob	(const AllPropertiesBlobs& allPropertiesBlobs) = 0;
62e5c31af7Sopenharmony_ci	virtual deUint32		getPropertyTypeId			(void) const = 0;
63e5c31af7Sopenharmony_ci	virtual PropertyDesc	getPropertyDesc				(void) const = 0;
64e5c31af7Sopenharmony_ci	virtual void**			getPropertyTypeNext			(void) = 0;
65e5c31af7Sopenharmony_ci	virtual void*			getPropertyTypeRaw			(void) = 0;
66e5c31af7Sopenharmony_ci};
67e5c31af7Sopenharmony_ci
68e5c31af7Sopenharmony_ciusing PropertyStructWrapperCreator	= PropertyStructWrapperBase* (*) (void);
69e5c31af7Sopenharmony_cistruct PropertyStructCreationData
70e5c31af7Sopenharmony_ci{
71e5c31af7Sopenharmony_ci	PropertyStructWrapperCreator creatorFunction;
72e5c31af7Sopenharmony_ci	const char*					 name;
73e5c31af7Sopenharmony_ci	deUint32					 specVersion;
74e5c31af7Sopenharmony_ci};
75e5c31af7Sopenharmony_ci
76e5c31af7Sopenharmony_citemplate<class PropertyType> class PropertyStructWrapper;
77e5c31af7Sopenharmony_citemplate<class PropertyType> PropertyDesc makePropertyDesc (void);
78e5c31af7Sopenharmony_ci
79e5c31af7Sopenharmony_citemplate<class PropertyType>
80e5c31af7Sopenharmony_ciPropertyStructWrapperBase* createPropertyStructWrapper (void)
81e5c31af7Sopenharmony_ci{
82e5c31af7Sopenharmony_ci	return new PropertyStructWrapper<PropertyType>(makePropertyDesc<PropertyType>());
83e5c31af7Sopenharmony_ci}
84e5c31af7Sopenharmony_ci
85e5c31af7Sopenharmony_citemplate<class PropertyType>
86e5c31af7Sopenharmony_civoid initPropertyFromBlob(PropertyType& propertyType, const AllPropertiesBlobs& allPropertiesBlobs);
87e5c31af7Sopenharmony_ci
88e5c31af7Sopenharmony_citemplate<class PropertyType>
89e5c31af7Sopenharmony_civoid initPropertyFromBlobWrapper(PropertyType& propertyType, const AllPropertiesBlobs& allPropertiesBlobs)
90e5c31af7Sopenharmony_ci{
91e5c31af7Sopenharmony_ci	initPropertyFromBlob<PropertyType>(propertyType, allPropertiesBlobs);
92e5c31af7Sopenharmony_ci}
93e5c31af7Sopenharmony_ci
94e5c31af7Sopenharmony_ciclass DeviceProperties
95e5c31af7Sopenharmony_ci{
96e5c31af7Sopenharmony_cipublic:
97e5c31af7Sopenharmony_ci												DeviceProperties				(const InstanceInterface&			vki,
98e5c31af7Sopenharmony_ci																				 const deUint32						apiVersion,
99e5c31af7Sopenharmony_ci																				 const VkPhysicalDevice				physicalDevice,
100e5c31af7Sopenharmony_ci																				 const std::vector<std::string>&	instanceExtensions,
101e5c31af7Sopenharmony_ci																				 const std::vector<std::string>&	deviceExtensions);
102e5c31af7Sopenharmony_ci
103e5c31af7Sopenharmony_ci												~DeviceProperties				(void);
104e5c31af7Sopenharmony_ci
105e5c31af7Sopenharmony_ci	template<class PropertyType>
106e5c31af7Sopenharmony_ci	const PropertyType&							getPropertyType				(void) const;
107e5c31af7Sopenharmony_ci
108e5c31af7Sopenharmony_ci	const VkPhysicalDeviceProperties2&			getCoreProperties2			(void) const { return m_coreProperties2; }
109e5c31af7Sopenharmony_ci	const VkPhysicalDeviceVulkan11Properties&	getVulkan11Properties		(void) const { return m_vulkan11Properties; }
110e5c31af7Sopenharmony_ci	const VkPhysicalDeviceVulkan12Properties&	getVulkan12Properties		(void) const { return m_vulkan12Properties; }
111e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC
112e5c31af7Sopenharmony_ci	const VkPhysicalDeviceVulkan13Properties&	getVulkan13Properties		(void) const { return m_vulkan13Properties; }
113e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC
114e5c31af7Sopenharmony_ci#ifdef CTS_USES_VULKANSC
115e5c31af7Sopenharmony_ci	const VkPhysicalDeviceVulkanSC10Properties&	getVulkanSC10Properties		(void) const { return m_vulkanSC10Properties; }
116e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC
117e5c31af7Sopenharmony_ci
118e5c31af7Sopenharmony_ci	bool										contains					(const std::string& property, bool throwIfNotExists = false) const;
119e5c31af7Sopenharmony_ci
120e5c31af7Sopenharmony_ci	bool										isDevicePropertyInitialized	(VkStructureType sType) const;
121e5c31af7Sopenharmony_ci
122e5c31af7Sopenharmony_ciprivate:
123e5c31af7Sopenharmony_ci
124e5c31af7Sopenharmony_ci	static void									addToChainStructWrapper(void*** chainPNextPtr, PropertyStructWrapperBase* structWrapper);
125e5c31af7Sopenharmony_ci
126e5c31af7Sopenharmony_ciprivate:
127e5c31af7Sopenharmony_ci
128e5c31af7Sopenharmony_ci	VkPhysicalDeviceProperties2						m_coreProperties2;
129e5c31af7Sopenharmony_ci	mutable std::vector<PropertyStructWrapperBase*>	m_properties;
130e5c31af7Sopenharmony_ci	VkPhysicalDeviceVulkan11Properties				m_vulkan11Properties;
131e5c31af7Sopenharmony_ci	VkPhysicalDeviceVulkan12Properties				m_vulkan12Properties;
132e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC
133e5c31af7Sopenharmony_ci	VkPhysicalDeviceVulkan13Properties				m_vulkan13Properties;
134e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC
135e5c31af7Sopenharmony_ci#ifdef CTS_USES_VULKANSC
136e5c31af7Sopenharmony_ci	VkPhysicalDeviceVulkanSC10Properties			m_vulkanSC10Properties;
137e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC
138e5c31af7Sopenharmony_ci};
139e5c31af7Sopenharmony_ci
140e5c31af7Sopenharmony_citemplate<class PropertyType>
141e5c31af7Sopenharmony_ciconst PropertyType&	DeviceProperties::getPropertyType(void) const
142e5c31af7Sopenharmony_ci{
143e5c31af7Sopenharmony_ci	typedef PropertyStructWrapper<PropertyType>* PropertyWrapperPtr;
144e5c31af7Sopenharmony_ci
145e5c31af7Sopenharmony_ci	const PropertyDesc		propDesc	= makePropertyDesc<PropertyType>();
146e5c31af7Sopenharmony_ci	const VkStructureType	sType		= propDesc.sType;
147e5c31af7Sopenharmony_ci
148e5c31af7Sopenharmony_ci	// try to find property by sType
149e5c31af7Sopenharmony_ci	for (auto property : m_properties)
150e5c31af7Sopenharmony_ci	{
151e5c31af7Sopenharmony_ci		if (sType == property->getPropertyDesc().sType)
152e5c31af7Sopenharmony_ci			return static_cast<PropertyWrapperPtr>(property)->getPropertyTypeRef();
153e5c31af7Sopenharmony_ci	}
154e5c31af7Sopenharmony_ci
155e5c31af7Sopenharmony_ci	// try to find property by id that was assigned by gen_framework script
156e5c31af7Sopenharmony_ci	const deUint32 propertyId = propDesc.typeId;
157e5c31af7Sopenharmony_ci	for (auto property : m_properties)
158e5c31af7Sopenharmony_ci	{
159e5c31af7Sopenharmony_ci		if (propertyId == property->getPropertyTypeId())
160e5c31af7Sopenharmony_ci			return static_cast<PropertyWrapperPtr>(property)->getPropertyTypeRef();
161e5c31af7Sopenharmony_ci	}
162e5c31af7Sopenharmony_ci
163e5c31af7Sopenharmony_ci	// if initialized property structure was not found create empty one and return it
164e5c31af7Sopenharmony_ci	m_properties.push_back(vk::createPropertyStructWrapper<PropertyType>());
165e5c31af7Sopenharmony_ci	return static_cast<PropertyWrapperPtr>(m_properties.back())->getPropertyTypeRef();
166e5c31af7Sopenharmony_ci}
167e5c31af7Sopenharmony_ci
168e5c31af7Sopenharmony_citemplate<class PropertyType>
169e5c31af7Sopenharmony_ciclass PropertyStructWrapper : public PropertyStructWrapperBase
170e5c31af7Sopenharmony_ci{
171e5c31af7Sopenharmony_cipublic:
172e5c31af7Sopenharmony_ci	PropertyStructWrapper (const PropertyDesc& propertyDesc)
173e5c31af7Sopenharmony_ci		: m_propertyDesc(propertyDesc)
174e5c31af7Sopenharmony_ci	{
175e5c31af7Sopenharmony_ci		deMemset(&m_propertyType, 0, sizeof(m_propertyType));
176e5c31af7Sopenharmony_ci		m_propertyType.sType = propertyDesc.sType;
177e5c31af7Sopenharmony_ci	}
178e5c31af7Sopenharmony_ci
179e5c31af7Sopenharmony_ci	void initializePropertyFromBlob (const AllPropertiesBlobs& allPropertiesBlobs)
180e5c31af7Sopenharmony_ci	{
181e5c31af7Sopenharmony_ci		initPropertyFromBlobWrapper(m_propertyType, allPropertiesBlobs);
182e5c31af7Sopenharmony_ci	}
183e5c31af7Sopenharmony_ci
184e5c31af7Sopenharmony_ci	deUint32		getPropertyTypeId	(void) const	{ return m_propertyDesc.typeId;	}
185e5c31af7Sopenharmony_ci	PropertyDesc	getPropertyDesc		(void) const	{ return m_propertyDesc;			}
186e5c31af7Sopenharmony_ci	void**			getPropertyTypeNext	(void)			{ return &m_propertyType.pNext;	}
187e5c31af7Sopenharmony_ci	void*			getPropertyTypeRaw	(void)			{ return &m_propertyType;		}
188e5c31af7Sopenharmony_ci	PropertyType&	getPropertyTypeRef	(void)			{ return m_propertyType;			}
189e5c31af7Sopenharmony_ci
190e5c31af7Sopenharmony_cipublic:
191e5c31af7Sopenharmony_ci	// metadata about property structure
192e5c31af7Sopenharmony_ci	const PropertyDesc	m_propertyDesc;
193e5c31af7Sopenharmony_ci
194e5c31af7Sopenharmony_ci	// actual vulkan property structure
195e5c31af7Sopenharmony_ci	PropertyType			m_propertyType;
196e5c31af7Sopenharmony_ci};
197e5c31af7Sopenharmony_ci} // vk
198e5c31af7Sopenharmony_ci
199e5c31af7Sopenharmony_ci#endif // _VKDEVICEPROPERTIES_HPP
200