Set maxVertexInputBindingStride and maxVertexInputAttributeOffset to min Vulkan values.
Ensure kMVKUndefinedLarge... family of constant values are each a power-of-two. Change several power-of-two math functions to template functions.
This commit is contained in:
parent
22e2f5a777
commit
b408557c7e
@ -21,6 +21,8 @@ Released 2020/06/09
|
||||
- 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.
|
||||
|
@ -81,7 +81,7 @@ const MVKMTLBufferAllocation* MVKMTLBufferAllocator::acquireMTLBufferRegion(NSUI
|
||||
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 @@ MVKMTLBufferAllocator::MVKMTLBufferAllocator(MVKDevice* device, NSUInteger maxRe
|
||||
_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);
|
||||
|
@ -1253,8 +1253,8 @@ void MVKPhysicalDevice::initProperties() {
|
||||
_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;
|
||||
|
@ -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 @@ static inline std::string mvkGetMoltenVKVersionString(uint32_t mvkVersion) {
|
||||
#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 @@ static inline uintptr_t mvkEnsurePowerOfTwo(uintptr_t value) {
|
||||
*
|
||||
* 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 @@ static inline uintptr_t mvkAlignByteCount(uintptr_t byteCount, uintptr_t byteAli
|
||||
*/
|
||||
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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user