Use MVKVector whenever possible in MoltenVK, especially within render loop.
Minor fixes and extensions to MVKVector implementations.
diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md
index 15bcbe5..a3a2ce3 100644
--- a/Docs/Whats_New.md
+++ b/Docs/Whats_New.md
@@ -21,6 +21,7 @@
- Revert to supporting host-coherent memory for linear images on macOS.
- Ensure Vulkan loader magic number is set every time before returning any dispatchable Vulkan handle.
- Consolidate the various linkable objects into a `MVKLinkableMixin` template base class.
+- Use `MVKVector` whenever possible in MoltenVK, especially within render loop.
MoltenVK 1.0.36
diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdDispatch.h b/MoltenVK/MoltenVK/Commands/MVKCmdDispatch.h
index 9213901..036605c 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCmdDispatch.h
+++ b/MoltenVK/MoltenVK/Commands/MVKCmdDispatch.h
@@ -20,7 +20,6 @@
#include "MVKCommand.h"
#include "MVKMTLResourceBindings.h"
-#include <vector>
#import <Metal/Metal.h>
diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.h b/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.h
index d5bf3dd..1cfd37e 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.h
+++ b/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.h
@@ -20,7 +20,6 @@
#include "MVKCommand.h"
#include "MVKVector.h"
-#include <vector>
class MVKCommandBuffer;
class MVKPipeline;
@@ -54,9 +53,9 @@
VkPipelineStageFlags _srcStageMask;
VkPipelineStageFlags _dstStageMask;
VkDependencyFlags _dependencyFlags;
- std::vector<VkMemoryBarrier> _memoryBarriers;
- std::vector<VkBufferMemoryBarrier> _bufferMemoryBarriers;
- std::vector<VkImageMemoryBarrier> _imageMemoryBarriers;
+ MVKVectorInline<VkMemoryBarrier, 4> _memoryBarriers;
+ MVKVectorInline<VkBufferMemoryBarrier, 4> _bufferMemoryBarriers;
+ MVKVectorInline<VkImageMemoryBarrier, 4> _imageMemoryBarriers;
};
diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.mm b/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.mm
index 18fe127..c65adce 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.mm
+++ b/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.mm
@@ -77,7 +77,7 @@
afterStages: srcStages
beforeStages: dstStages];
}
- std::vector<id<MTLResource>> resources;
+ MVKVectorInline<id<MTLResource>, 16> resources;
resources.reserve(_bufferMemoryBarriers.size() + _imageMemoryBarriers.size());
for (auto& mb : _bufferMemoryBarriers) {
auto* mvkBuff = (MVKBuffer*)mb.buffer;
diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.h b/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.h
index 2658c0f..0f84ff0 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.h
+++ b/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.h
@@ -20,7 +20,6 @@
#include "MVKCommand.h"
#include "MVKVector.h"
-#include <vector>
#import <Metal/Metal.h>
@@ -85,7 +84,7 @@
#pragma mark -
#pragma mark MVKCmdExecuteCommands
-/** Vulkan command to end the current render pass. */
+/** Vulkan command to execute secondary command buffers. */
class MVKCmdExecuteCommands : public MVKCommand {
public:
@@ -96,7 +95,7 @@
MVKCmdExecuteCommands(MVKCommandTypePool<MVKCmdExecuteCommands>* pool);
private:
- std::vector<MVKCommandBuffer*> _secondaryCommandBuffers;
+ MVKVectorInline<MVKCommandBuffer*, 64> _secondaryCommandBuffers;
};
#pragma mark -
diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.h b/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.h
index 231924a..a7b9486 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.h
+++ b/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.h
@@ -22,7 +22,7 @@
#include "MVKMTLBufferAllocation.h"
#include "MVKCommandResourceFactory.h"
#include "MVKFoundation.h"
-#include <vector>
+#include "MVKVector.h"
#import <Metal/Metal.h>
@@ -68,9 +68,9 @@
bool _isDstCompressed;
bool _canCopyFormats;
bool _useTempBuffer;
- std::vector<VkImageCopy> _imageCopyRegions;
- std::vector<VkBufferImageCopy> _srcTmpBuffImgCopies;
- std::vector<VkBufferImageCopy> _dstTmpBuffImgCopies;
+ MVKVectorInline<VkImageCopy, 4> _imageCopyRegions;
+ MVKVectorInline<VkBufferImageCopy, 4> _srcTmpBuffImgCopies;
+ MVKVectorInline<VkBufferImageCopy, 4> _dstTmpBuffImgCopies;
size_t _tmpBuffSize;
MVKCommandUse _commandUse;
};
@@ -117,7 +117,7 @@
MTLRenderPassDescriptor* _mtlRenderPassDescriptor;
MTLSamplerMinMagFilter _mtlFilter;
MVKRPSKeyBlitImg _blitKey;
- std::vector<MVKImageBlitRender> _mvkImageBlitRenders;
+ MVKVectorInline<MVKImageBlitRender, 4> _mvkImageBlitRenders;
};
@@ -157,11 +157,11 @@
VkImageLayout _srcLayout;
MVKImage* _dstImage;
VkImageLayout _dstLayout;
- std::vector<VkImageBlit> _expansionRegions;
- std::vector<VkImageCopy> _copyRegions;
MVKImageDescriptorData _transferImageData;
MTLRenderPassDescriptor* _mtlRenderPassDescriptor;
- std::vector<MVKMetalResolveSlice> _mtlResolveSlices;
+ MVKVectorInline<VkImageBlit, 4> _expansionRegions;
+ MVKVectorInline<VkImageCopy, 4> _copyRegions;
+ MVKVectorInline<MVKMetalResolveSlice, 4> _mtlResolveSlices;
};
@@ -186,7 +186,7 @@
MVKBuffer* _srcBuffer;
MVKBuffer* _dstBuffer;
- std::vector<VkBufferCopy> _mtlBuffCopyRegions;
+ MVKVectorInline<VkBufferCopy, 4> _mtlBuffCopyRegions;
};
@@ -215,7 +215,7 @@
MVKBuffer* _buffer;
MVKImage* _image;
VkImageLayout _imageLayout;
- std::vector<VkBufferImageCopy> _bufferImageCopyRegions;
+ MVKVectorInline<VkBufferImageCopy, 4> _bufferImageCopyRegions;
bool _toImage = false;
};
@@ -241,8 +241,8 @@
void populateVertices(float attWidth, float attHeight);
void populateVertices(VkClearRect& clearRect, float attWidth, float attHeight);
- std::vector<VkClearRect> _clearRects;
- std::vector<simd::float4> _vertices;
+ MVKVectorInline<VkClearRect, 4> _clearRects;
+ MVKVectorInline<simd::float4, (4 * 6)> _vertices;
simd::float4 _clearColors[kMVKClearAttachmentCount];
VkClearValue _vkClearValues[kMVKClearAttachmentCount];
MVKRPSKeyClearAtt _rpsKey;
@@ -278,7 +278,7 @@
MVKImage* _image;
VkImageLayout _imgLayout;
- std::vector<VkImageSubresourceRange> _subresourceRanges;
+ MVKVectorInline<VkImageSubresourceRange, 4> _subresourceRanges;
MTLClearColor _mtlColorClearValue;
double _mtlDepthClearValue;
uint32_t _mtlStencilClearValue;
@@ -330,7 +330,7 @@
MVKBuffer* _dstBuffer;
VkDeviceSize _dstOffset;
VkDeviceSize _dataSize;
- std::vector<uint8_t> _srcDataCache;
+ MVKVectorDefault<uint8_t> _srcDataCache;
};
diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h
index 18f6dfe..ddeae21 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h
+++ b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h
@@ -23,8 +23,8 @@
#include "MVKCommandEncoderState.h"
#include "MVKMTLBufferAllocation.h"
#include "MVKCmdPipeline.h"
+#include "MVKQueryPool.h"
#include "MVKVector.h"
-#include <vector>
#include <unordered_map>
class MVKCommandPool;
@@ -240,7 +240,7 @@
/*** Holds a collection of active queries for each query pool. */
-typedef std::unordered_map<MVKQueryPool*, std::vector<uint32_t>> MVKActivatedQueries;
+typedef std::unordered_map<MVKQueryPool*, MVKVectorInline<uint32_t, kMVKDefaultQueryCount>> MVKActivatedQueries;
/**
* MVKCommandEncoder uses a visitor design pattern iterate the commands in a MVKCommandBuffer,
diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm
index 40dfbd9..f43a495 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm
+++ b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm
@@ -398,7 +398,7 @@
// Clears the render area of the framebuffer attachments.
void MVKCommandEncoder::clearRenderArea() {
- vector<VkClearAttachment> clearAtts;
+ MVKVectorInline<VkClearAttachment, kMVKDefaultAttachmentCount> clearAtts;
getSubpass()->populateClearAttachments(clearAtts, _clearValues);
uint32_t clearAttCnt = (uint32_t)clearAtts.size();
diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h
index 901f457..9af8197 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h
+++ b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h
@@ -519,11 +519,11 @@
void resetImpl() override;
void markDirty() override;
- MVKVectorDefault<MVKMTLBufferBinding> _bufferBindings;
- MVKVectorDefault<MVKMTLTextureBinding> _textureBindings;
- MVKVectorDefault<MVKMTLSamplerStateBinding> _samplerStateBindings;
- MVKVectorDefault<uint32_t> _swizzleConstants;
- MVKVectorDefault<uint32_t> _bufferSizes;
+ MVKVectorInline<MVKMTLBufferBinding, 4> _bufferBindings;
+ MVKVectorInline<MVKMTLTextureBinding, 4> _textureBindings;
+ MVKVectorInline<MVKMTLSamplerStateBinding, 4> _samplerStateBindings;
+ MVKVectorInline<uint32_t, 4> _swizzleConstants;
+ MVKVectorInline<uint32_t, 4> _bufferSizes;
MVKMTLBufferBinding _swizzleBufferBinding;
MVKMTLBufferBinding _bufferSizeBufferBinding;
diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandPool.mm b/MoltenVK/MoltenVK/Commands/MVKCommandPool.mm
index 1c5d51e..668089f 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCommandPool.mm
+++ b/MoltenVK/MoltenVK/Commands/MVKCommandPool.mm
@@ -123,6 +123,9 @@
_cmdDispatchIndirectPool.clear();
_cmdPushDescriptorSetPool.clear();
_cmdPushSetWithTemplatePool.clear();
+ _cmdDebugMarkerBeginPool.clear();
+ _cmdDebugMarkerEndPool.clear();
+ _cmdDebugMarkerInsertPool.clear();
}
@@ -131,9 +134,9 @@
MVKCommandPool::MVKCommandPool(MVKDevice* device,
const VkCommandPoolCreateInfo* pCreateInfo) :
MVKVulkanAPIDeviceObject(device),
+ _queueFamilyIndex(pCreateInfo->queueFamilyIndex),
_commandBufferPool(device),
_commandEncodingPool(this),
- _queueFamilyIndex(pCreateInfo->queueFamilyIndex),
_cmdPipelineBarrierPool(this),
_cmdBindPipelinePool(this),
_cmdBeginRenderPassPool(this),
@@ -143,13 +146,13 @@
_cmdBindDescriptorSetsPool(this),
_cmdSetViewportPool(this),
_cmdSetScissorPool(this),
- _cmdSetLineWidthPool(this),
- _cmdSetDepthBiasPool(this),
- _cmdSetBlendConstantsPool(this),
- _cmdSetDepthBoundsPool(this),
- _cmdSetStencilCompareMaskPool(this),
- _cmdSetStencilWriteMaskPool(this),
- _cmdSetStencilReferencePool(this),
+ _cmdSetLineWidthPool(this),
+ _cmdSetDepthBiasPool(this),
+ _cmdSetBlendConstantsPool(this),
+ _cmdSetDepthBoundsPool(this),
+ _cmdSetStencilCompareMaskPool(this),
+ _cmdSetStencilWriteMaskPool(this),
+ _cmdSetStencilReferencePool(this),
_cmdBindVertexBuffersPool(this),
_cmdBindIndexBufferPool(this),
_cmdDrawPool(this),
@@ -158,26 +161,27 @@
_cmdDrawIndexedIndirectPool(this),
_cmdCopyImagePool(this),
_cmdBlitImagePool(this),
- _cmdResolveImagePool(this),
- _cmdFillBufferPool(this),
- _cmdUpdateBufferPool(this),
+ _cmdResolveImagePool(this),
+ _cmdFillBufferPool(this),
+ _cmdUpdateBufferPool(this),
_cmdCopyBufferPool(this),
- _cmdBufferImageCopyPool(this),
+ _cmdBufferImageCopyPool(this),
_cmdClearAttachmentsPool(this),
_cmdClearImagePool(this),
- _cmdBeginQueryPool(this),
- _cmdEndQueryPool(this),
+ _cmdBeginQueryPool(this),
+ _cmdEndQueryPool(this),
_cmdWriteTimestampPool(this),
- _cmdResetQueryPoolPool(this),
- _cmdCopyQueryPoolResultsPool(this),
+ _cmdResetQueryPoolPool(this),
+ _cmdCopyQueryPoolResultsPool(this),
_cmdPushConstantsPool(this),
- _cmdDispatchPool(this),
- _cmdDispatchIndirectPool(this),
- _cmdPushDescriptorSetPool(this),
- _cmdPushSetWithTemplatePool(this),
+ _cmdDispatchPool(this),
+ _cmdDispatchIndirectPool(this),
+ _cmdPushDescriptorSetPool(this),
+ _cmdPushSetWithTemplatePool(this),
_cmdDebugMarkerBeginPool(this),
_cmdDebugMarkerEndPool(this),
_cmdDebugMarkerInsertPool(this)
+// when extending be sure to add to trim() as well
{}
MVKCommandPool::~MVKCommandPool() {
diff --git a/MoltenVK/MoltenVK/Commands/MVKMTLBufferAllocation.h b/MoltenVK/MoltenVK/Commands/MVKMTLBufferAllocation.h
index eef16f6..c5ff171 100644
--- a/MoltenVK/MoltenVK/Commands/MVKMTLBufferAllocation.h
+++ b/MoltenVK/MoltenVK/Commands/MVKMTLBufferAllocation.h
@@ -22,7 +22,7 @@
#include "MVKFoundation.h"
#include "MVKObjectPool.h"
#include "MVKDevice.h"
-#include <vector>
+#include "MVKVector.h"
class MVKMTLBufferAllocationPool;
@@ -97,7 +97,7 @@
NSUInteger _nextOffset;
NSUInteger _allocationLength;
NSUInteger _mtlBufferLength;
- std::vector<id<MTLBuffer>> _mtlBuffers;
+ MVKVectorInline<id<MTLBuffer>, 64> _mtlBuffers;
MVKDevice* _device;
};
@@ -142,7 +142,7 @@
~MVKMTLBufferAllocator() override;
protected:
- std::vector<MVKMTLBufferAllocationPool*> _regionPools;
+ MVKVectorInline<MVKMTLBufferAllocationPool*, 32> _regionPools;
NSUInteger _maxAllocationLength;
bool _makeThreadSafe;
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.h b/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.h
index f5eb7b6..9b80795 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.h
@@ -24,7 +24,6 @@
#include <MoltenVKSPIRVToMSLConverter/SPIRVToMSLConverter.h>
#include <unordered_set>
#include <unordered_map>
-#include <vector>
class MVKDescriptorPool;
class MVKDescriptorBinding;
@@ -118,7 +117,7 @@
MVKDescriptorSetLayout* _layout;
VkDescriptorSetLayoutBinding _info;
- std::vector<MVKSampler*> _immutableSamplers;
+ MVKVectorInline<MVKSampler*, 16> _immutableSamplers;
MVKShaderResourceBinding _mtlResourceIndexOffsets;
bool _applyToStage[kMVKShaderStageMax];
};
@@ -272,13 +271,13 @@
MVKDescriptorSet* _pDescSet;
MVKDescriptorSetLayoutBinding* _pBindingLayout;
- std::vector<VkDescriptorImageInfo> _imageBindings;
- std::vector<VkDescriptorBufferInfo> _bufferBindings;
- std::vector<VkBufferView> _texelBufferBindings;
- std::vector<id<MTLBuffer>> _mtlBuffers;
- std::vector<NSUInteger> _mtlBufferOffsets;
- std::vector<id<MTLTexture>> _mtlTextures;
- std::vector<id<MTLSamplerState>> _mtlSamplers;
+ MVKVectorInline<VkDescriptorImageInfo, 1> _imageBindings;
+ MVKVectorInline<VkDescriptorBufferInfo, 1> _bufferBindings;
+ MVKVectorInline<VkBufferView, 1> _texelBufferBindings;
+ MVKVectorInline<id<MTLBuffer>, 1> _mtlBuffers;
+ MVKVectorInline<NSUInteger, 1> _mtlBufferOffsets;
+ MVKVectorInline<id<MTLTexture>, 1> _mtlTextures;
+ MVKVectorInline<id<MTLSamplerState>, 1> _mtlSamplers;
bool _hasDynamicSamplers;
};
@@ -324,7 +323,7 @@
MVKDescriptorBinding* getBinding(uint32_t binding);
MVKDescriptorSetLayout* _pLayout = nullptr;
- std::vector<MVKDescriptorBinding> _bindings;
+ MVKVectorInline<MVKDescriptorBinding, 8> _bindings;
};
@@ -408,7 +407,7 @@
void propogateDebugName() override {}
VkDescriptorUpdateTemplateTypeKHR _type;
- std::vector<VkDescriptorUpdateTemplateEntryKHR> _entries;
+ MVKVectorInline<VkDescriptorUpdateTemplateEntryKHR, 4> _entries;
};
#pragma mark -
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h
index e087ea1..3ce7590 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h
@@ -22,9 +22,9 @@
#include "MVKVulkanAPIObject.h"
#include "MVKLayers.h"
#include "MVKObjectPool.h"
+#include "MVKVector.h"
#include "mvk_datatypes.hpp"
#include "vk_mvk_moltenvk.h"
-#include <vector>
#include <string>
#include <mutex>
@@ -67,6 +67,10 @@
const static uint32_t kMVKVertexContentBufferIndex = 0;
// Parameters to define the sizing of inline collections
+const static uint32_t kMVKQueueFamilyCount = 4;
+const static uint32_t kMVKQueueCountPerQueueFamily = 1; // Must be 1. See comments in MVKPhysicalDevice::getQueueFamilies()
+const static uint32_t kMVKMinSwapchainImageCount = 2;
+const static uint32_t kMVKMaxSwapchainImageCount = 3;
const static uint32_t kMVKCachedViewportScissorCount = 16;
const static uint32_t kMVKCachedColorAttachmentCount = 8;
@@ -328,7 +332,7 @@
void initMemoryProperties();
void initExtensions();
MVKExtensionList* getSupportedExtensions(const char* pLayerName = nullptr);
- std::vector<MVKQueueFamily*>& getQueueFamilies();
+ MVKVector<MVKQueueFamily*>& getQueueFamilies();
void initPipelineCacheUUID();
MTLFeatureSet getHighestMTLFeatureSet();
uint64_t getSpirvCrossRevision();
@@ -343,7 +347,7 @@
VkPhysicalDeviceProperties _properties;
VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT _texelBuffAlignProperties;
VkPhysicalDeviceMemoryProperties _memoryProperties;
- std::vector<MVKQueueFamily*> _queueFamilies;
+ MVKVectorInline<MVKQueueFamily*, kMVKQueueFamilyCount> _queueFamilies;
uint32_t _allMemoryTypes;
uint32_t _hostVisibleMemoryTypes;
uint32_t _hostCoherentMemoryTypes;
@@ -677,8 +681,8 @@
MVKPhysicalDevice* _physicalDevice;
MVKCommandResourceFactory* _commandResourceFactory;
MTLCompileOptions* _mtlCompileOptions;
- std::vector<std::vector<MVKQueue*>> _queuesByQueueFamilyIndex;
- std::vector<MVKResource*> _resources;
+ MVKVectorInline<MVKVectorInline<MVKQueue*, kMVKQueueCountPerQueueFamily>, kMVKQueueFamilyCount> _queuesByQueueFamilyIndex;
+ MVKVectorInline<MVKResource*, 256> _resources;
std::mutex _rezLock;
std::mutex _perfLock;
id<MTLBuffer> _globalVisibilityResultMTLBuffer;
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
index e9e481f..438674c 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
@@ -606,16 +606,16 @@
// Metal does not distinguish functionality between queues, which would normally lead us
// to create only only one general-purpose queue family. However, Vulkan associates command
// buffers with a queue family, whereas Metal associates command buffers with a Metal queue.
-// In order to allow a Metal command buffer to be prefilled before is is formally submitted to
+// In order to allow a Metal command buffer to be prefilled before it is formally submitted to
// a Vulkan queue, we need to enforce that each Vulkan queue family can have only one Metal queue.
// In order to provide parallel queue operations, we therefore provide multiple queue families.
-vector<MVKQueueFamily*>& MVKPhysicalDevice::getQueueFamilies() {
+MVKVector<MVKQueueFamily*>& MVKPhysicalDevice::getQueueFamilies() {
if (_queueFamilies.empty()) {
VkQueueFamilyProperties qfProps;
bool specialize = _mvkInstance->getMoltenVKConfiguration()->specializedQueueFamilies;
uint32_t qfIdx = 0;
- qfProps.queueCount = 1; // Each queue family must have a single Metal queue (see above)
+ qfProps.queueCount = kMVKQueueCountPerQueueFamily;
qfProps.timestampValidBits = 64;
qfProps.minImageTransferGranularity = { 1, 1, 1};
@@ -634,6 +634,8 @@
// Dedicated transfer queue family...or another general-purpose queue family.
if (specialize) { qfProps.queueFlags = VK_QUEUE_TRANSFER_BIT; }
_queueFamilies.push_back(new MVKQueueFamily(this, qfIdx++, &qfProps));
+
+ MVKAssert(kMVKQueueFamilyCount >= _queueFamilies.size(), "Adjust value of kMVKQueueFamilyCount.");
}
return _queueFamilies;
}
@@ -641,7 +643,7 @@
VkResult MVKPhysicalDevice::getQueueFamilyProperties(uint32_t* pCount,
VkQueueFamilyProperties* pQueueFamilyProperties) {
- vector<MVKQueueFamily*> qFams = getQueueFamilies();
+ auto& qFams = getQueueFamilies();
uint32_t qfCnt = uint32_t(qFams.size());
// If properties aren't actually being requested yet, simply update the returned count
@@ -750,8 +752,8 @@
_metalFeatures.ioSurfaces = MVK_SUPPORT_IOSURFACE_BOOL;
// Metal supports 2 or 3 concurrent CAMetalLayer drawables.
- _metalFeatures.minSwapchainImageCount = 2;
- _metalFeatures.maxSwapchainImageCount = 3;
+ _metalFeatures.minSwapchainImageCount = kMVKMinSwapchainImageCount;
+ _metalFeatures.maxSwapchainImageCount = kMVKMaxSwapchainImageCount;
#if MVK_IOS
_metalFeatures.mslVersionEnum = MTLLanguageVersion1_0;
@@ -2088,14 +2090,14 @@
mvkDevMem->destroy();
}
-/** Adds the specified resource for tracking, and returns the added resource. */
+// Adds the specified resource for tracking, and returns the added resource.
MVKResource* MVKDevice::addResource(MVKResource* rez) {
lock_guard<mutex> lock(_rezLock);
_resources.push_back(rez);
return rez;
}
-/** Removes the specified resource for tracking and returns the removed resource. */
+// Removes the specified resource for tracking and returns the removed resource.
MVKResource* MVKDevice::removeResource(MVKResource* rez) {
lock_guard<mutex> lock(_rezLock);
mvkRemoveFirstOccurance(_resources, rez);
@@ -2488,7 +2490,7 @@
// Create the command queues
void MVKDevice::initQueues(const VkDeviceCreateInfo* pCreateInfo) {
- vector<MVKQueueFamily*> qFams = _physicalDevice->getQueueFamilies();
+ auto& qFams = _physicalDevice->getQueueFamilies();
uint32_t qrCnt = pCreateInfo->queueCreateInfoCount;
for (uint32_t qrIdx = 0; qrIdx < qrCnt; qrIdx++) {
const VkDeviceQueueCreateInfo* pQFInfo = &pCreateInfo->pQueueCreateInfos[qrIdx];
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDeviceMemory.h b/MoltenVK/MoltenVK/GPUObjects/MVKDeviceMemory.h
index c87b443..9d468ef 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDeviceMemory.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDeviceMemory.h
@@ -19,7 +19,7 @@
#pragma once
#include "MVKDevice.h"
-#include <vector>
+#include "MVKVector.h"
#include <mutex>
#import <Metal/Metal.h>
@@ -128,8 +128,8 @@
void freeHostMemory();
MVKResource* getDedicatedResource();
- std::vector<MVKBuffer*> _buffers;
- std::vector<MVKImage*> _images;
+ MVKVectorInline<MVKBuffer*, 4> _buffers;
+ MVKVectorInline<MVKImage*, 4> _images;
std::mutex _rezLock;
VkDeviceSize _allocationSize = 0;
VkDeviceSize _mapOffset = 0;
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKFramebuffer.h b/MoltenVK/MoltenVK/GPUObjects/MVKFramebuffer.h
index 9fd9ef3..e7a0852 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKFramebuffer.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKFramebuffer.h
@@ -20,7 +20,7 @@
#include "MVKDevice.h"
#include "MVKImage.h"
-#include <vector>
+#include "MVKVector.h"
#pragma mark MVKFramebuffer
@@ -56,6 +56,6 @@
VkExtent2D _extent;
uint32_t _layerCount;
- std::vector<MVKImageView*> _attachments;
+ MVKVectorInline<MVKImageView*, 8> _attachments;
};
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.h b/MoltenVK/MoltenVK/GPUObjects/MVKImage.h
index 0cbf0d0..68fdd23 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.h
@@ -257,7 +257,7 @@
VkPipelineStageFlags dstStageMask,
VkImageMemoryBarrier* pImageMemoryBarrier);
- std::vector<MVKImageSubresource> _subresources;
+ MVKVectorInline<MVKImageSubresource, 4> _subresources;
std::unordered_map<NSUInteger, id<MTLTexture>> _mtlTextureViews;
VkExtent3D _extent;
uint32_t _mipLevels;
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.h b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.h
index 5771fe6..4bbef89 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.h
@@ -21,8 +21,8 @@
#include "MVKEnvironment.h"
#include "MVKLayers.h"
#include "MVKVulkanAPIObject.h"
+#include "MVKVector.h"
#include "vk_mvk_moltenvk.h"
-#include <vector>
#include <unordered_map>
#include <string>
#include <mutex>
@@ -100,7 +100,7 @@
VkResult getPhysicalDeviceGroups(uint32_t* pCount, VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProps);
/** Returns the driver layer. */
- MVKLayer* getDriverLayer() { return MVKLayerManager::globalManager()->getDriverLayer(); }
+ MVKLayer* getDriverLayer() { return getLayerManager()->getDriverLayer(); }
MVKSurface* createSurface(const VkMetalSurfaceCreateInfoEXT* pCreateInfo,
const VkAllocationCallbacks* pAllocator);
@@ -187,10 +187,10 @@
MVKConfiguration _mvkConfig;
VkApplicationInfo _appInfo;
- std::vector<MVKPhysicalDevice*> _physicalDevices;
+ MVKVectorInline<MVKPhysicalDevice*, 4> _physicalDevices;
+ MVKVectorInline<MVKDebugReportCallback*, 4> _debugReportCallbacks;
+ MVKVectorInline<MVKDebugUtilsMessenger*, 4> _debugUtilMessengers;
std::unordered_map<std::string, MVKEntryPoint> _entryPoints;
- std::vector<MVKDebugReportCallback*> _debugReportCallbacks;
- std::vector<MVKDebugUtilsMessenger*> _debugUtilMessengers;
std::mutex _dcbLock;
bool _hasDebugReportCallbacks;
bool _hasDebugUtilsMessengers;
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm
index ce9fa40..0bb9bef 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm
@@ -666,7 +666,7 @@
VkResult MVKInstance::verifyLayers(uint32_t count, const char* const* names) {
VkResult result = VK_SUCCESS;
for (uint32_t i = 0; i < count; i++) {
- if ( !MVKLayerManager::globalManager()->getLayerNamed(names[i]) ) {
+ if ( !getLayerManager()->getLayerNamed(names[i]) ) {
result = reportError(VK_ERROR_LAYER_NOT_PRESENT, "Vulkan layer %s is not supported.", names[i]);
}
}
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.h b/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.h
index 23bdb68..90d86f1 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.h
@@ -20,7 +20,6 @@
#include "MVKDevice.h"
#include "MVKVector.h"
-#include <vector>
#include <mutex>
#include <condition_variable>
@@ -29,7 +28,8 @@
class MVKCommandEncoder;
// The size of one query slot in bytes
-#define kMVKQuerySlotSizeInBytes sizeof(uint64_t)
+#define kMVKQuerySlotSizeInBytes sizeof(uint64_t)
+#define kMVKDefaultQueryCount 64
#pragma mark -
@@ -57,7 +57,7 @@
virtual void endQuery(uint32_t query, MVKCommandEncoder* cmdEncoder);
/** Finishes the specified queries and marks them as available. */
- virtual void finishQueries(std::vector<uint32_t>& queries);
+ virtual void finishQueries(MVKVector<uint32_t>& queries);
/** Resets the results and availability status of the specified queries. */
virtual void resetResults(uint32_t firstQuery, uint32_t queryCount, MVKCommandEncoder* cmdEncoder);
@@ -101,7 +101,7 @@
MVKQueryPool(MVKDevice* device,
const VkQueryPoolCreateInfo* pCreateInfo,
const uint32_t queryElementCount) : MVKVulkanAPIDeviceObject(device),
- _availability(pCreateInfo->queryCount),
+ _availability(pCreateInfo->queryCount, Initial),
_queryElementCount(queryElementCount) {}
protected:
@@ -127,12 +127,12 @@
Available /**< Query is available to the host. */
};
- std::vector<Status> _availability;
+ MVKVectorInline<Status, kMVKDefaultQueryCount> _availability;
+ MVKVectorInline<DeferredCopy, 4> _deferredCopies;
uint32_t _queryElementCount;
std::mutex _availabilityLock;
std::condition_variable _availabilityBlocker;
std::mutex _deferredCopiesLock;
- MVKVectorInline<DeferredCopy, 2> _deferredCopies;
};
@@ -143,7 +143,7 @@
class MVKTimestampQueryPool : public MVKQueryPool {
public:
- void finishQueries(std::vector<uint32_t>& queries) override;
+ void finishQueries(MVKVector<uint32_t>& queries) override;
#pragma mark Construction
@@ -156,7 +156,7 @@
id<MTLBuffer> getResultBuffer(MVKCommandEncoder* cmdEncoder, uint32_t firstQuery, uint32_t queryCount, NSUInteger& offset) override;
void encodeSetResultBuffer(MVKCommandEncoder* cmdEncoder, uint32_t firstQuery, uint32_t queryCount, uint32_t index) override;
- std::vector<uint64_t> _timestamps;
+ MVKVectorInline<uint64_t, kMVKDefaultQueryCount> _timestamps;
};
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.mm b/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.mm
index 0090244..b174d07 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.mm
@@ -47,7 +47,7 @@
}
// Mark queries as available
-void MVKQueryPool::finishQueries(vector<uint32_t>& queries) {
+void MVKQueryPool::finishQueries(MVKVector<uint32_t>& queries) {
lock_guard<mutex> lock(_availabilityLock);
for (uint32_t qry : queries) { _availability[qry] = Available; }
_availabilityBlocker.notify_all(); // Predicate of each wait() call will check whether all required queries are available
@@ -184,7 +184,7 @@
#pragma mark MVKTimestampQueryPool
// Update timestamp values, then mark queries as available
-void MVKTimestampQueryPool::finishQueries(vector<uint32_t>& queries) {
+void MVKTimestampQueryPool::finishQueries(MVKVector<uint32_t>& queries) {
uint64_t ts = mvkGetTimestamp();
for (uint32_t qry : queries) { _timestamps[qry] = ts; }
@@ -215,7 +215,8 @@
#pragma mark Construction
MVKTimestampQueryPool::MVKTimestampQueryPool(MVKDevice* device,
- const VkQueryPoolCreateInfo* pCreateInfo) : MVKQueryPool(device, pCreateInfo, 1), _timestamps(pCreateInfo->queryCount) {
+ const VkQueryPoolCreateInfo* pCreateInfo) :
+ MVKQueryPool(device, pCreateInfo, 1), _timestamps(pCreateInfo->queryCount, 0) {
}
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKQueue.h b/MoltenVK/MoltenVK/GPUObjects/MVKQueue.h
index 0cd2c53..d41bfee 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKQueue.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKQueue.h
@@ -23,7 +23,6 @@
#include "MVKImage.h"
#include "MVKSync.h"
#include "MVKVector.h"
-#include <vector>
#include <mutex>
#import <Metal/Metal.h>
@@ -65,7 +64,7 @@
MVKPhysicalDevice* _physicalDevice;
uint32_t _queueFamilyIndex;
VkQueueFamilyProperties _properties;
- std::vector<id<MTLCommandQueue>> _mtlQueues;
+ MVKVectorInline<id<MTLCommandQueue>, kMVKQueueCountPerQueueFamily> _mtlQueues;
std::mutex _qLock;
};
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.h b/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.h
index a93dba6..70b6ea4 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.h
@@ -20,7 +20,6 @@
#include "MVKDevice.h"
#include "MVKVector.h"
-#include <vector>
#import <Metal/Metal.h>
@@ -28,6 +27,10 @@
class MVKFramebuffer;
+// Parameters to define the sizing of inline collections
+const static uint32_t kMVKDefaultAttachmentCount = 8;
+
+
#pragma mark -
#pragma mark MVKRenderSubpass
@@ -70,7 +73,7 @@
* Populates the specified vector with the attachments that need to be cleared
* when the render area is smaller than the full framebuffer size.
*/
- void populateClearAttachments(std::vector<VkClearAttachment>& clearAtts,
+ void populateClearAttachments(MVKVector<VkClearAttachment>& clearAtts,
MVKVector<VkClearValue>& clearValues);
/** Constructs an instance for the specified parent renderpass. */
@@ -85,10 +88,10 @@
MVKRenderPass* _renderPass;
uint32_t _subpassIndex;
- std::vector<VkAttachmentReference> _inputAttachments;
- std::vector<VkAttachmentReference> _colorAttachments;
- std::vector<VkAttachmentReference> _resolveAttachments;
- std::vector<uint32_t> _preserveAttachments;
+ MVKVectorInline<VkAttachmentReference, kMVKDefaultAttachmentCount> _inputAttachments;
+ MVKVectorInline<VkAttachmentReference, kMVKDefaultAttachmentCount> _colorAttachments;
+ MVKVectorInline<VkAttachmentReference, kMVKDefaultAttachmentCount> _resolveAttachments;
+ MVKVectorInline<uint32_t, kMVKDefaultAttachmentCount> _preserveAttachments;
VkAttachmentReference _depthStencilAttachment;
id<MTLTexture> _mtlDummyTex = nil;
};
@@ -168,9 +171,9 @@
void propogateDebugName() override {}
- std::vector<MVKRenderSubpass> _subpasses;
- std::vector<MVKRenderPassAttachment> _attachments;
- std::vector<VkSubpassDependency> _subpassDependencies;
+ MVKVectorInline<MVKRenderPassAttachment, kMVKDefaultAttachmentCount> _attachments;
+ MVKVectorInline<MVKRenderSubpass, 4> _subpasses;
+ MVKVectorInline<VkSubpassDependency, 4 * 2> _subpassDependencies;
};
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.mm b/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.mm
index 52609af..4ee7b1c 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.mm
@@ -165,7 +165,7 @@
}
}
-void MVKRenderSubpass::populateClearAttachments(vector<VkClearAttachment>& clearAtts,
+void MVKRenderSubpass::populateClearAttachments(MVKVector<VkClearAttachment>& clearAtts,
MVKVector<VkClearValue>& clearValues) {
VkClearAttachment cAtt;
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.h b/MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.h
index d9a8f84..4ef1dfb 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.h
@@ -20,9 +20,9 @@
#include "MVKDevice.h"
#include "MVKSync.h"
+#include "MVKVector.h"
#include <MoltenVKSPIRVToMSLConverter/SPIRVToMSLConverter.h>
#include <MoltenVKGLSLToSPIRVConverter/GLSLToSPIRVConverter.h>
-#include <vector>
#include <mutex>
#import <Metal/Metal.h>
@@ -151,7 +151,7 @@
void merge(MVKShaderLibraryCache* other);
MVKVulkanAPIDeviceObject* _owner;
- std::vector<std::pair<SPIRVToMSLConversionConfiguration, MVKShaderLibrary*>> _shaderLibraries;
+ MVKVectorInline<std::pair<SPIRVToMSLConversionConfiguration, MVKShaderLibrary*>, 4> _shaderLibraries;
};
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.h b/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.h
index 20e3dbe..802f2ad 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.h
@@ -19,7 +19,7 @@
#pragma once
#include "MVKDevice.h"
-#include <vector>
+#include "MVKVector.h"
class MVKSwapchainImage;
class MVKWatermark;
@@ -111,7 +111,7 @@
CAMetalLayer* _mtlLayer;
MVKWatermark* _licenseWatermark;
- std::vector<MVKSwapchainImage*> _surfaceImages;
+ MVKVectorInline<MVKSwapchainImage*, kMVKMaxSwapchainImageCount> _surfaceImages;
std::atomic<uint64_t> _currentAcquisitionID;
CGSize _mtlLayerOrigDrawSize;
MVKSwapchainPerformance _performanceStatistics;
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKSync.h b/MoltenVK/MoltenVK/GPUObjects/MVKSync.h
index fa5f647..24ac84f 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKSync.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKSync.h
@@ -23,7 +23,6 @@
#include <mutex>
#include <condition_variable>
#include <unordered_set>
-#include <vector>
class MVKFenceSitter;
diff --git a/MoltenVK/MoltenVK/Layers/MVKLayers.h b/MoltenVK/MoltenVK/Layers/MVKLayers.h
index b93742a..e4bbc42 100644
--- a/MoltenVK/MoltenVK/Layers/MVKLayers.h
+++ b/MoltenVK/MoltenVK/Layers/MVKLayers.h
@@ -20,7 +20,7 @@
#include "MVKBaseObject.h"
#include "MVKExtensions.h"
-#include <vector>
+#include "MVKVector.h"
#pragma mark MVKLayer
@@ -115,7 +115,7 @@
static MVKLayerManager* globalManager();
protected:
- std::vector<MVKLayer> _layers;
+ MVKVectorInline<MVKLayer, 1> _layers;
};
diff --git a/MoltenVK/MoltenVK/Utility/MVKVector.h b/MoltenVK/MoltenVK/Utility/MVKVector.h
index 3746100..eac2b57 100755
--- a/MoltenVK/MoltenVK/Utility/MVKVector.h
+++ b/MoltenVK/MoltenVK/Utility/MVKVector.h
@@ -42,8 +42,7 @@
// Like std::vector, MVKVector is guaranteed to use contiguous memory, so if the
// preallocated number of elements are exceeded, all elements are then in heap.
// MVKVector supports just the necessary members to be compatible with MoltenVK
-// If C++17 will be the default in the future, code can be simplified quite
-// a bit.
+// If C++17 will be the default in the future, code can be simplified quite a bit.
//
// Example:
//
@@ -55,8 +54,7 @@
// vector.emplace_back( 4 );
//
// If you don't need any inline storage use
-// MVKVectorDefault<int> vector; // this is essentially the same as using
-// // std::vector
+// MVKVectorDefault<int> vector; // this is essentially the same as using std::vector
//
// Passing MVKVectorInline to a function would require to use the same template
// parameters that have been used for declaration. To avoid this MVKVectorInline
@@ -182,6 +180,7 @@
virtual const Type * const back() const = 0;
virtual Type * &back() = 0;
virtual const Type * const *data() const = 0;
+ virtual Type * *data() = 0;
virtual size_t size() const = 0;
virtual bool empty() const = 0;
@@ -670,7 +669,7 @@
// this is the growth strategy -> adjust to your needs
size_t vector_GetNextCapacity() const
{
- constexpr auto ELEMENTS_FOR_64_BYTES = 64 / sizeof( Type );
+ constexpr auto ELEMENTS_FOR_64_BYTES = 64 / sizeof( Type* );
constexpr auto MINIMUM_CAPACITY = ELEMENTS_FOR_64_BYTES > 4 ? ELEMENTS_FOR_64_BYTES : 4;
const auto current_capacity = capacity();
return MINIMUM_CAPACITY + ( 3 * current_capacity ) / 2;
@@ -830,6 +829,7 @@
const Type * const back() const override { return alc.ptr[alc.num_elements_used - 1]; }
Type * &back() override { return alc.ptr[alc.num_elements_used - 1]; }
const Type * const *data() const override { return &alc.ptr[0]; }
+ Type * *data() override { return &alc.ptr[0]; }
size_t size() const override { return alc.num_elements_used; }
bool empty() const override { return alc.num_elements_used == 0; }
@@ -931,6 +931,21 @@
}
}
+ void erase( const iterator first, const iterator last )
+ {
+ if( first.is_valid() )
+ {
+ size_t last_pos = last.is_valid() ? last.get_position() : size();
+ size_t n = last_pos - first.get_position();
+ alc.num_elements_used -= n;
+
+ for( size_t i = first.get_position(), e = last_pos; i < alc.num_elements_used && e < alc.num_elements_used + n; ++i, ++e )
+ {
+ alc.ptr[i] = alc.ptr[e];
+ }
+ }
+ }
+
// adds t before position it and automatically resizes vector if necessary
void insert( const iterator it, const Type *t )
{