Merge pull request #911 from billhollings/master
Set maxVertexInputBindingStride and maxVertexInputAttributeOffset to min Vulkan values.
diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md
index 118881e..a114c71 100644
--- a/Docs/Whats_New.md
+++ b/Docs/Whats_New.md
@@ -21,6 +21,8 @@
- Fix issue in reporting properties of substitutable `VkFormats`.
- Fix vertex attribute offset adjustments when vertex buffer stride is zero.
- Update `fetchDependencies` script to use pre-built `spirv-tools` files by default.
+- Update `maxVertexInputBindingStride` and `maxVertexInputAttributeOffset`
+ to minimum Vulkan values.
- Numerous documentation typo corrections.
- Update `VK_MVK_MOLTENVK_SPEC_VERSION` to `26`.
- Update Travis CI to Xcode 11.5.
diff --git a/MoltenVK/MoltenVK/Commands/MVKMTLBufferAllocation.mm b/MoltenVK/MoltenVK/Commands/MVKMTLBufferAllocation.mm
index 7e1bf25..a09386b 100644
--- a/MoltenVK/MoltenVK/Commands/MVKMTLBufferAllocation.mm
+++ b/MoltenVK/MoltenVK/Commands/MVKMTLBufferAllocation.mm
@@ -81,7 +81,7 @@
MVKAssert(length <= _maxAllocationLength, "This MVKMTLBufferAllocator has been configured to dispense MVKMTLBufferRegions no larger than %lu bytes.", (unsigned long)_maxAllocationLength);
// Convert max length to the next power-of-two exponent to use as a lookup
- uint32_t p2Exp = mvkPowerOfTwoExponent(length);
+ NSUInteger p2Exp = mvkPowerOfTwoExponent(length);
MVKMTLBufferAllocationPool* pRP = _regionPools[p2Exp];
return _makeThreadSafe ? pRP->acquireObjectSafely() : pRP->acquireObject();
}
@@ -91,7 +91,7 @@
_makeThreadSafe = makeThreadSafe;
// Convert max length to the next power-of-two exponent
- uint32_t maxP2Exp = mvkPowerOfTwoExponent(_maxAllocationLength);
+ NSUInteger maxP2Exp = mvkPowerOfTwoExponent(_maxAllocationLength);
// Populate the array of region pools to cover the maximum region size
_regionPools.reserve(maxP2Exp + 1);
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
index aec27ae..7362b30 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
@@ -1253,8 +1253,8 @@
_properties.limits.maxVertexInputAttributes = 31;
_properties.limits.maxVertexInputBindings = 31;
- _properties.limits.maxVertexInputAttributeOffset = (4 * KIBI);
- _properties.limits.maxVertexInputBindingStride = _properties.limits.maxVertexInputAttributeOffset - 1;
+ _properties.limits.maxVertexInputBindingStride = (2 * KIBI);
+ _properties.limits.maxVertexInputAttributeOffset = _properties.limits.maxVertexInputBindingStride - 1;
_properties.limits.maxPerStageDescriptorSamplers = _metalFeatures.maxPerStageSamplerCount;
_properties.limits.maxPerStageDescriptorUniformBuffers = _metalFeatures.maxPerStageBufferCount;
diff --git a/MoltenVK/MoltenVK/Utility/MVKFoundation.h b/MoltenVK/MoltenVK/Utility/MVKFoundation.h
index a0f0eac..a8ea008 100644
--- a/MoltenVK/MoltenVK/Utility/MVKFoundation.h
+++ b/MoltenVK/MoltenVK/Utility/MVKFoundation.h
@@ -29,18 +29,6 @@
#pragma mark Math
-/**
- * The following constants are used to indicate values that have no defined limit.
- * They are ridiculously large numbers, but low enough to be safely used as both
- * uint and int values without risking overflowing between positive and negative values.
- */
-static int32_t kMVKUndefinedLargeNegativeInt32 = std::numeric_limits<int32_t>::min() / 2;
-static int32_t kMVKUndefinedLargePositiveInt32 = std::numeric_limits<int32_t>::max() / 2;
-static uint32_t kMVKUndefinedLargeUInt32 = kMVKUndefinedLargePositiveInt32;
-static int64_t kMVKUndefinedLargeNegativeInt64 = std::numeric_limits<int64_t>::min() / 2;
-static int64_t kMVKUndefinedLargePositiveInt64 = std::numeric_limits<int64_t>::max() / 2;
-static uint64_t kMVKUndefinedLargeUInt64 = kMVKUndefinedLargePositiveInt64;
-
// Common scaling multipliers
#define KIBI (1024)
#define MEBI (KIBI * KIBI)
@@ -136,21 +124,23 @@
#pragma mark -
#pragma mark Alignment functions
-/** Returns whether the specified value is a power-of-two. */
-static inline bool mvkIsPowerOfTwo(uintptr_t value) {
+/** Returns whether the specified positive value is a power-of-two. */
+template<typename T>
+static inline bool mvkIsPowerOfTwo(T value) {
// Test POT: (x != 0) && ((x & (x - 1)) == 0)
return value && ((value & (value - 1)) == 0);
}
/**
- * Ensures the specified value is a power-of-two. Returns the specified value if it is a
- * power-of-two value. If it is not, returns the next power-of-two value that is larger
- * than the specified value is returned.
+ * Ensures the specified positive value is a power-of-two. Returns the specified value
+ * if it is a power-of-two value. If it is not, returns the next power-of-two value
+ * that is larger than the specified value is returned.
*/
-static inline uintptr_t mvkEnsurePowerOfTwo(uintptr_t value) {
+template<typename T>
+static inline T mvkEnsurePowerOfTwo(T value) {
if (mvkIsPowerOfTwo(value)) { return value; }
- uintptr_t pot = 1;
+ T pot = 1;
while(pot <= value) { pot <<= 1; };
return pot;
}
@@ -161,12 +151,13 @@
*
* This implementation returns zero for both zero and one as inputs.
*/
-static inline uint32_t mvkPowerOfTwoExponent(uintptr_t value) {
- uintptr_t p2Value = mvkEnsurePowerOfTwo(value);
+template<typename T>
+static inline T mvkPowerOfTwoExponent(T value) {
+ T p2Value = mvkEnsurePowerOfTwo(value);
// Count the trailing zeros
p2Value = (p2Value ^ (p2Value - 1)) >> 1; // Set trailing 0s to 1s and zero rest
- uint32_t potExp = 0;
+ T potExp = 0;
while (p2Value) {
p2Value >>= 1;
potExp++;
@@ -230,6 +221,18 @@
*/
void mvkFlipVertically(void* rowMajorData, uint32_t rowCount, size_t bytesPerRow);
+/**
+ * The following constants are used to indicate values that have no defined limit.
+ * They are ridiculously large numbers, but low enough to be safely used as both
+ * uint and int values without risking overflowing between positive and negative values.
+ */
+static int32_t kMVKUndefinedLargePositiveInt32 = mvkEnsurePowerOfTwo(std::numeric_limits<int32_t>::max() / 2);
+static int32_t kMVKUndefinedLargeNegativeInt32 = -kMVKUndefinedLargePositiveInt32;
+static uint32_t kMVKUndefinedLargeUInt32 = kMVKUndefinedLargePositiveInt32;
+static int64_t kMVKUndefinedLargePositiveInt64 = mvkEnsurePowerOfTwo(std::numeric_limits<int64_t>::max() / 2);
+static int64_t kMVKUndefinedLargeNegativeInt64 = -kMVKUndefinedLargePositiveInt64;
+static uint64_t kMVKUndefinedLargeUInt64 = kMVKUndefinedLargePositiveInt64;
+
#pragma mark Vulkan structure support functions