From e897f49185eff0cb0180c55213283b50878144cc Mon Sep 17 00:00:00 2001 From: Bill Hollings Date: Tue, 14 Feb 2023 15:36:43 -0500 Subject: [PATCH] Fixes to recent update, to suit building on older Xcode versions. - Revert mvkRoundHalfToEven() to static inline instead of constexpr, because internal use of std::remainder() is not constexpr until C++23. - Replace non-template constexpr functions with static constexpr. - Update Github CI to default to use Xcode 14.2, and macos-latest (which is now macos-12). --- .github/workflows/CI.yml | 4 +- .../Commands/MVKCommandEncodingPool.mm | 2 +- MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.h | 2 +- MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm | 2 +- MoltenVK/MoltenVK/Utility/MVKFoundation.h | 40 +++++++++---------- 5 files changed, 25 insertions(+), 25 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index e7d9de8a..cb792195 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -15,9 +15,9 @@ jobs: build: strategy: matrix: - xcode: [ "14.1" ] + xcode: [ "14.2" ] platform: [ "macos", "maccat", "ios", "tvos" ] - os: [ "macos-12" ] + os: [ "macos-latest" ] upload_artifacts: [ true ] # additional specific configurations include: diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandEncodingPool.mm b/MoltenVK/MoltenVK/Commands/MVKCommandEncodingPool.mm index d861422b..1d8c893d 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandEncodingPool.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCommandEncodingPool.mm @@ -109,7 +109,7 @@ id MVKCommandEncodingPool::getCmdFillBufferMTLComputePi MVK_ENC_REZ_ACCESS(_mtlFillBufferComputePipelineState, newCmdFillBufferMTLComputePipelineState(_commandPool)); } -constexpr uint32_t getRenderpassLoadStoreStateIndex(MVKFormatType type) { +static constexpr uint32_t getRenderpassLoadStoreStateIndex(MVKFormatType type) { switch (type) { case kMVKFormatColorHalf: case kMVKFormatColorFloat: diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.h b/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.h index 414e33a5..25552b13 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.h @@ -314,7 +314,7 @@ uint32_t mvkGetAttachments(const VkRenderingInfo* pRenderingInfo, VkClearValue clearValues[]); /** Returns whether the view mask uses multiview. */ -constexpr bool mvkIsMultiview(uint32_t viewMask) { return viewMask != 0; } +static constexpr bool mvkIsMultiview(uint32_t viewMask) { return viewMask != 0; } /** Returns whether the attachment is being used. */ bool mvkIsColorAttachmentUsed(const VkPipelineRenderingCreateInfo* pRendInfo, uint32_t colorAttIdx); diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm b/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm index 1c0702af..53aba660 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm @@ -188,7 +188,7 @@ struct CIE1931XY { // According to D.3.28: // "[x and y] specify the normalized x and y chromaticity coordinates, respectively... // in normalized increments of 0.00002." -constexpr uint16_t FloatToCIE1931Unorm(float x) { return OSSwapHostToBigInt16((uint16_t)(x * 100000 / 2)); } +static constexpr uint16_t FloatToCIE1931Unorm(float x) { return OSSwapHostToBigInt16((uint16_t)(x * 100000 / 2)); } static inline CIE1931XY VkXYColorEXTToCIE1931XY(VkXYColorEXT xy) { return { FloatToCIE1931Unorm(xy.x), FloatToCIE1931Unorm(xy.y) }; } diff --git a/MoltenVK/MoltenVK/Utility/MVKFoundation.h b/MoltenVK/MoltenVK/Utility/MVKFoundation.h index cbaaf685..3d123376 100644 --- a/MoltenVK/MoltenVK/Utility/MVKFoundation.h +++ b/MoltenVK/MoltenVK/Utility/MVKFoundation.h @@ -137,7 +137,7 @@ static inline std::string mvkGetMoltenVKVersionString(uint32_t mvkVersion) { /** Returns whether the specified positive value is a power-of-two. */ template -constexpr bool mvkIsPowerOfTwo(T value) { +static constexpr bool mvkIsPowerOfTwo(T value) { return value && ((value & (value - 1)) == 0); } @@ -147,7 +147,7 @@ constexpr bool mvkIsPowerOfTwo(T value) { * that is larger than the specified value is returned. */ template -constexpr T mvkEnsurePowerOfTwo(T value) { +static constexpr T mvkEnsurePowerOfTwo(T value) { if (mvkIsPowerOfTwo(value)) { return value; } T pot = 1; @@ -162,7 +162,7 @@ constexpr T mvkEnsurePowerOfTwo(T value) { * This implementation returns zero for both zero and one as inputs. */ template -constexpr T mvkPowerOfTwoExponent(T value) { +static constexpr T mvkPowerOfTwoExponent(T value) { T p2Value = mvkEnsurePowerOfTwo(value); // Count the trailing zeros @@ -183,7 +183,7 @@ constexpr T mvkPowerOfTwoExponent(T value) { * This is a low level utility method. Usually you will use the convenience functions * mvkAlignAddress() and mvkAlignByteCount() to align addresses and offsets respectively. */ -constexpr uintptr_t mvkAlignByteRef(uintptr_t byteRef, uintptr_t byteAlignment, bool alignDown = false) { +static constexpr uintptr_t mvkAlignByteRef(uintptr_t byteRef, uintptr_t byteAlignment, bool alignDown = false) { if (byteAlignment == 0) { return byteRef; } assert(mvkIsPowerOfTwo(byteAlignment)); @@ -212,7 +212,7 @@ static inline void* mvkAlignAddress(void* address, uintptr_t byteAlignment, bool * which will be greater than or equal to the original offset if alignDown is false, or less * than or equal to the original offset if alignDown is true. */ -constexpr uint64_t mvkAlignByteCount(uint64_t byteCount, uint64_t byteAlignment, bool alignDown = false) { +static constexpr uint64_t mvkAlignByteCount(uint64_t byteCount, uint64_t byteAlignment, bool alignDown = false) { return mvkAlignByteRef(byteCount, byteAlignment, alignDown); } @@ -253,22 +253,22 @@ static inline VkExtent2D mvkVkExtent2DFromVkExtent3D(VkExtent3D e) { return {e.w static inline VkExtent3D mvkVkExtent3DFromVkExtent2D(VkExtent2D e) { return {e.width, e.height, 1U }; } /** Returns whether the two Vulkan extents are equal by comparing their respective components. */ -constexpr bool mvkVkExtent2DsAreEqual(VkExtent2D e1, VkExtent2D e2) { +static constexpr bool mvkVkExtent2DsAreEqual(VkExtent2D e1, VkExtent2D e2) { return (e1.width == e2.width) && (e1.height == e2.height); } /** Returns whether the two Vulkan extents are equal by comparing their respective components. */ -constexpr bool mvkVkExtent3DsAreEqual(VkExtent3D e1, VkExtent3D e2) { +static constexpr bool mvkVkExtent3DsAreEqual(VkExtent3D e1, VkExtent3D e2) { return (e1.width == e2.width) && (e1.height == e2.height) && (e1.depth == e2.depth); } /** Returns whether the two Vulkan offsets are equal by comparing their respective components. */ -constexpr bool mvkVkOffset2DsAreEqual(VkOffset2D os1, VkOffset2D os2) { +static constexpr bool mvkVkOffset2DsAreEqual(VkOffset2D os1, VkOffset2D os2) { return (os1.x == os2.x) && (os1.y == os2.y); } /** Returns whether the two Vulkan offsets are equal by comparing their respective components. */ -constexpr bool mvkVkOffset3DsAreEqual(VkOffset3D os1, VkOffset3D os2) { +static constexpr bool mvkVkOffset3DsAreEqual(VkOffset3D os1, VkOffset3D os2) { return (os1.x == os2.x) && (os1.y == os2.y) && (os1.z == os2.z); } @@ -285,7 +285,7 @@ static inline VkOffset3D mvkVkOffset3DDifference(VkOffset3D minuend, VkOffset3D } /** Packs the four swizzle components into a single 32-bit word. */ -constexpr uint32_t mvkPackSwizzle(VkComponentMapping components) { +static constexpr uint32_t mvkPackSwizzle(VkComponentMapping components) { return (((components.r & 0xFF) << 0) | ((components.g & 0xFF) << 8) | ((components.b & 0xFF) << 16) | ((components.a & 0xFF) << 24)); } @@ -310,7 +310,7 @@ static inline VkComponentMapping mvkUnpackSwizzle(uint32_t packed) { * 3) Either cs1 or cs2 is VK_COMPONENT_SWIZZLE_MAX_ENUM, which is considered a wildcard, * and matches any value. */ -constexpr bool mvkVKComponentSwizzlesMatch(VkComponentSwizzle cs1, +static constexpr bool mvkVKComponentSwizzlesMatch(VkComponentSwizzle cs1, VkComponentSwizzle cs2, VkComponentSwizzle csPos) { return ((cs1 == cs2) || @@ -327,7 +327,7 @@ constexpr bool mvkVKComponentSwizzlesMatch(VkComponentSwizzle cs1, * A component value of VK_COMPONENT_SWIZZLE_MAX_ENUM is considered a wildcard and matches * any value in the corresponding component in the other mapping. */ -constexpr bool mvkVkComponentMappingsMatch(VkComponentMapping cm1, VkComponentMapping cm2) { +static constexpr bool mvkVkComponentMappingsMatch(VkComponentMapping cm1, VkComponentMapping cm2) { return (mvkVKComponentSwizzlesMatch(cm1.r, cm2.r, VK_COMPONENT_SWIZZLE_R) && mvkVKComponentSwizzlesMatch(cm1.g, cm2.g, VK_COMPONENT_SWIZZLE_G) && mvkVKComponentSwizzlesMatch(cm1.b, cm2.b, VK_COMPONENT_SWIZZLE_B) && @@ -341,8 +341,8 @@ constexpr bool mvkVkComponentMappingsMatch(VkComponentMapping cm1, VkComponentMa #pragma mark Math /** Rounds the value to nearest integer using half-to-even rounding. */ -constexpr double mvkRoundHalfToEven(const double val) { - return val - std::remainder(val, 1.0); // remainder() uses half-to-even rounding +static inline double mvkRoundHalfToEven(const double val) { + return val - std::remainder(val, 1.0); // remainder() uses half-to-even rounding, and unfortunately isn't constexpr until C++23. } /** Returns whether the value will fit inside the numeric type. */ @@ -555,7 +555,7 @@ bool mvkAreEqual(const T* pV1, const T* pV2, size_t count = 1) { * otherwise returns false. This functionality is different than the char version of mvkAreEqual(), * which works on individual chars or char arrays, not strings. */ -constexpr bool mvkStringsAreEqual(const char* pV1, const char* pV2, size_t count = 1) { +static constexpr bool mvkStringsAreEqual(const char* pV1, const char* pV2, size_t count = 1) { return (pV1 && pV2) ? (strcmp(pV1, pV2) == 0) : false; } @@ -572,7 +572,7 @@ constexpr bool mvkStringsAreEqual(const char* pV1, const char* pV2, size_t count * If the destination pointer is NULL, does nothing, and returns false. */ template -constexpr bool mvkSetOrClear(T* pDest, const T* pSrc) { +static constexpr bool mvkSetOrClear(T* pDest, const T* pSrc) { if (pDest && pSrc) { *pDest = *pSrc; return true; @@ -594,17 +594,17 @@ void mvkDisableFlags(Tv& value, const Tm bitMask) { value = (Tv)(value & ~(Tv)bi /** Returns whether the specified value has ANY of the flags specified in bitMask enabled (set to 1). */ template -constexpr bool mvkIsAnyFlagEnabled(Tv value, const Tm bitMask) { return ((value & bitMask) != 0); } +static constexpr bool mvkIsAnyFlagEnabled(Tv value, const Tm bitMask) { return ((value & bitMask) != 0); } /** Returns whether the specified value has ALL of the flags specified in bitMask enabled (set to 1). */ template -constexpr bool mvkAreAllFlagsEnabled(Tv value, const Tm bitMask) { return ((value & bitMask) == bitMask); } +static constexpr bool mvkAreAllFlagsEnabled(Tv value, const Tm bitMask) { return ((value & bitMask) == bitMask); } /** Returns whether the specified value has ONLY one or more of the flags specified in bitMask enabled (set to 1), and none others. */ template -constexpr bool mvkIsOnlyAnyFlagEnabled(Tv value, const Tm bitMask) { return (mvkIsAnyFlagEnabled(value, bitMask) && ((value | bitMask) == bitMask)); } +static constexpr bool mvkIsOnlyAnyFlagEnabled(Tv value, const Tm bitMask) { return (mvkIsAnyFlagEnabled(value, bitMask) && ((value | bitMask) == bitMask)); } /** Returns whether the specified value has ONLY ALL of the flags specified in bitMask enabled (set to 1), and none others. */ template -constexpr bool mvkAreOnlyAllFlagsEnabled(Tv value, const Tm bitMask) { return (value == bitMask); } +static constexpr bool mvkAreOnlyAllFlagsEnabled(Tv value, const Tm bitMask) { return (value == bitMask); }