diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md index 15bcbe50..a3a2ce3b 100644 --- a/Docs/Whats_New.md +++ b/Docs/Whats_New.md @@ -21,6 +21,7 @@ Released TBD - 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 92139015..036605c3 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdDispatch.h +++ b/MoltenVK/MoltenVK/Commands/MVKCmdDispatch.h @@ -20,7 +20,6 @@ #include "MVKCommand.h" #include "MVKMTLResourceBindings.h" -#include #import diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.h b/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.h index d5bf3dd7..1cfd37eb 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.h +++ b/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.h @@ -20,7 +20,6 @@ #include "MVKCommand.h" #include "MVKVector.h" -#include class MVKCommandBuffer; class MVKPipeline; @@ -54,9 +53,9 @@ private: VkPipelineStageFlags _srcStageMask; VkPipelineStageFlags _dstStageMask; VkDependencyFlags _dependencyFlags; - std::vector _memoryBarriers; - std::vector _bufferMemoryBarriers; - std::vector _imageMemoryBarriers; + MVKVectorInline _memoryBarriers; + MVKVectorInline _bufferMemoryBarriers; + MVKVectorInline _imageMemoryBarriers; }; diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.mm b/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.mm index 18fe1272..c65adced 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.mm @@ -77,7 +77,7 @@ void MVKCmdPipelineBarrier::encode(MVKCommandEncoder* cmdEncoder) { afterStages: srcStages beforeStages: dstStages]; } - std::vector> resources; + MVKVectorInline, 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 2658c0f3..0f84ff04 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.h +++ b/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.h @@ -20,7 +20,6 @@ #include "MVKCommand.h" #include "MVKVector.h" -#include #import @@ -85,7 +84,7 @@ public: #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 @@ public: MVKCmdExecuteCommands(MVKCommandTypePool* pool); private: - std::vector _secondaryCommandBuffers; + MVKVectorInline _secondaryCommandBuffers; }; #pragma mark - diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.h b/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.h index 231924a4..a7b9486b 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 +#include "MVKVector.h" #import @@ -68,9 +68,9 @@ protected: bool _isDstCompressed; bool _canCopyFormats; bool _useTempBuffer; - std::vector _imageCopyRegions; - std::vector _srcTmpBuffImgCopies; - std::vector _dstTmpBuffImgCopies; + MVKVectorInline _imageCopyRegions; + MVKVectorInline _srcTmpBuffImgCopies; + MVKVectorInline _dstTmpBuffImgCopies; size_t _tmpBuffSize; MVKCommandUse _commandUse; }; @@ -117,7 +117,7 @@ protected: MTLRenderPassDescriptor* _mtlRenderPassDescriptor; MTLSamplerMinMagFilter _mtlFilter; MVKRPSKeyBlitImg _blitKey; - std::vector _mvkImageBlitRenders; + MVKVectorInline _mvkImageBlitRenders; }; @@ -157,11 +157,11 @@ protected: VkImageLayout _srcLayout; MVKImage* _dstImage; VkImageLayout _dstLayout; - std::vector _expansionRegions; - std::vector _copyRegions; MVKImageDescriptorData _transferImageData; MTLRenderPassDescriptor* _mtlRenderPassDescriptor; - std::vector _mtlResolveSlices; + MVKVectorInline _expansionRegions; + MVKVectorInline _copyRegions; + MVKVectorInline _mtlResolveSlices; }; @@ -186,7 +186,7 @@ protected: MVKBuffer* _srcBuffer; MVKBuffer* _dstBuffer; - std::vector _mtlBuffCopyRegions; + MVKVectorInline _mtlBuffCopyRegions; }; @@ -215,7 +215,7 @@ protected: MVKBuffer* _buffer; MVKImage* _image; VkImageLayout _imageLayout; - std::vector _bufferImageCopyRegions; + MVKVectorInline _bufferImageCopyRegions; bool _toImage = false; }; @@ -241,8 +241,8 @@ protected: void populateVertices(float attWidth, float attHeight); void populateVertices(VkClearRect& clearRect, float attWidth, float attHeight); - std::vector _clearRects; - std::vector _vertices; + MVKVectorInline _clearRects; + MVKVectorInline _vertices; simd::float4 _clearColors[kMVKClearAttachmentCount]; VkClearValue _vkClearValues[kMVKClearAttachmentCount]; MVKRPSKeyClearAtt _rpsKey; @@ -278,7 +278,7 @@ protected: MVKImage* _image; VkImageLayout _imgLayout; - std::vector _subresourceRanges; + MVKVectorInline _subresourceRanges; MTLClearColor _mtlColorClearValue; double _mtlDepthClearValue; uint32_t _mtlStencilClearValue; @@ -330,7 +330,7 @@ protected: MVKBuffer* _dstBuffer; VkDeviceSize _dstOffset; VkDeviceSize _dataSize; - std::vector _srcDataCache; + MVKVectorDefault _srcDataCache; }; diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h index 18f6dfee..ddeae21f 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 #include class MVKCommandPool; @@ -240,7 +240,7 @@ protected: /*** Holds a collection of active queries for each query pool. */ -typedef std::unordered_map> MVKActivatedQueries; +typedef std::unordered_map> 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 40dfbd9d..f43a4954 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm @@ -398,7 +398,7 @@ void MVKCommandEncoder::finalizeDrawState(MVKGraphicsStage stage) { // Clears the render area of the framebuffer attachments. void MVKCommandEncoder::clearRenderArea() { - vector clearAtts; + MVKVectorInline 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 901f4575..9af81973 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h +++ b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h @@ -519,11 +519,11 @@ protected: void resetImpl() override; void markDirty() override; - MVKVectorDefault _bufferBindings; - MVKVectorDefault _textureBindings; - MVKVectorDefault _samplerStateBindings; - MVKVectorDefault _swizzleConstants; - MVKVectorDefault _bufferSizes; + MVKVectorInline _bufferBindings; + MVKVectorInline _textureBindings; + MVKVectorInline _samplerStateBindings; + MVKVectorInline _swizzleConstants; + MVKVectorInline _bufferSizes; MVKMTLBufferBinding _swizzleBufferBinding; MVKMTLBufferBinding _bufferSizeBufferBinding; diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandPool.mm b/MoltenVK/MoltenVK/Commands/MVKCommandPool.mm index 1c5d51e2..668089fd 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandPool.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCommandPool.mm @@ -123,6 +123,9 @@ void MVKCommandPool::trim() { _cmdDispatchIndirectPool.clear(); _cmdPushDescriptorSetPool.clear(); _cmdPushSetWithTemplatePool.clear(); + _cmdDebugMarkerBeginPool.clear(); + _cmdDebugMarkerEndPool.clear(); + _cmdDebugMarkerInsertPool.clear(); } @@ -131,9 +134,9 @@ void MVKCommandPool::trim() { 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 @@ MVKCommandPool::MVKCommandPool(MVKDevice* device, _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 @@ MVKCommandPool::MVKCommandPool(MVKDevice* device, _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 eef16f64..c5ff171a 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 +#include "MVKVector.h" class MVKMTLBufferAllocationPool; @@ -97,7 +97,7 @@ protected: NSUInteger _nextOffset; NSUInteger _allocationLength; NSUInteger _mtlBufferLength; - std::vector> _mtlBuffers; + MVKVectorInline, 64> _mtlBuffers; MVKDevice* _device; }; @@ -142,7 +142,7 @@ public: ~MVKMTLBufferAllocator() override; protected: - std::vector _regionPools; + MVKVectorInline _regionPools; NSUInteger _maxAllocationLength; bool _makeThreadSafe; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.h b/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.h index f5eb7b6c..9b80795f 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.h @@ -24,7 +24,6 @@ #include #include #include -#include class MVKDescriptorPool; class MVKDescriptorBinding; @@ -118,7 +117,7 @@ protected: MVKDescriptorSetLayout* _layout; VkDescriptorSetLayoutBinding _info; - std::vector _immutableSamplers; + MVKVectorInline _immutableSamplers; MVKShaderResourceBinding _mtlResourceIndexOffsets; bool _applyToStage[kMVKShaderStageMax]; }; @@ -272,13 +271,13 @@ protected: MVKDescriptorSet* _pDescSet; MVKDescriptorSetLayoutBinding* _pBindingLayout; - std::vector _imageBindings; - std::vector _bufferBindings; - std::vector _texelBufferBindings; - std::vector> _mtlBuffers; - std::vector _mtlBufferOffsets; - std::vector> _mtlTextures; - std::vector> _mtlSamplers; + MVKVectorInline _imageBindings; + MVKVectorInline _bufferBindings; + MVKVectorInline _texelBufferBindings; + MVKVectorInline, 1> _mtlBuffers; + MVKVectorInline _mtlBufferOffsets; + MVKVectorInline, 1> _mtlTextures; + MVKVectorInline, 1> _mtlSamplers; bool _hasDynamicSamplers; }; @@ -324,7 +323,7 @@ protected: MVKDescriptorBinding* getBinding(uint32_t binding); MVKDescriptorSetLayout* _pLayout = nullptr; - std::vector _bindings; + MVKVectorInline _bindings; }; @@ -408,7 +407,7 @@ protected: void propogateDebugName() override {} VkDescriptorUpdateTemplateTypeKHR _type; - std::vector _entries; + MVKVectorInline _entries; }; #pragma mark - diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h index e087ea1b..3ce75903 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 #include #include @@ -67,6 +67,10 @@ class MVKCommandResourceFactory; 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 @@ protected: void initMemoryProperties(); void initExtensions(); MVKExtensionList* getSupportedExtensions(const char* pLayerName = nullptr); - std::vector& getQueueFamilies(); + MVKVector& getQueueFamilies(); void initPipelineCacheUUID(); MTLFeatureSet getHighestMTLFeatureSet(); uint64_t getSpirvCrossRevision(); @@ -343,7 +347,7 @@ protected: VkPhysicalDeviceProperties _properties; VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT _texelBuffAlignProperties; VkPhysicalDeviceMemoryProperties _memoryProperties; - std::vector _queueFamilies; + MVKVectorInline _queueFamilies; uint32_t _allMemoryTypes; uint32_t _hostVisibleMemoryTypes; uint32_t _hostCoherentMemoryTypes; @@ -677,8 +681,8 @@ protected: MVKPhysicalDevice* _physicalDevice; MVKCommandResourceFactory* _commandResourceFactory; MTLCompileOptions* _mtlCompileOptions; - std::vector> _queuesByQueueFamilyIndex; - std::vector _resources; + MVKVectorInline, kMVKQueueFamilyCount> _queuesByQueueFamilyIndex; + MVKVectorInline _resources; std::mutex _rezLock; std::mutex _perfLock; id _globalVisibilityResultMTLBuffer; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm index e9e481f7..438674cf 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm @@ -606,16 +606,16 @@ VkResult MVKPhysicalDevice::getPresentRectangles(MVKSurface* surface, // 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& MVKPhysicalDevice::getQueueFamilies() { +MVKVector& 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 @@ vector& MVKPhysicalDevice::getQueueFamilies() { // 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 @@ vector& MVKPhysicalDevice::getQueueFamilies() { VkResult MVKPhysicalDevice::getQueueFamilyProperties(uint32_t* pCount, VkQueueFamilyProperties* pQueueFamilyProperties) { - vector 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 @@ void MVKPhysicalDevice::initMetalFeatures() { _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 @@ void MVKDevice::freeMemory(MVKDeviceMemory* mvkDevMem, 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 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 lock(_rezLock); mvkRemoveFirstOccurance(_resources, rez); @@ -2488,7 +2490,7 @@ void MVKDevice::enableExtensions(const VkDeviceCreateInfo* pCreateInfo) { // Create the command queues void MVKDevice::initQueues(const VkDeviceCreateInfo* pCreateInfo) { - vector 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 c87b443c..9d468ef4 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDeviceMemory.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDeviceMemory.h @@ -19,7 +19,7 @@ #pragma once #include "MVKDevice.h" -#include +#include "MVKVector.h" #include #import @@ -128,8 +128,8 @@ protected: void freeHostMemory(); MVKResource* getDedicatedResource(); - std::vector _buffers; - std::vector _images; + MVKVectorInline _buffers; + MVKVectorInline _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 9fd9ef33..e7a08529 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKFramebuffer.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKFramebuffer.h @@ -20,7 +20,7 @@ #include "MVKDevice.h" #include "MVKImage.h" -#include +#include "MVKVector.h" #pragma mark MVKFramebuffer @@ -56,6 +56,6 @@ protected: VkExtent2D _extent; uint32_t _layerCount; - std::vector _attachments; + MVKVectorInline _attachments; }; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.h b/MoltenVK/MoltenVK/GPUObjects/MVKImage.h index 0cbf0d04..68fdd238 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.h @@ -257,7 +257,7 @@ protected: VkPipelineStageFlags dstStageMask, VkImageMemoryBarrier* pImageMemoryBarrier); - std::vector _subresources; + MVKVectorInline _subresources; std::unordered_map> _mtlTextureViews; VkExtent3D _extent; uint32_t _mipLevels; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.h b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.h index 5771fe6b..4bbef89a 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 #include #include #include @@ -100,7 +100,7 @@ public: 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 @@ protected: MVKConfiguration _mvkConfig; VkApplicationInfo _appInfo; - std::vector _physicalDevices; + MVKVectorInline _physicalDevices; + MVKVectorInline _debugReportCallbacks; + MVKVectorInline _debugUtilMessengers; std::unordered_map _entryPoints; - std::vector _debugReportCallbacks; - std::vector _debugUtilMessengers; std::mutex _dcbLock; bool _hasDebugReportCallbacks; bool _hasDebugUtilsMessengers; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm index ce9fa406..0bb9bef6 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm @@ -666,7 +666,7 @@ void MVKInstance::initConfig() { 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 23bdb68a..90d86f1c 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.h @@ -20,7 +20,6 @@ #include "MVKDevice.h" #include "MVKVector.h" -#include #include #include @@ -29,7 +28,8 @@ class MVKCommandBuffer; 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 @@ public: virtual void endQuery(uint32_t query, MVKCommandEncoder* cmdEncoder); /** Finishes the specified queries and marks them as available. */ - virtual void finishQueries(std::vector& queries); + virtual void finishQueries(MVKVector& 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 @@ public: 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 @@ protected: Available /**< Query is available to the host. */ }; - std::vector _availability; + MVKVectorInline _availability; + MVKVectorInline _deferredCopies; uint32_t _queryElementCount; std::mutex _availabilityLock; std::condition_variable _availabilityBlocker; std::mutex _deferredCopiesLock; - MVKVectorInline _deferredCopies; }; @@ -143,7 +143,7 @@ protected: class MVKTimestampQueryPool : public MVKQueryPool { public: - void finishQueries(std::vector& queries) override; + void finishQueries(MVKVector& queries) override; #pragma mark Construction @@ -156,7 +156,7 @@ protected: id 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 _timestamps; + MVKVectorInline _timestamps; }; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.mm b/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.mm index 00902449..b174d07d 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.mm @@ -47,7 +47,7 @@ void MVKQueryPool::endQuery(uint32_t query, MVKCommandEncoder* cmdEncoder) { } // Mark queries as available -void MVKQueryPool::finishQueries(vector& queries) { +void MVKQueryPool::finishQueries(MVKVector& queries) { lock_guard 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 @@ void MVKQueryPool::deferCopyResults(uint32_t firstQuery, #pragma mark MVKTimestampQueryPool // Update timestamp values, then mark queries as available -void MVKTimestampQueryPool::finishQueries(vector& queries) { +void MVKTimestampQueryPool::finishQueries(MVKVector& queries) { uint64_t ts = mvkGetTimestamp(); for (uint32_t qry : queries) { _timestamps[qry] = ts; } @@ -215,7 +215,8 @@ void MVKTimestampQueryPool::encodeSetResultBuffer(MVKCommandEncoder* cmdEncoder, #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 0cd2c53e..d41bfee8 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 #include #import @@ -65,7 +64,7 @@ protected: MVKPhysicalDevice* _physicalDevice; uint32_t _queueFamilyIndex; VkQueueFamilyProperties _properties; - std::vector> _mtlQueues; + MVKVectorInline, kMVKQueueCountPerQueueFamily> _mtlQueues; std::mutex _qLock; }; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.h b/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.h index a93dba69..70b6ea44 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.h @@ -20,7 +20,6 @@ #include "MVKDevice.h" #include "MVKVector.h" -#include #import @@ -28,6 +27,10 @@ class MVKRenderPass; 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 @@ public: * 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& clearAtts, + void populateClearAttachments(MVKVector& clearAtts, MVKVector& clearValues); /** Constructs an instance for the specified parent renderpass. */ @@ -85,10 +88,10 @@ private: MVKRenderPass* _renderPass; uint32_t _subpassIndex; - std::vector _inputAttachments; - std::vector _colorAttachments; - std::vector _resolveAttachments; - std::vector _preserveAttachments; + MVKVectorInline _inputAttachments; + MVKVectorInline _colorAttachments; + MVKVectorInline _resolveAttachments; + MVKVectorInline _preserveAttachments; VkAttachmentReference _depthStencilAttachment; id _mtlDummyTex = nil; }; @@ -168,9 +171,9 @@ protected: void propogateDebugName() override {} - std::vector _subpasses; - std::vector _attachments; - std::vector _subpassDependencies; + MVKVectorInline _attachments; + MVKVectorInline _subpasses; + MVKVectorInline _subpassDependencies; }; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.mm b/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.mm index 52609af6..4ee7b1c7 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.mm @@ -165,7 +165,7 @@ void MVKRenderSubpass::populateMTLRenderPassDescriptor(MTLRenderPassDescriptor* } } -void MVKRenderSubpass::populateClearAttachments(vector& clearAtts, +void MVKRenderSubpass::populateClearAttachments(MVKVector& clearAtts, MVKVector& clearValues) { VkClearAttachment cAtt; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.h b/MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.h index d9a8f843..4ef1dfb5 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 #include -#include #include #import @@ -151,7 +151,7 @@ protected: void merge(MVKShaderLibraryCache* other); MVKVulkanAPIDeviceObject* _owner; - std::vector> _shaderLibraries; + MVKVectorInline, 4> _shaderLibraries; }; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.h b/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.h index 20e3dbe7..802f2adc 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.h @@ -19,7 +19,7 @@ #pragma once #include "MVKDevice.h" -#include +#include "MVKVector.h" class MVKSwapchainImage; class MVKWatermark; @@ -111,7 +111,7 @@ protected: CAMetalLayer* _mtlLayer; MVKWatermark* _licenseWatermark; - std::vector _surfaceImages; + MVKVectorInline _surfaceImages; std::atomic _currentAcquisitionID; CGSize _mtlLayerOrigDrawSize; MVKSwapchainPerformance _performanceStatistics; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKSync.h b/MoltenVK/MoltenVK/GPUObjects/MVKSync.h index fa5f6477..24ac84fd 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKSync.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKSync.h @@ -23,7 +23,6 @@ #include #include #include -#include class MVKFenceSitter; diff --git a/MoltenVK/MoltenVK/Layers/MVKLayers.h b/MoltenVK/MoltenVK/Layers/MVKLayers.h index b93742a0..e4bbc42f 100644 --- a/MoltenVK/MoltenVK/Layers/MVKLayers.h +++ b/MoltenVK/MoltenVK/Layers/MVKLayers.h @@ -20,7 +20,7 @@ #include "MVKBaseObject.h" #include "MVKExtensions.h" -#include +#include "MVKVector.h" #pragma mark MVKLayer @@ -115,7 +115,7 @@ public: static MVKLayerManager* globalManager(); protected: - std::vector _layers; + MVKVectorInline _layers; }; diff --git a/MoltenVK/MoltenVK/Utility/MVKVector.h b/MoltenVK/MoltenVK/Utility/MVKVector.h index 37461004..eac2b57d 100755 --- a/MoltenVK/MoltenVK/Utility/MVKVector.h +++ b/MoltenVK/MoltenVK/Utility/MVKVector.h @@ -42,8 +42,7 @@ using MVKVector = std::vector; // 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 @@ using MVKVector = std::vector; // vector.emplace_back( 4 ); // // If you don't need any inline storage use -// MVKVectorDefault vector; // this is essentially the same as using -// // std::vector +// MVKVectorDefault 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 @@ public: 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 @@ private: // 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 @@ public: 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 @@ public: } } + 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 ) {