所以基本上我想比较VkPhysicalDeviceFeatures
Vulkan中的两个,一个VkPhysicalDevice
我正在看的,另一个与我实际需要的一组功能相对应。一个VkPhysicalDeviceFeatures
结构只包含VkBool32
成员(它们的类型定义uint32_t
),但福尔康的每个次要版本可以添加未知数量的这些特征。我想做的只是简单地将每个结构的成员相互比较,而不是为了平等,而是逻辑比较。如果物理设备结构中的相应成员为false,但是我的结构对该成员具有true,则比较应返回false。
我能想到的唯一方法就是此答案发布的内容:
bool hasRequiredFeatures(VkPhysicalDevice physical_device,
VkPhysicalDeviceFeatures required_features) {
VkPhysicalDeviceFeatures physical_device_features = getSupportedFeatures(physical_device);
std::size_t struct_length = sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32);
auto physical_device_features_bool_ptr = reinterpret_cast<VkBool32*>(&physical_device_features);
auto required_features_bool_ptr = reinterpret_cast<VkBool32*>(&required_features);
for(std::size_t i = 0; i < struct_length; ++i){
if(physical_device_features_bool_ptr[i] == VK_FALSE && required_features_bool_ptr[i] == VK_TRUE){
return false;
}
}
return true;
}
这就是我想要的(尽管最好有一种方法来查看哪个特定名称的成员未通过比较,但是我想如果没有反射,那是不可能的),但是我不认为C ++可以保证这样严格的对齐?我有跨平台的方式来完成此任务吗?
您的方法存在一个大问题,该问题与C ++无关,而与Vulkan无关。特别:
次要版本的vulkan可以添加未知数量的这些结构
这告诉我,您打算将此类技术VkPhysicalDeviceFeatures2
以及可能出现在其pNext
链中的任何功能结构应用到。因此,“这些结构的数目未知”。
好吧,这就是问题:VkPhysicalDeviceFeatures2
不仅是一堆VkBool
s。它是可扩展的Vulkan结构,这意味着它以此类结构共有的sType
和pNext
字段开头。1.0版之后的Vulkan设备功能结构也是如此。
可以完成您在1.0版之后的功能结构中所陈述的功能的代码必须能够采用整个pNext
功能结构链并对其进行测试。为了做到这一点,您必须知道它们是什么。从一个指针到任意数据,都无法查询该数据包含X个VkBool
s。
为了使这项工作有效,您将需要能够将sType
值映射到该结构的大小。因此,它不能自动扩展(而且,C ++反射不能解决此问题;它不知道void *pNext
指向的结构);这将需要一定程度的手动维护。
幸运的是,Vulkan XML规范描述文件清楚地指定了特定pNext
链中可以存在的结构。因此,您可以编写一个工具来加载XML,查找VkPhysicalDeviceFeatures2
并处理其pNext
链中出现的所有结构(这部分说起来容易做起来难,因为XML格式仅由Khronos自己的工具处理),以查找哪个结构可用,并生成所需的C ++信息。我相信您可以使用任何脚本语言相对轻松地编写这样的东西。
但是,由于您已经获得了(准合理的)XML中的结构定义,并且您已经获得了将无论如何都将生成一些C ++代码的工具,您只需生成实际的比较逻辑即可。也就是说,与其直接手写成员之间的比较,不如生成成员之间的比较。您甚至可以获取不匹配的成员名称。
如果要处理任意的pNext
-chain功能,则需要某种生成器工具。而且,如果您仍然需要生成器工具,只需使用它即可解决整个问题。
现在,重要的是要意识到,假设hasRequiredFeatures
实现的生成代码将必须是半复杂的。如果允许完整pNext
的结构链,则需要构建自己的等效结构链以用于从Vulkan查询。那并不是完全无关紧要的。
您将需要遍历整个pNext
链并检查sType
每个结构的字段。但是,当然pNext
是void*
,因此您将不得不撒谎/欺骗C ++的规则以阅读该sType
领域。基本上,你必须reinterpret_cast
在void*
一VkStructureType*
,阅读的价值,把它比对所有与您合作的可能性,并从那里继续。您应该跳过所有sType
您不知道的内容,这将需要做更多的C ++技巧。
但是您使用的是低级API。违反C ++规则只是您必须习惯这里的事情。
对于每个这样的结构,您需要分配一个匹配的结构,sType
适当地填充它,然后将其添加到pNext
要构建的链中。
构建完所有这些功能之后,您可以进行Vulkan调用,进行比较,收集数据并最后删除整个结构链。
如果您的目标确实是坚持使用公正VkPhysicalDeviceFeatures
而不是可扩展的结构,而您只想使用C ++便携式方法比较此类结构,则将memcpy
它们放入一个VkBool
数组中,并比较两个数组是否不匹配。这两种类型都是微不足道的可复制的,因此做到这一点并不是表面上违法的。
此代码尚未编译或测试。
bool hasRequiredFeatures(VkPhysicalDevice physical_device,
VkPhysicalDeviceFeatures required_features)
{
constexpr auto feature_count = sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32);
using FeatureArray = std::array<VkBool, feature_count>;
auto physical_device_features = getSupportedFeatures(physical_device);
FeatureArray required;
memcpy(&required, &required_features, sizeof(FeatureArray));
FeatureArray retrieved;
memcpy(&retrieved, &physical_device_features, sizeof(FeatureArray));
bool did_mismatch = false;
for(auto it_pair = std::mismatch(required.begin(), required.end(), retrieved.begin());
it_pair.first != required.end();
it_pair = std::mismatch(it_pair.first, required.end(), it_pair.second))
{
did_mismatch = true
auto mismatch_index = it_pair.first - required.begin();
//Do something with mismatch_index
}
return did_mismatch;
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句