blob: 319e9971f2006c4cebfd2275bc5be6da69c396f4 [file] [log] [blame]
#ifndef _VKDEVICEPROPERTIES_HPP
#define _VKDEVICEPROPERTIES_HPP
/*-------------------------------------------------------------------------
* Vulkan CTS Framework
* --------------------
*
* Copyright (c) 2019 The Khronos Group Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*//*!
* \file
* \brief Vulkan DeviceProperties class utility.
*//*--------------------------------------------------------------------*/
#include <map>
#include <string>
#include <utility>
#include <vector>
#include "deMemory.h"
#include "vkDefs.hpp"
namespace vk
{
// Structure describing vulkan property structure
struct PropertyDesc
{
VkStructureType sType;
const char *name;
const uint32_t specVersion;
const uint32_t typeId;
};
// Structure containg all property blobs - this simplifies generated code
struct AllPropertiesBlobs
{
VkPhysicalDeviceVulkan11Properties &vk11;
VkPhysicalDeviceVulkan12Properties &vk12;
// add blobs from future vulkan versions here
};
// Base class for all PropertyStructWrapper specialization
struct PropertyStructWrapperBase
{
virtual ~PropertyStructWrapperBase(void)
{
}
virtual void initializePropertyFromBlob(const AllPropertiesBlobs &allPropertiesBlobs) = 0;
virtual uint32_t getPropertyTypeId(void) const = 0;
virtual PropertyDesc getPropertyDesc(void) const = 0;
virtual void **getPropertyTypeNext(void) = 0;
virtual void *getPropertyTypeRaw(void) = 0;
};
using PropertyStructWrapperCreator = PropertyStructWrapperBase *(*)(void);
struct PropertyStructCreationData
{
PropertyStructWrapperCreator creatorFunction;
const char *name;
uint32_t specVersion;
};
template <class PropertyType>
class PropertyStructWrapper;
template <class PropertyType>
PropertyDesc makePropertyDesc(void);
template <class PropertyType>
PropertyStructWrapperBase *createPropertyStructWrapper(void)
{
return new PropertyStructWrapper<PropertyType>(makePropertyDesc<PropertyType>());
}
template <class PropertyType>
void initPropertyFromBlob(PropertyType &propertyType, const AllPropertiesBlobs &allPropertiesBlobs);
template <class PropertyType>
void initPropertyFromBlobWrapper(PropertyType &propertyType, const AllPropertiesBlobs &allPropertiesBlobs)
{
initPropertyFromBlob<PropertyType>(propertyType, allPropertiesBlobs);
}
class DeviceProperties
{
public:
DeviceProperties(const InstanceInterface &vki, const uint32_t apiVersion, const VkPhysicalDevice physicalDevice,
const std::vector<std::string> &instanceExtensions,
const std::vector<std::string> &deviceExtensions);
~DeviceProperties(void);
template <class PropertyType>
const PropertyType &getPropertyType(void) const;
const VkPhysicalDeviceProperties2 &getCoreProperties2(void) const
{
return m_coreProperties2;
}
const VkPhysicalDeviceVulkan11Properties &getVulkan11Properties(void) const
{
return m_vulkan11Properties;
}
const VkPhysicalDeviceVulkan12Properties &getVulkan12Properties(void) const
{
return m_vulkan12Properties;
}
#ifdef CTS_USES_VULKANSC
const VkPhysicalDeviceVulkanSC10Properties &getVulkanSC10Properties(void) const
{
return m_vulkanSC10Properties;
}
#endif // CTS_USES_VULKANSC
bool contains(const std::string &property, bool throwIfNotExists = false) const;
bool isDevicePropertyInitialized(VkStructureType sType) const;
private:
static void addToChainStructWrapper(void ***chainPNextPtr, PropertyStructWrapperBase *structWrapper);
private:
VkPhysicalDeviceProperties2 m_coreProperties2;
mutable std::vector<PropertyStructWrapperBase *> m_properties;
VkPhysicalDeviceVulkan11Properties m_vulkan11Properties;
VkPhysicalDeviceVulkan12Properties m_vulkan12Properties;
#ifdef CTS_USES_VULKANSC
VkPhysicalDeviceVulkanSC10Properties m_vulkanSC10Properties;
#endif // CTS_USES_VULKANSC
};
template <class PropertyType>
const PropertyType &DeviceProperties::getPropertyType(void) const
{
typedef PropertyStructWrapper<PropertyType> *PropertyWrapperPtr;
const PropertyDesc propDesc = makePropertyDesc<PropertyType>();
const VkStructureType sType = propDesc.sType;
// try to find property by sType
for (auto property : m_properties)
{
if (sType == property->getPropertyDesc().sType)
return static_cast<PropertyWrapperPtr>(property)->getPropertyTypeRef();
}
// try to find property by id that was assigned by gen_framework script
const uint32_t propertyId = propDesc.typeId;
for (auto property : m_properties)
{
if (propertyId == property->getPropertyTypeId())
return static_cast<PropertyWrapperPtr>(property)->getPropertyTypeRef();
}
// if initialized property structure was not found create empty one and return it
m_properties.push_back(vk::createPropertyStructWrapper<PropertyType>());
return static_cast<PropertyWrapperPtr>(m_properties.back())->getPropertyTypeRef();
}
template <class PropertyType>
class PropertyStructWrapper : public PropertyStructWrapperBase
{
public:
PropertyStructWrapper(const PropertyDesc &propertyDesc) : m_propertyDesc(propertyDesc)
{
deMemset(&m_propertyType, 0, sizeof(m_propertyType));
m_propertyType.sType = propertyDesc.sType;
}
void initializePropertyFromBlob(const AllPropertiesBlobs &allPropertiesBlobs)
{
initPropertyFromBlobWrapper(m_propertyType, allPropertiesBlobs);
}
uint32_t getPropertyTypeId(void) const
{
return m_propertyDesc.typeId;
}
PropertyDesc getPropertyDesc(void) const
{
return m_propertyDesc;
}
void **getPropertyTypeNext(void)
{
return &m_propertyType.pNext;
}
void *getPropertyTypeRaw(void)
{
return &m_propertyType;
}
PropertyType &getPropertyTypeRef(void)
{
return m_propertyType;
}
public:
// metadata about property structure
const PropertyDesc m_propertyDesc;
// actual vulkan property structure
PropertyType m_propertyType;
};
} // namespace vk
#endif // _VKDEVICEPROPERTIES_HPP