Fix breaking bug with features not being populated from VkGetPhysicalDeviceFeatures2

This commit is contained in:
dangerkangaroo 2021-04-09 02:10:34 -05:00 committed by Charles Giessen
parent 0a397a33d5
commit 21e400cfcc
2 changed files with 34 additions and 12 deletions

View File

@ -1015,9 +1015,12 @@ PhysicalDeviceSelector::PhysicalDeviceDesc PhysicalDeviceSelector::populate_devi
prev = &extension; prev = &extension;
} }
if(desc.extension_features.size() > 0) { if(desc.extension_features.size() > 0) {
desc.device_features2.pNext = &desc.extension_features[0].structure; desc.device_features2.pNext = desc.extension_features[0].structure;
} }
detail::vulkan_functions().fp_vkGetPhysicalDeviceFeatures2(phys_device, &desc.device_features2); detail::vulkan_functions().fp_vkGetPhysicalDeviceFeatures2(phys_device, &desc.device_features2);
for(auto& extension : desc.extension_features) {
extension.update();
}
} }
#endif #endif
return desc; return desc;

View File

@ -198,21 +198,26 @@ class PhysicalDeviceSelector;
struct ExtensionFeatures { struct ExtensionFeatures {
using DeleteProc = void(*)(ExtensionFeatures&); using DeleteProc = void(*)(ExtensionFeatures&);
using UpdateProc = void(*)(ExtensionFeatures&);
using CopyProc = void(*)(const ExtensionFeatures&, ExtensionFeatures&); using CopyProc = void(*)(const ExtensionFeatures&, ExtensionFeatures&);
ExtensionFeatures() = default; ExtensionFeatures() = default;
ExtensionFeatures (const ExtensionFeatures& other) : delete_proc(other.delete_proc), copy_proc(other.copy_proc) { ExtensionFeatures (const ExtensionFeatures& other) : delete_proc(other.delete_proc),
update_proc(other.update_proc),
copy_proc(other.copy_proc) {
if(copy_proc) { copy_proc(other, *this); } if(copy_proc) { copy_proc(other, *this); }
} }
ExtensionFeatures (ExtensionFeatures&& other) : delete_proc(std::exchange(other.delete_proc, nullptr)), ExtensionFeatures (ExtensionFeatures&& other) : delete_proc(std::exchange(other.delete_proc, nullptr)),
update_proc(std::exchange(other.update_proc, nullptr)),
copy_proc(std::exchange(other.copy_proc, nullptr)), copy_proc(std::exchange(other.copy_proc, nullptr)),
structure(std::exchange(other.structure, nullptr)), structure(std::exchange(other.structure, nullptr)),
fields(std::exchange(other.fields, {})) {} fields(std::exchange(other.fields, {})) {}
ExtensionFeatures& operator=(const ExtensionFeatures& other) { ExtensionFeatures& operator=(const ExtensionFeatures& other) {
delete_proc = other.delete_proc; delete_proc = other.delete_proc;
update_proc = other.update_proc;
copy_proc = other.copy_proc; copy_proc = other.copy_proc;
if(copy_proc) { copy_proc(other, *this); } if(copy_proc) { copy_proc(other, *this); }
return *this; return *this;
@ -220,6 +225,7 @@ struct ExtensionFeatures {
ExtensionFeatures& operator=(ExtensionFeatures&& other) { ExtensionFeatures& operator=(ExtensionFeatures&& other) {
delete_proc = std::exchange(other.delete_proc, nullptr); delete_proc = std::exchange(other.delete_proc, nullptr);
update_proc = std::exchange(other.update_proc, nullptr);
copy_proc = std::exchange(other.copy_proc, nullptr); copy_proc = std::exchange(other.copy_proc, nullptr);
structure = std::exchange(other.structure, nullptr); structure = std::exchange(other.structure, nullptr);
fields = std::exchange(other.fields, {}); fields = std::exchange(other.fields, {});
@ -234,14 +240,6 @@ struct ExtensionFeatures {
*new_features_structure = src; *new_features_structure = src;
extension_features.structure = reinterpret_cast<VkBaseOutStructure*>(new_features_structure); extension_features.structure = reinterpret_cast<VkBaseOutStructure*>(new_features_structure);
auto structure_field_count =
(sizeof(T) - (sizeof(VkStructureType) + sizeof(void*))) / sizeof(VkBool32);
extension_features.fields.resize(structure_field_count);
memcpy(extension_features.fields.data(),
reinterpret_cast<unsigned char*>(extension_features.structure) +
(sizeof(VkStructureType) + sizeof(void*)),
sizeof(VkBool32) * extension_features.fields.size());
extension_features.delete_proc = [](ExtensionFeatures& features) { extension_features.delete_proc = [](ExtensionFeatures& features) {
features.fields = {}; features.fields = {};
@ -252,6 +250,16 @@ struct ExtensionFeatures {
}; };
extension_features.update_proc = [](ExtensionFeatures& features) {
auto structure_field_count = (sizeof(T) - (sizeof(void*) * 2)) / sizeof(VkBool32);
features.fields.resize(structure_field_count);
memcpy(features.fields.data(),
reinterpret_cast<unsigned char*>(features.structure) + (sizeof(void*) * 2),
sizeof(VkBool32) * features.fields.size());
};
extension_features.copy_proc = [](const ExtensionFeatures& src, ExtensionFeatures& dst) { extension_features.copy_proc = [](const ExtensionFeatures& src, ExtensionFeatures& dst) {
if(dst.structure) { if(dst.structure) {
@ -265,9 +273,19 @@ struct ExtensionFeatures {
}; };
extension_features.update();
return extension_features; return extension_features;
} }
void update() {
if(update_proc) {
update_proc(*this);
}
}
bool match(const ExtensionFeatures& other) const { bool match(const ExtensionFeatures& other) const {
if(!structure || !other.structure || structure->sType != other.structure->sType) { return false; } if(!structure || !other.structure || structure->sType != other.structure->sType) { return false; }
@ -290,8 +308,9 @@ struct ExtensionFeatures {
VkBaseOutStructure* structure = nullptr; VkBaseOutStructure* structure = nullptr;
std::vector<VkBool32> fields; std::vector<VkBool32> fields;
private: private:
DeleteProc delete_proc = {}; DeleteProc delete_proc = nullptr;
CopyProc copy_proc = {}; UpdateProc update_proc = nullptr;
CopyProc copy_proc = nullptr;
}; };
struct Instance { struct Instance {