Identify each unsupported device feature flag that the app attempts to be enable.
- Make MVKDevice::enableFeatures() functions into templates to pass struct type. - Add mvkGetAddressOfFirstMember() to retrieve the address of the first member of a struct, taking into consideration whether the struct has a Vulkan pNext member. - Add mvk::getTypeName() and mvk::getOrdinalSuffix() string functions.
This commit is contained in:
parent
7d4f5745f7
commit
4893f78b29
@ -21,6 +21,8 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <streambuf>
|
#include <streambuf>
|
||||||
|
#include <vector>
|
||||||
|
#include <cxxabi.h>
|
||||||
|
|
||||||
namespace mvk {
|
namespace mvk {
|
||||||
|
|
||||||
@ -59,6 +61,26 @@ namespace mvk {
|
|||||||
return varName;
|
return varName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Returns a string containing the ordinal suffix for a numeric value.*/
|
||||||
|
inline const char* getOrdinalSuffix(int64_t val) {
|
||||||
|
static const char* suffixes[] = {"th", "st", "nd", "rd"};
|
||||||
|
auto ord = val % 100;
|
||||||
|
if (ord > 10 && ord < 20) { return suffixes[0]; } // All teens end in th.
|
||||||
|
ord = ord % 10;
|
||||||
|
if (ord > 3) { return suffixes[0]; } // 4-9 end in th.
|
||||||
|
return suffixes[ord];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the name of a C++ type. */
|
||||||
|
template<typename T>
|
||||||
|
inline std::string getTypeName(const T* pObj) {
|
||||||
|
int status;
|
||||||
|
char* demangledName = abi::__cxa_demangle(typeid(*pObj).name(), 0, 0, &status);
|
||||||
|
std::string tName = demangledName;
|
||||||
|
free(demangledName);
|
||||||
|
return tName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark Streams
|
#pragma mark Streams
|
||||||
|
@ -30,6 +30,7 @@ Released TBD
|
|||||||
- Add `MVK_ENABLE_EXPLICIT_LOD_WORKAROUND` environment variable to selectively
|
- Add `MVK_ENABLE_EXPLICIT_LOD_WORKAROUND` environment variable to selectively
|
||||||
disable recent fixes to handling LOD for arrayed depth images in shaders,
|
disable recent fixes to handling LOD for arrayed depth images in shaders,
|
||||||
on Apple Silicon, when those fixes cause regression in rendering behavior.
|
on Apple Silicon, when those fixes cause regression in rendering behavior.
|
||||||
|
- Identify each unsupported device feature flag that the app attempts to be enable.
|
||||||
- For correctness, set `VkPhysicalDeviceLimits::lineWidthGranularity` to `1`.
|
- For correctness, set `VkPhysicalDeviceLimits::lineWidthGranularity` to `1`.
|
||||||
- Improve GitHub CI production of binary artifacts on submission and release.
|
- Improve GitHub CI production of binary artifacts on submission and release.
|
||||||
|
|
||||||
|
@ -886,8 +886,8 @@ protected:
|
|||||||
void initQueues(const VkDeviceCreateInfo* pCreateInfo);
|
void initQueues(const VkDeviceCreateInfo* pCreateInfo);
|
||||||
void reservePrivateData(const VkDeviceCreateInfo* pCreateInfo);
|
void reservePrivateData(const VkDeviceCreateInfo* pCreateInfo);
|
||||||
void enableFeatures(const VkDeviceCreateInfo* pCreateInfo);
|
void enableFeatures(const VkDeviceCreateInfo* pCreateInfo);
|
||||||
void enableFeatures(VkBaseInStructure* pEnabled, const VkBaseInStructure* pRequested, const VkBaseInStructure* pAvailable, uint32_t count);
|
template<typename S> void enableFeatures(S* pEnabled, const S* pRequested, const S* pAvailable, uint32_t count);
|
||||||
void enableFeatures(VkBool32* pEnabledBools, const VkBool32* pRequestedBools, const VkBool32* pAvailableBools, uint32_t count);
|
template<typename S> void enableFeatures(S* pRequested, VkBool32* pEnabledBools, const VkBool32* pRequestedBools, const VkBool32* pAvailableBools, uint32_t count);
|
||||||
void enableExtensions(const VkDeviceCreateInfo* pCreateInfo);
|
void enableExtensions(const VkDeviceCreateInfo* pCreateInfo);
|
||||||
const char* getActivityPerformanceDescription(MVKPerformanceTracker& activity, MVKPerformanceStatistics& perfStats);
|
const char* getActivityPerformanceDescription(MVKPerformanceTracker& activity, MVKPerformanceStatistics& perfStats);
|
||||||
void logActivityPerformance(MVKPerformanceTracker& activity, MVKPerformanceStatistics& perfStats, bool isInline = false);
|
void logActivityPerformance(MVKPerformanceTracker& activity, MVKPerformanceStatistics& perfStats, bool isInline = false);
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include "MVKCommandPool.h"
|
#include "MVKCommandPool.h"
|
||||||
#include "MVKFoundation.h"
|
#include "MVKFoundation.h"
|
||||||
#include "MVKCodec.h"
|
#include "MVKCodec.h"
|
||||||
|
#include "MVKStrings.h"
|
||||||
#include <MoltenVKShaderConverter/SPIRVToMSLConverter.h>
|
#include <MoltenVKShaderConverter/SPIRVToMSLConverter.h>
|
||||||
|
|
||||||
#import "CAMetalLayer+MoltenVK.h"
|
#import "CAMetalLayer+MoltenVK.h"
|
||||||
@ -4590,7 +4591,8 @@ void MVKDevice::enableFeatures(const VkDeviceCreateInfo* pCreateInfo) {
|
|||||||
//Enable device features based on requested and available features,
|
//Enable device features based on requested and available features,
|
||||||
// including extended features that are requested in the pNext chain.
|
// including extended features that are requested in the pNext chain.
|
||||||
if (pCreateInfo->pEnabledFeatures) {
|
if (pCreateInfo->pEnabledFeatures) {
|
||||||
enableFeatures(&_enabledFeatures.robustBufferAccess,
|
enableFeatures(pCreateInfo->pEnabledFeatures,
|
||||||
|
&_enabledFeatures.robustBufferAccess,
|
||||||
&pCreateInfo->pEnabledFeatures->robustBufferAccess,
|
&pCreateInfo->pEnabledFeatures->robustBufferAccess,
|
||||||
&pdFeats2.features.robustBufferAccess, 55);
|
&pdFeats2.features.robustBufferAccess, 55);
|
||||||
}
|
}
|
||||||
@ -4599,29 +4601,36 @@ void MVKDevice::enableFeatures(const VkDeviceCreateInfo* pCreateInfo) {
|
|||||||
switch ((uint32_t)next->sType) {
|
switch ((uint32_t)next->sType) {
|
||||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2: {
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2: {
|
||||||
auto* requestedFeatures = (VkPhysicalDeviceFeatures2*)next;
|
auto* requestedFeatures = (VkPhysicalDeviceFeatures2*)next;
|
||||||
enableFeatures(&_enabledFeatures.robustBufferAccess,
|
enableFeatures(requestedFeatures,
|
||||||
|
&_enabledFeatures.robustBufferAccess,
|
||||||
&requestedFeatures->features.robustBufferAccess,
|
&requestedFeatures->features.robustBufferAccess,
|
||||||
&pdFeats2.features.robustBufferAccess, 55);
|
&pdFeats2.features.robustBufferAccess, 55);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES: {
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES: {
|
||||||
auto* requestedFeatures = (VkPhysicalDeviceVulkan11Features*)next;
|
auto* requestedFeatures = (VkPhysicalDeviceVulkan11Features*)next;
|
||||||
enableFeatures(&_enabled16BitStorageFeatures.storageBuffer16BitAccess,
|
enableFeatures(requestedFeatures,
|
||||||
|
&_enabled16BitStorageFeatures.storageBuffer16BitAccess,
|
||||||
&requestedFeatures->storageBuffer16BitAccess,
|
&requestedFeatures->storageBuffer16BitAccess,
|
||||||
&pd16BitStorageFeatures.storageBuffer16BitAccess, 4);
|
&pd16BitStorageFeatures.storageBuffer16BitAccess, 4);
|
||||||
enableFeatures(&_enabledMultiviewFeatures.multiview,
|
enableFeatures(requestedFeatures,
|
||||||
|
&_enabledMultiviewFeatures.multiview,
|
||||||
&requestedFeatures->multiview,
|
&requestedFeatures->multiview,
|
||||||
&pdMultiviewFeatures.multiview, 3);
|
&pdMultiviewFeatures.multiview, 3);
|
||||||
enableFeatures(&_enabledVariablePointerFeatures.variablePointersStorageBuffer,
|
enableFeatures(requestedFeatures,
|
||||||
|
&_enabledVariablePointerFeatures.variablePointersStorageBuffer,
|
||||||
&requestedFeatures->variablePointersStorageBuffer,
|
&requestedFeatures->variablePointersStorageBuffer,
|
||||||
&pdVariablePointerFeatures.variablePointersStorageBuffer, 2);
|
&pdVariablePointerFeatures.variablePointersStorageBuffer, 2);
|
||||||
enableFeatures(&_enabledProtectedMemoryFeatures.protectedMemory,
|
enableFeatures(requestedFeatures,
|
||||||
|
&_enabledProtectedMemoryFeatures.protectedMemory,
|
||||||
&requestedFeatures->protectedMemory,
|
&requestedFeatures->protectedMemory,
|
||||||
&pdProtectedMemoryFeatures.protectedMemory, 1);
|
&pdProtectedMemoryFeatures.protectedMemory, 1);
|
||||||
enableFeatures(&_enabledSamplerYcbcrConversionFeatures.samplerYcbcrConversion,
|
enableFeatures(requestedFeatures,
|
||||||
|
&_enabledSamplerYcbcrConversionFeatures.samplerYcbcrConversion,
|
||||||
&requestedFeatures->samplerYcbcrConversion,
|
&requestedFeatures->samplerYcbcrConversion,
|
||||||
&pdSamplerYcbcrConversionFeatures.samplerYcbcrConversion, 1);
|
&pdSamplerYcbcrConversionFeatures.samplerYcbcrConversion, 1);
|
||||||
enableFeatures(&_enabledShaderDrawParametersFeatures.shaderDrawParameters,
|
enableFeatures(requestedFeatures,
|
||||||
|
&_enabledShaderDrawParametersFeatures.shaderDrawParameters,
|
||||||
&requestedFeatures->shaderDrawParameters,
|
&requestedFeatures->shaderDrawParameters,
|
||||||
&pdShaderDrawParametersFeatures.shaderDrawParameters, 1);
|
&pdShaderDrawParametersFeatures.shaderDrawParameters, 1);
|
||||||
break;
|
break;
|
||||||
@ -4629,55 +4638,72 @@ void MVKDevice::enableFeatures(const VkDeviceCreateInfo* pCreateInfo) {
|
|||||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES: {
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES: {
|
||||||
auto& pdvulkan12FeaturesNoExt = _physicalDevice->_vulkan12FeaturesNoExt;
|
auto& pdvulkan12FeaturesNoExt = _physicalDevice->_vulkan12FeaturesNoExt;
|
||||||
auto* requestedFeatures = (VkPhysicalDeviceVulkan12Features*)next;
|
auto* requestedFeatures = (VkPhysicalDeviceVulkan12Features*)next;
|
||||||
enableFeatures(&_enabledVulkan12FeaturesNoExt.samplerMirrorClampToEdge,
|
enableFeatures(requestedFeatures,
|
||||||
|
&_enabledVulkan12FeaturesNoExt.samplerMirrorClampToEdge,
|
||||||
&requestedFeatures->samplerMirrorClampToEdge,
|
&requestedFeatures->samplerMirrorClampToEdge,
|
||||||
&pdvulkan12FeaturesNoExt.samplerMirrorClampToEdge, 2);
|
&pdvulkan12FeaturesNoExt.samplerMirrorClampToEdge, 2);
|
||||||
enableFeatures(&_enabled8BitStorageFeatures.storageBuffer8BitAccess,
|
enableFeatures(requestedFeatures,
|
||||||
|
&_enabled8BitStorageFeatures.storageBuffer8BitAccess,
|
||||||
&requestedFeatures->storageBuffer8BitAccess,
|
&requestedFeatures->storageBuffer8BitAccess,
|
||||||
&pd8BitStorageFeatures.storageBuffer8BitAccess, 3);
|
&pd8BitStorageFeatures.storageBuffer8BitAccess, 3);
|
||||||
enableFeatures(&_enabledShaderAtomicInt64Features.shaderBufferInt64Atomics,
|
enableFeatures(requestedFeatures,
|
||||||
|
&_enabledShaderAtomicInt64Features.shaderBufferInt64Atomics,
|
||||||
&requestedFeatures->shaderBufferInt64Atomics,
|
&requestedFeatures->shaderBufferInt64Atomics,
|
||||||
&pdShaderAtomicInt64Features.shaderBufferInt64Atomics, 2);
|
&pdShaderAtomicInt64Features.shaderBufferInt64Atomics, 2);
|
||||||
enableFeatures(&_enabledShaderFloat16Int8Features.shaderFloat16,
|
enableFeatures(requestedFeatures,
|
||||||
|
&_enabledShaderFloat16Int8Features.shaderFloat16,
|
||||||
&requestedFeatures->shaderFloat16,
|
&requestedFeatures->shaderFloat16,
|
||||||
&pdShaderFloat16Int8Features.shaderFloat16, 2);
|
&pdShaderFloat16Int8Features.shaderFloat16, 2);
|
||||||
enableFeatures(&_enabledVulkan12FeaturesNoExt.descriptorIndexing,
|
enableFeatures(requestedFeatures,
|
||||||
|
&_enabledVulkan12FeaturesNoExt.descriptorIndexing,
|
||||||
&requestedFeatures->descriptorIndexing,
|
&requestedFeatures->descriptorIndexing,
|
||||||
&pdvulkan12FeaturesNoExt.descriptorIndexing, 1);
|
&pdvulkan12FeaturesNoExt.descriptorIndexing, 1);
|
||||||
enableFeatures(&_enabledDescriptorIndexingFeatures.shaderInputAttachmentArrayDynamicIndexing,
|
enableFeatures(requestedFeatures,
|
||||||
|
&_enabledDescriptorIndexingFeatures.shaderInputAttachmentArrayDynamicIndexing,
|
||||||
&requestedFeatures->shaderInputAttachmentArrayDynamicIndexing,
|
&requestedFeatures->shaderInputAttachmentArrayDynamicIndexing,
|
||||||
&pdDescriptorIndexingFeatures.shaderInputAttachmentArrayDynamicIndexing, 20);
|
&pdDescriptorIndexingFeatures.shaderInputAttachmentArrayDynamicIndexing, 20);
|
||||||
enableFeatures(&_enabledVulkan12FeaturesNoExt.samplerFilterMinmax,
|
enableFeatures(requestedFeatures,
|
||||||
|
&_enabledVulkan12FeaturesNoExt.samplerFilterMinmax,
|
||||||
&requestedFeatures->samplerFilterMinmax,
|
&requestedFeatures->samplerFilterMinmax,
|
||||||
&pdvulkan12FeaturesNoExt.samplerFilterMinmax, 1);
|
&pdvulkan12FeaturesNoExt.samplerFilterMinmax, 1);
|
||||||
enableFeatures(&_enabledScalarBlockLayoutFeatures.scalarBlockLayout,
|
enableFeatures(requestedFeatures,
|
||||||
|
&_enabledScalarBlockLayoutFeatures.scalarBlockLayout,
|
||||||
&requestedFeatures->scalarBlockLayout,
|
&requestedFeatures->scalarBlockLayout,
|
||||||
&pdScalarBlockLayoutFeatures.scalarBlockLayout, 1);
|
&pdScalarBlockLayoutFeatures.scalarBlockLayout, 1);
|
||||||
enableFeatures(&_enabledImagelessFramebufferFeatures.imagelessFramebuffer,
|
enableFeatures(requestedFeatures,
|
||||||
|
&_enabledImagelessFramebufferFeatures.imagelessFramebuffer,
|
||||||
&requestedFeatures->imagelessFramebuffer,
|
&requestedFeatures->imagelessFramebuffer,
|
||||||
&pdImagelessFramebufferFeatures.imagelessFramebuffer, 1);
|
&pdImagelessFramebufferFeatures.imagelessFramebuffer, 1);
|
||||||
enableFeatures(&_enabledUniformBufferStandardLayoutFeatures.uniformBufferStandardLayout,
|
enableFeatures(requestedFeatures,
|
||||||
|
&_enabledUniformBufferStandardLayoutFeatures.uniformBufferStandardLayout,
|
||||||
&requestedFeatures->uniformBufferStandardLayout,
|
&requestedFeatures->uniformBufferStandardLayout,
|
||||||
&pdUniformBufferStandardLayoutFeatures.uniformBufferStandardLayout, 1);
|
&pdUniformBufferStandardLayoutFeatures.uniformBufferStandardLayout, 1);
|
||||||
enableFeatures(&_enabledShaderSubgroupExtendedTypesFeatures.shaderSubgroupExtendedTypes,
|
enableFeatures(requestedFeatures,
|
||||||
|
&_enabledShaderSubgroupExtendedTypesFeatures.shaderSubgroupExtendedTypes,
|
||||||
&requestedFeatures->shaderSubgroupExtendedTypes,
|
&requestedFeatures->shaderSubgroupExtendedTypes,
|
||||||
&pdShaderSubgroupExtendedTypesFeatures.shaderSubgroupExtendedTypes, 1);
|
&pdShaderSubgroupExtendedTypesFeatures.shaderSubgroupExtendedTypes, 1);
|
||||||
enableFeatures(&_enabledSeparateDepthStencilLayoutsFeatures.separateDepthStencilLayouts,
|
enableFeatures(requestedFeatures,
|
||||||
|
&_enabledSeparateDepthStencilLayoutsFeatures.separateDepthStencilLayouts,
|
||||||
&requestedFeatures->separateDepthStencilLayouts,
|
&requestedFeatures->separateDepthStencilLayouts,
|
||||||
&pdSeparateDepthStencilLayoutsFeatures.separateDepthStencilLayouts, 1);
|
&pdSeparateDepthStencilLayoutsFeatures.separateDepthStencilLayouts, 1);
|
||||||
enableFeatures(&_enabledHostQueryResetFeatures.hostQueryReset,
|
enableFeatures(requestedFeatures,
|
||||||
|
&_enabledHostQueryResetFeatures.hostQueryReset,
|
||||||
&requestedFeatures->hostQueryReset,
|
&requestedFeatures->hostQueryReset,
|
||||||
&pdHostQueryResetFeatures.hostQueryReset, 1);
|
&pdHostQueryResetFeatures.hostQueryReset, 1);
|
||||||
enableFeatures(&_enabledTimelineSemaphoreFeatures.timelineSemaphore,
|
enableFeatures(requestedFeatures,
|
||||||
|
&_enabledTimelineSemaphoreFeatures.timelineSemaphore,
|
||||||
&requestedFeatures->timelineSemaphore,
|
&requestedFeatures->timelineSemaphore,
|
||||||
&pdTimelineSemaphoreFeatures.timelineSemaphore, 1);
|
&pdTimelineSemaphoreFeatures.timelineSemaphore, 1);
|
||||||
enableFeatures(&_enabledBufferDeviceAddressFeatures.bufferDeviceAddress,
|
enableFeatures(requestedFeatures,
|
||||||
|
&_enabledBufferDeviceAddressFeatures.bufferDeviceAddress,
|
||||||
&requestedFeatures->bufferDeviceAddress,
|
&requestedFeatures->bufferDeviceAddress,
|
||||||
&pdBufferDeviceAddressFeatures.bufferDeviceAddress, 3);
|
&pdBufferDeviceAddressFeatures.bufferDeviceAddress, 3);
|
||||||
enableFeatures(&_enabledVulkanMemoryModelFeatures.vulkanMemoryModel,
|
enableFeatures(requestedFeatures,
|
||||||
|
&_enabledVulkanMemoryModelFeatures.vulkanMemoryModel,
|
||||||
&requestedFeatures->vulkanMemoryModel,
|
&requestedFeatures->vulkanMemoryModel,
|
||||||
&pdVulkanMemoryModelFeatures.vulkanMemoryModel, 3);
|
&pdVulkanMemoryModelFeatures.vulkanMemoryModel, 3);
|
||||||
enableFeatures(&_enabledVulkan12FeaturesNoExt.shaderOutputViewportIndex,
|
enableFeatures(requestedFeatures,
|
||||||
|
&_enabledVulkan12FeaturesNoExt.shaderOutputViewportIndex,
|
||||||
&requestedFeatures->shaderOutputViewportIndex,
|
&requestedFeatures->shaderOutputViewportIndex,
|
||||||
&pdvulkan12FeaturesNoExt.shaderOutputViewportIndex, 3);
|
&pdvulkan12FeaturesNoExt.shaderOutputViewportIndex, 3);
|
||||||
break;
|
break;
|
||||||
@ -4685,17 +4711,17 @@ void MVKDevice::enableFeatures(const VkDeviceCreateInfo* pCreateInfo) {
|
|||||||
|
|
||||||
#define MVK_DEVICE_FEATURE(structName, enumName, flagCount) \
|
#define MVK_DEVICE_FEATURE(structName, enumName, flagCount) \
|
||||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_##enumName##_FEATURES: { \
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_##enumName##_FEATURES: { \
|
||||||
enableFeatures((VkBaseInStructure*)&_enabled##structName##Features, \
|
enableFeatures(&_enabled##structName##Features, \
|
||||||
next, \
|
(VkPhysicalDevice##structName##Features*)next, \
|
||||||
(VkBaseInStructure*)&pd##structName##Features, \
|
&pd##structName##Features, \
|
||||||
flagCount); \
|
flagCount); \
|
||||||
break; \
|
break; \
|
||||||
}
|
}
|
||||||
#define MVK_DEVICE_FEATURE_EXTN(structName, enumName, extnSfx, flagCount) \
|
#define MVK_DEVICE_FEATURE_EXTN(structName, enumName, extnSfx, flagCount) \
|
||||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_##enumName##_FEATURES_##extnSfx: { \
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_##enumName##_FEATURES_##extnSfx: { \
|
||||||
enableFeatures((VkBaseInStructure*)&_enabled##structName##Features, \
|
enableFeatures(&_enabled##structName##Features, \
|
||||||
next, \
|
(VkPhysicalDevice##structName##Features##extnSfx*)next, \
|
||||||
(VkBaseInStructure*)&pd##structName##Features, \
|
&pd##structName##Features, \
|
||||||
flagCount); \
|
flagCount); \
|
||||||
break; \
|
break; \
|
||||||
}
|
}
|
||||||
@ -4707,18 +4733,23 @@ void MVKDevice::enableFeatures(const VkDeviceCreateInfo* pCreateInfo) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MVKDevice::enableFeatures(VkBaseInStructure* pEnabled, const VkBaseInStructure* pRequested, const VkBaseInStructure* pAvailable, uint32_t count) {
|
template<typename S>
|
||||||
enableFeatures((VkBool32*)(&(pEnabled->pNext) + 1),
|
void MVKDevice::enableFeatures(S* pEnabled, const S* pRequested, const S* pAvailable, uint32_t count) {
|
||||||
(VkBool32*)(&(pRequested->pNext) + 1),
|
enableFeatures(pRequested,
|
||||||
(VkBool32*)(&(pAvailable->pNext) + 1),
|
(VkBool32*)mvkGetAddressOfFirstMember(pEnabled),
|
||||||
|
(VkBool32*)mvkGetAddressOfFirstMember(pRequested),
|
||||||
|
(VkBool32*)mvkGetAddressOfFirstMember(pAvailable),
|
||||||
count);
|
count);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MVKDevice::enableFeatures(VkBool32* pEnabledBools, const VkBool32* pRequestedBools, const VkBool32* pAvailableBools, uint32_t count) {
|
template<typename S>
|
||||||
|
void MVKDevice::enableFeatures(S* pRequested, VkBool32* pEnabledBools, const VkBool32* pRequestedBools, const VkBool32* pAvailableBools, uint32_t count) {
|
||||||
for (uint32_t i = 0; i < count; i++) {
|
for (uint32_t i = 0; i < count; i++) {
|
||||||
pEnabledBools[i] = pRequestedBools[i] && pAvailableBools[i];
|
pEnabledBools[i] = pRequestedBools[i] && pAvailableBools[i];
|
||||||
if (pRequestedBools[i] && !pAvailableBools[i]) {
|
if (pRequestedBools[i] && !pAvailableBools[i]) {
|
||||||
setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateDevice(): Requested feature is not available on this device."));
|
uintptr_t mbrOffset = (uintptr_t)&pRequestedBools[i] - (uintptr_t)mvkGetAddressOfFirstMember(pRequested);
|
||||||
|
size_t mbrIdxOrd = (mbrOffset / sizeof(VkBool32)) + 1;
|
||||||
|
setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateDevice(): Requested physical device feature specified by the %zu%s flag in %s is not available on this device.", mbrIdxOrd, mvk::getOrdinalSuffix(mbrIdxOrd), mvk::getTypeName(pRequested).c_str()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
#include "MVKInstance.h"
|
#include "MVKInstance.h"
|
||||||
#include "MVKFoundation.h"
|
#include "MVKFoundation.h"
|
||||||
#include "MVKOSExtensions.h"
|
#include "MVKOSExtensions.h"
|
||||||
#include <cxxabi.h>
|
#include "MVKStrings.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -44,13 +44,7 @@ static const char* getReportingLevelString(MVKConfigLogLevel logLevel) {
|
|||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark MVKBaseObject
|
#pragma mark MVKBaseObject
|
||||||
|
|
||||||
string MVKBaseObject::getClassName() {
|
string MVKBaseObject::getClassName() { return mvk::getTypeName(this); }
|
||||||
int status;
|
|
||||||
char* demangled = abi::__cxa_demangle(typeid(*this).name(), 0, 0, &status);
|
|
||||||
string clzName = demangled;
|
|
||||||
free(demangled);
|
|
||||||
return clzName;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MVKBaseObject::reportMessage(MVKConfigLogLevel logLevel, const char* format, ...) {
|
void MVKBaseObject::reportMessage(MVKConfigLogLevel logLevel, const char* format, ...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
|
@ -217,6 +217,44 @@ static constexpr uint64_t mvkAlignByteCount(uint64_t byteCount, uint64_t byteAli
|
|||||||
return mvkAlignByteRef(byteCount, byteAlignment, alignDown);
|
return mvkAlignByteRef(byteCount, byteAlignment, alignDown);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compile time indication if the struct contains a specific member.
|
||||||
|
*
|
||||||
|
* If S::mbr is well-formed because the struct contains that member, the decltype() and
|
||||||
|
* comma operator together trigger a true_type, otherwise it falls back to a false_type.
|
||||||
|
*
|
||||||
|
* Credit to: https://fekir.info/post/detect-member-variables/
|
||||||
|
*/
|
||||||
|
#define mvk_define_has_member(mbr) \
|
||||||
|
template <typename T, typename = void> struct mvk_has_##mbr : std::false_type {}; \
|
||||||
|
template <typename T> struct mvk_has_##mbr<T, decltype((void)T::mbr, void())> : std::true_type {};
|
||||||
|
|
||||||
|
mvk_define_has_member(pNext); // Defines the mvk_has_pNext() function.
|
||||||
|
|
||||||
|
/** Returns the address of the first member of a structure, which is just the address of the structure. */
|
||||||
|
template <typename S>
|
||||||
|
void* mvkGetAddressOfFirstMember(const S* pStruct, std::false_type){
|
||||||
|
return (void*)pStruct;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the address of the first member of a Vulkan structure containing a pNext member.
|
||||||
|
* The first member is the one after the pNext member.
|
||||||
|
*/
|
||||||
|
template <class S>
|
||||||
|
void* mvkGetAddressOfFirstMember(const S* pStruct, std::true_type){
|
||||||
|
return (void*)(&(pStruct->pNext) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the address of the first member of a structure. If the structure is a Vulkan
|
||||||
|
* structure containing a pNext member, the first member is the one after the pNext member.
|
||||||
|
*/
|
||||||
|
template <class S>
|
||||||
|
void* mvkGetAddressOfFirstMember(const S* pStruct){
|
||||||
|
return mvkGetAddressOfFirstMember(pStruct, mvk_has_pNext<S>{});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reverses the order of the rows in the specified data block.
|
* Reverses the order of the rows in the specified data block.
|
||||||
* The transformation is performed in-place.
|
* The transformation is performed in-place.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user