Files
strato/app/src/main/cpp/skyline/gpu/quirk_manager.cpp
PixelyIon 31c4f1ca4e Unlink VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT when disabled
When `VK_EXT_vertex_attribute_divisor` is not available, `VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT` is unlinked from the device enabled feature list as it is undefined behavior to link a structure provided by an extension without enabling that extension.
2022-04-14 14:14:52 +05:30

59 lines
3.5 KiB
C++

// SPDX-License-Identifier: MPL-2.0
// Copyright © 2021 Skyline Team and Contributors (https://github.com/skyline-emu/)
#include "quirk_manager.h"
namespace skyline::gpu {
QuirkManager::QuirkManager(const vk::PhysicalDeviceProperties &properties, const DeviceFeatures2 &deviceFeatures2, DeviceFeatures2 &enabledFeatures2, const std::vector<vk::ExtensionProperties> &deviceExtensions, std::vector<std::array<char, VK_MAX_EXTENSION_NAME_SIZE>> &enabledExtensions) {
for (auto &extension : deviceExtensions) {
#define EXT_SET(name, property) \
case util::Hash(name): \
if (name == extensionName) { \
property = true; \
enabledExtensions.push_back(std::array<char, VK_MAX_EXTENSION_NAME_SIZE>{name}); \
} \
break
#define EXT_SET_V(name, property, version) \
case util::Hash(name): \
if (name == extensionName && extensionVersion >= version) { \
property = true; \
enabledExtensions.push_back(std::array<char, VK_MAX_EXTENSION_NAME_SIZE>{name}); \
} \
break
std::string_view extensionName{extension.extensionName};
auto extensionVersion{extension.specVersion};
switch (util::Hash(extensionName)) {
EXT_SET("VK_EXT_provoking_vertex", supportsLastProvokingVertex);
EXT_SET("VK_EXT_vertex_attribute_divisor", supportsVertexAttributeDivisor);
}
#undef EXT_SET
#undef EXT_SET_V
}
#define FEAT_SET(structName, feature, property) \
if (deviceFeatures2.get<structName>().feature) { \
property = true; \
enabledFeatures2.get<structName>().feature = true; \
}
FEAT_SET(vk::PhysicalDeviceFeatures2, features.logicOp, supportsLogicOp)
FEAT_SET(vk::PhysicalDeviceFeatures2, features.multiViewport, supportsMultipleViewports)
if (supportsVertexAttributeDivisor) {
FEAT_SET(vk::PhysicalDeviceVertexAttributeDivisorFeaturesEXT, vertexAttributeInstanceRateDivisor, supportsVertexAttributeDivisor)
FEAT_SET(vk::PhysicalDeviceVertexAttributeDivisorFeaturesEXT, vertexAttributeInstanceRateZeroDivisor, supportsVertexAttributeZeroDivisor)
} else {
enabledFeatures2.unlink<vk::PhysicalDeviceVertexAttributeDivisorFeaturesEXT>();
}
#undef FEAT_SET
}
std::string QuirkManager::Summary() {
return fmt::format("\n* Supports Last Provoking Vertex: {}\n* Supports Logical Operations: {}\n* Supports Vertex Attribute Divisor: {}\n* Supports Vertex Attribute Zero Divisor: {}\n* Supports Multiple Viewports: {}", supportsLastProvokingVertex, supportsLogicOp, supportsVertexAttributeDivisor, supportsVertexAttributeZeroDivisor, supportsMultipleViewports);
}
}