mirror of
https://github.com/charles-lunarg/vk-bootstrap.git
synced 2024-11-22 15:24:34 +00:00
Revert "Revert "Removes need for function pointers.""
This reverts commit e671170007
.
This commit is contained in:
parent
63f06898f9
commit
9c4317e324
@ -1010,17 +1010,14 @@ PhysicalDeviceSelector::PhysicalDeviceDesc PhysicalDeviceSelector::populate_devi
|
|||||||
detail::ExtensionFeatures* prev = nullptr;
|
detail::ExtensionFeatures* prev = nullptr;
|
||||||
for(auto& extension : desc.extension_features) {
|
for(auto& extension : desc.extension_features) {
|
||||||
if(prev != nullptr) {
|
if(prev != nullptr) {
|
||||||
prev->structure->pNext = extension.structure;
|
prev->structure.header->pNext = extension.structure.header;
|
||||||
}
|
}
|
||||||
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.front().structure.header;
|
||||||
}
|
}
|
||||||
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;
|
||||||
@ -1407,20 +1404,20 @@ detail::Result<Device> DeviceBuilder::build() const {
|
|||||||
// Setup the pNexts of all the extension features
|
// Setup the pNexts of all the extension features
|
||||||
std::vector<detail::ExtensionFeatures> match = physical_device.extension_features;
|
std::vector<detail::ExtensionFeatures> match = physical_device.extension_features;
|
||||||
VkPhysicalDeviceFeatures2 local_features2{};
|
VkPhysicalDeviceFeatures2 local_features2{};
|
||||||
VkBaseOutStructure* tail = nullptr;
|
//VkBaseOutStructure* tail = nullptr;
|
||||||
if (physical_device.instance_version >= VK_MAKE_VERSION(1, 1, 0) &&
|
if (physical_device.instance_version >= VK_MAKE_VERSION(1, 1, 0) &&
|
||||||
match.size() > 0) {
|
match.size() > 0) {
|
||||||
detail::ExtensionFeatures* prev = nullptr;
|
detail::ExtensionFeatures* prev = nullptr;
|
||||||
for(auto& extension : match) {
|
for(auto& extension : match) {
|
||||||
if(prev != nullptr) {
|
if(prev != nullptr) {
|
||||||
prev->structure->pNext = extension.structure;
|
prev->structure.header->pNext = extension.structure.header;
|
||||||
}
|
}
|
||||||
prev = &extension;
|
prev = &extension;
|
||||||
tail = prev->structure;
|
//tail = prev->structure;
|
||||||
}
|
}
|
||||||
local_features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
|
local_features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
|
||||||
local_features2.features = physical_device.features;
|
local_features2.features = physical_device.features;
|
||||||
local_features2.pNext = match.front().structure;
|
local_features2.pNext = match.front().structure.header;
|
||||||
has_phys_dev_features_2 = true;
|
has_phys_dev_features_2 = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1440,7 +1437,7 @@ detail::Result<Device> DeviceBuilder::build() const {
|
|||||||
if (has_phys_dev_features_2) {
|
if (has_phys_dev_features_2) {
|
||||||
device_create_info.pNext = &local_features2;
|
device_create_info.pNext = &local_features2;
|
||||||
if(info.pNext_chain.size() > 0) {
|
if(info.pNext_chain.size() > 0) {
|
||||||
match.back().structure->pNext = info.pNext_chain.front();
|
match.back().structure.header->pNext = info.pNext_chain.front();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
device_create_info.pEnabledFeatures = &physical_device.features;
|
device_create_info.pEnabledFeatures = &physical_device.features;
|
||||||
|
@ -117,38 +117,73 @@ template <typename T> class Result {
|
|||||||
|
|
||||||
struct ExtensionFeatures {
|
struct ExtensionFeatures {
|
||||||
|
|
||||||
using DeleteProc = void(*)(ExtensionFeatures&);
|
struct StructureContainer {
|
||||||
using UpdateProc = void(*)(ExtensionFeatures&);
|
|
||||||
using CopyProc = void(*)(const ExtensionFeatures&, ExtensionFeatures&);
|
struct Header {
|
||||||
|
VkStructureType sType;
|
||||||
|
void* pNext;
|
||||||
|
};
|
||||||
|
|
||||||
|
StructureContainer() = default;
|
||||||
|
|
||||||
|
StructureContainer (StructureContainer const& other) { copy(other); }
|
||||||
|
|
||||||
|
StructureContainer (StructureContainer&& other) { copy(other); }
|
||||||
|
|
||||||
|
StructureContainer& operator=(StructureContainer const& other) { copy(other); return *this; }
|
||||||
|
|
||||||
|
StructureContainer& operator=(StructureContainer&& other) { copy(other); return *this; }
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void set(T const& features) {
|
||||||
|
data.resize(sizeof(T));
|
||||||
|
*reinterpret_cast<T*>(data.data()) = features;
|
||||||
|
count = (sizeof(T) - sizeof(Header)) / sizeof(VkBool32);
|
||||||
|
header = reinterpret_cast<Header*>(data.data());
|
||||||
|
fields = reinterpret_cast<VkBool32*>(data.data() + sizeof(Header));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool match(StructureContainer const& other) const {
|
||||||
|
if(!header || !other.header || header->sType != other.header->sType) { return false; }
|
||||||
|
for(auto i = 0; i < count; ++i) {
|
||||||
|
if(fields[i] == VK_TRUE && other.fields[i] == VK_FALSE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Header* header = nullptr;
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Just to avoid having it copied in 4 places
|
||||||
|
void copy(StructureContainer const& other) {
|
||||||
|
data = other.data;
|
||||||
|
count = other.count;
|
||||||
|
header = reinterpret_cast<Header*>(data.data());
|
||||||
|
fields = reinterpret_cast<VkBool32*>(data.data() + sizeof(Header));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<char> data;
|
||||||
|
VkBool32* fields = nullptr;
|
||||||
|
void* extend = nullptr; // Future proofing
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
ExtensionFeatures() = default;
|
ExtensionFeatures() = default;
|
||||||
|
|
||||||
ExtensionFeatures (const ExtensionFeatures& other) : delete_proc(other.delete_proc),
|
ExtensionFeatures (ExtensionFeatures const& other) : structure(other.structure) {}
|
||||||
update_proc(other.update_proc),
|
|
||||||
copy_proc(other.copy_proc) {
|
|
||||||
if(copy_proc) { copy_proc(other, *this); }
|
|
||||||
}
|
|
||||||
|
|
||||||
ExtensionFeatures (ExtensionFeatures&& other) : delete_proc(std::exchange(other.delete_proc, nullptr)),
|
ExtensionFeatures (ExtensionFeatures&& other) : structure(std::exchange(other.structure, {})) {}
|
||||||
update_proc(std::exchange(other.update_proc, nullptr)),
|
|
||||||
copy_proc(std::exchange(other.copy_proc, nullptr)),
|
|
||||||
structure(std::exchange(other.structure, nullptr)),
|
|
||||||
fields(std::exchange(other.fields, {})) {}
|
|
||||||
|
|
||||||
ExtensionFeatures& operator=(const ExtensionFeatures& other) {
|
ExtensionFeatures& operator=(ExtensionFeatures const& other) {
|
||||||
delete_proc = other.delete_proc;
|
structure = other.structure;
|
||||||
update_proc = other.update_proc;
|
|
||||||
copy_proc = other.copy_proc;
|
|
||||||
if(copy_proc) { copy_proc(other, *this); }
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExtensionFeatures& operator=(ExtensionFeatures&& other) {
|
ExtensionFeatures& operator=(ExtensionFeatures&& other) {
|
||||||
delete_proc = std::exchange(other.delete_proc, nullptr);
|
structure = std::exchange(other.structure, {});
|
||||||
update_proc = std::exchange(other.update_proc, nullptr);
|
|
||||||
copy_proc = std::exchange(other.copy_proc, nullptr);
|
|
||||||
structure = std::exchange(other.structure, nullptr);
|
|
||||||
fields = std::exchange(other.fields, {});
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,81 +191,15 @@ struct ExtensionFeatures {
|
|||||||
static ExtensionFeatures make(T src) {
|
static ExtensionFeatures make(T src) {
|
||||||
|
|
||||||
ExtensionFeatures extension_features;
|
ExtensionFeatures extension_features;
|
||||||
T* new_features_structure = new T;
|
extension_features.structure.set<T>(src);
|
||||||
*new_features_structure = src;
|
|
||||||
extension_features.structure = reinterpret_cast<VkBaseOutStructure*>(new_features_structure);
|
|
||||||
|
|
||||||
extension_features.delete_proc = [](ExtensionFeatures& features) {
|
|
||||||
|
|
||||||
features.fields = {};
|
|
||||||
if(features.structure) {
|
|
||||||
auto casted = reinterpret_cast<T *>(features.structure);
|
|
||||||
delete casted;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
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) {
|
|
||||||
|
|
||||||
if(dst.structure) {
|
|
||||||
auto casted = reinterpret_cast<T*>(dst.structure);
|
|
||||||
delete casted;
|
|
||||||
}
|
|
||||||
T* new_features_structure = new T;
|
|
||||||
*new_features_structure = *reinterpret_cast<T*>(src.structure);
|
|
||||||
dst.structure = reinterpret_cast<VkBaseOutStructure*>(new_features_structure);
|
|
||||||
dst.fields = src.fields;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
extension_features.update();
|
|
||||||
|
|
||||||
return extension_features;
|
return extension_features;
|
||||||
}
|
|
||||||
|
|
||||||
void update() {
|
|
||||||
|
|
||||||
if(update_proc) {
|
|
||||||
update_proc(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
bool match(const ExtensionFeatures& other) const {
|
|
||||||
|
|
||||||
if(!structure || !other.structure || structure->sType != other.structure->sType) { return false; }
|
|
||||||
|
|
||||||
for(auto i = 0; i < fields.size(); ++i) {
|
|
||||||
if(fields[i] == VK_TRUE && other.fields[i] == VK_FALSE) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
~ExtensionFeatures() {
|
|
||||||
|
|
||||||
if(delete_proc) { delete_proc(*this); }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VkBaseOutStructure* structure = nullptr;
|
bool match(const ExtensionFeatures& other) const { return structure.match(other.structure); }
|
||||||
std::vector<VkBool32> fields;
|
|
||||||
private:
|
StructureContainer structure;
|
||||||
DeleteProc delete_proc = nullptr;
|
|
||||||
UpdateProc update_proc = nullptr;
|
|
||||||
CopyProc copy_proc = nullptr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
Loading…
Reference in New Issue
Block a user