From 5a216ab1f86122339a8d3b0e4bf3ed3f8802245b Mon Sep 17 00:00:00 2001 From: Evan Tang Date: Tue, 13 Jun 2023 11:41:36 -0500 Subject: [PATCH 1/5] Refcounting cleanup - Use relaxed atomics where possible - Calling operator= on a refcounted object should not reinitialize the refcount --- MoltenVK/MoltenVK/Utility/MVKBaseObject.h | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/MoltenVK/MoltenVK/Utility/MVKBaseObject.h b/MoltenVK/MoltenVK/Utility/MVKBaseObject.h index d2fcb9e8..dd156b3e 100644 --- a/MoltenVK/MoltenVK/Utility/MVKBaseObject.h +++ b/MoltenVK/MoltenVK/Utility/MVKBaseObject.h @@ -143,7 +143,7 @@ public: * Called when this instance has been retained as a reference by another object, * indicating that this instance will not be deleted until that reference is released. */ - void retain() { _refCount++; } + void retain() { _refCount.fetch_add(1, std::memory_order_relaxed); } /** * Called when this instance has been released as a reference from another object. @@ -154,7 +154,7 @@ public: * Note that the destroy() function is called on the BaseClass. * Releasing will not call any overridden destroy() function in a descendant class. */ - void release() { if (--_refCount == 0) { BaseClass::destroy(); } } + void release() { if (_refCount.fetch_sub(1, std::memory_order_acq_rel) == 1) { BaseClass::destroy(); } } /** * Marks this instance as destroyed. If all previous references to this instance @@ -166,15 +166,10 @@ public: MVKReferenceCountingMixin() : _refCount(1) {} /** Copy starts with fresh reference counts. */ - MVKReferenceCountingMixin(const MVKReferenceCountingMixin& other) { - _refCount = 1; - } + MVKReferenceCountingMixin(const MVKReferenceCountingMixin& other) : _refCount(1) {} - /** Copy starts with fresh reference counts. */ - MVKReferenceCountingMixin& operator=(const MVKReferenceCountingMixin& other) { - _refCount = 1; - return *this; - } + /** Don't overwrite refcounted objects. */ + MVKReferenceCountingMixin& operator=(const MVKReferenceCountingMixin& other) = delete; protected: std::atomic _refCount; From aeae18d48b362e133718c2a1a3f4099d4b17d230 Mon Sep 17 00:00:00 2001 From: Evan Tang Date: Tue, 13 Jun 2023 12:00:31 -0500 Subject: [PATCH 2/5] Remove getBaseObject Nothing used it, and you should always be able to `static_cast` for any object without a crazy inheritance tree --- MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h | 1 - .../MoltenVK/Commands/MVKMTLBufferAllocation.h | 1 - MoltenVK/MoltenVK/GPUObjects/MVKDevice.h | 14 +------------- MoltenVK/MoltenVK/GPUObjects/MVKQueue.h | 1 - MoltenVK/MoltenVK/Utility/MVKBaseObject.h | 2 +- 5 files changed, 2 insertions(+), 17 deletions(-) diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h index 59242aff..8f8b2c0b 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h +++ b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h @@ -182,7 +182,6 @@ protected: friend class MVKCommandEncoder; friend class MVKCommandPool; - MVKBaseObject* getBaseObject() override { return this; }; void propagateDebugName() override {} void init(const VkCommandBufferAllocateInfo* pAllocateInfo); bool canExecute(); diff --git a/MoltenVK/MoltenVK/Commands/MVKMTLBufferAllocation.h b/MoltenVK/MoltenVK/Commands/MVKMTLBufferAllocation.h index 474a0a16..2be98144 100644 --- a/MoltenVK/MoltenVK/Commands/MVKMTLBufferAllocation.h +++ b/MoltenVK/MoltenVK/Commands/MVKMTLBufferAllocation.h @@ -99,7 +99,6 @@ public: protected: friend class MVKMTLBufferAllocation; - MVKBaseObject* getBaseObject() override { return this; }; MVKMTLBufferAllocation* newObject() override; void returnAllocationUnlocked(MVKMTLBufferAllocation* ba); void returnAllocation(MVKMTLBufferAllocation* ba); diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h index b6b462ad..125bf9aa 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h @@ -959,13 +959,9 @@ public: bool isUsingPipelineStageMetalArgumentBuffers() { return isUsingMetalArgumentBuffers() && !_device->_pMetalFeatures->descriptorSetArgumentBuffers; }; /** Constructs an instance for the specified device. */ - MVKDeviceTrackingMixin(MVKDevice* device) : _device(device) { assert(_device); } - - virtual ~MVKDeviceTrackingMixin() {} + MVKDeviceTrackingMixin(MVKDevice* device) : _device(device) { assert(_device); } protected: - virtual MVKBaseObject* getBaseObject() = 0; - MVKDevice* _device; }; @@ -980,9 +976,6 @@ public: /** Constructs an instance for the specified device. */ MVKBaseDeviceObject(MVKDevice* device) : MVKDeviceTrackingMixin(device) {} - -protected: - MVKBaseObject* getBaseObject() override { return this; }; }; @@ -999,10 +992,6 @@ public: /** Constructs an instance for the specified device. */ MVKVulkanAPIDeviceObject(MVKDevice* device) : MVKDeviceTrackingMixin(device) {} - -protected: - MVKBaseObject* getBaseObject() override { return this; }; - }; @@ -1055,7 +1044,6 @@ public: protected: T* newObject() override { return new T(_device); } - MVKBaseObject* getBaseObject() override { return this; }; }; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKQueue.h b/MoltenVK/MoltenVK/GPUObjects/MVKQueue.h index b4509f0b..086410e8 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKQueue.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKQueue.h @@ -135,7 +135,6 @@ protected: friend class MVKQueueCommandBufferSubmission; friend class MVKQueuePresentSurfaceSubmission; - MVKBaseObject* getBaseObject() override { return this; }; void propagateDebugName() override; void initName(); void initExecQueue(); diff --git a/MoltenVK/MoltenVK/Utility/MVKBaseObject.h b/MoltenVK/MoltenVK/Utility/MVKBaseObject.h index dd156b3e..41942802 100644 --- a/MoltenVK/MoltenVK/Utility/MVKBaseObject.h +++ b/MoltenVK/MoltenVK/Utility/MVKBaseObject.h @@ -105,7 +105,7 @@ public: /** Destroys this object. Default behaviour simply deletes it. Subclasses may override to delay deletion. */ virtual void destroy() { delete this; } - virtual ~MVKBaseObject() {} + virtual ~MVKBaseObject() {} protected: static VkResult reportResult(MVKBaseObject* mvkObj, VkResult vkRslt, MVKConfigLogLevel logLevel, const char* format, va_list args) __printflike(4, 0); From 89195dc7254c56c50c7cc64a17b6a0a12ff075d6 Mon Sep 17 00:00:00 2001 From: Evan Tang Date: Tue, 13 Jun 2023 12:13:21 -0500 Subject: [PATCH 3/5] Remove count from mvkStringsAreEqual It doesn't do anything, and we don't want anyone to think it does something --- MoltenVK/MoltenVK/Utility/MVKFoundation.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MoltenVK/MoltenVK/Utility/MVKFoundation.h b/MoltenVK/MoltenVK/Utility/MVKFoundation.h index 1097afb5..16c7fd2e 100644 --- a/MoltenVK/MoltenVK/Utility/MVKFoundation.h +++ b/MoltenVK/MoltenVK/Utility/MVKFoundation.h @@ -598,7 +598,7 @@ bool mvkAreEqual(const T* pV1, const T* pV2, size_t count = 1) { * which works on individual chars or char arrays, not strings. * Returns false if either string is null. */ -static constexpr bool mvkStringsAreEqual(const char* pV1, const char* pV2, size_t count = 1) { +static constexpr bool mvkStringsAreEqual(const char* pV1, const char* pV2) { return pV1 && pV2 && (pV1 == pV2 || strcmp(pV1, pV2) == 0); } From 4ba3f335b4f73627e94645361bc35efce222dad2 Mon Sep 17 00:00:00 2001 From: Evan Tang Date: Tue, 13 Jun 2023 15:22:44 -0500 Subject: [PATCH 4/5] MVKArrayRef cleanup Make everything constexpr, remove direct access to members --- .../MoltenVK/Commands/MVKCommandBuffer.mm | 6 ++-- .../Commands/MVKCommandEncoderState.mm | 28 +++++++++--------- MoltenVK/MoltenVK/GPUObjects/MVKDescriptor.mm | 2 +- MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm | 2 +- MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm | 2 +- MoltenVK/MoltenVK/Utility/MVKFoundation.h | 29 ++++++++++--------- MoltenVK/MoltenVK/Vulkan/vulkan.mm | 2 +- 7 files changed, 37 insertions(+), 34 deletions(-) diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm index 72dde4f1..e92a57c1 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm @@ -472,8 +472,8 @@ void MVKCommandEncoder::beginRenderpass(MVKCommand* passCmd, _attachments.assign(attachments.begin(), attachments.end()); // Copy the sample positions array of arrays, one array of sample positions for each subpass index. - _subpassSamplePositions.resize(subpassSamplePositions.size); - for (uint32_t spSPIdx = 0; spSPIdx < subpassSamplePositions.size; spSPIdx++) { + _subpassSamplePositions.resize(subpassSamplePositions.size()); + for (uint32_t spSPIdx = 0; spSPIdx < subpassSamplePositions.size(); spSPIdx++) { _subpassSamplePositions[spSPIdx].assign(subpassSamplePositions[spSPIdx].begin(), subpassSamplePositions[spSPIdx].end()); } @@ -593,7 +593,7 @@ void MVKCommandEncoder::beginMetalRenderPass(MVKCommandUse cmdUse) { // and Metal will default to using default sample postions. if (_pDeviceMetalFeatures->programmableSamplePositions) { auto cstmSampPosns = getCustomSamplePositions(); - [mtlRPDesc setSamplePositions: cstmSampPosns.data count: cstmSampPosns.size]; + [mtlRPDesc setSamplePositions: cstmSampPosns.data() count: cstmSampPosns.size()]; } _mtlRenderEncoder = [_mtlCmdBuffer renderCommandEncoderWithDescriptor: mtlRPDesc]; diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm index 044dd96e..2817343d 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm @@ -58,7 +58,7 @@ void MVKViewportCommandEncoderState::setViewports(const MVKArrayRef uint32_t firstViewport, bool isSettingDynamically) { - size_t vpCnt = viewports.size; + size_t vpCnt = viewports.size(); uint32_t maxViewports = getDevice()->_pProperties->limits.maxViewports; if ((firstViewport + vpCnt > maxViewports) || (firstViewport >= maxViewports) || @@ -111,7 +111,7 @@ void MVKScissorCommandEncoderState::setScissors(const MVKArrayRef scis uint32_t firstScissor, bool isSettingDynamically) { - size_t sCnt = scissors.size; + size_t sCnt = scissors.size(); uint32_t maxScissors = getDevice()->_pProperties->limits.maxViewports; if ((firstScissor + sCnt > maxScissors) || (firstScissor >= maxScissors) || @@ -165,7 +165,7 @@ void MVKPushConstantsCommandEncoderState:: setPushConstants(uint32_t offset, MVK // Typically any MSL struct that contains a float4 will also have a size that is rounded up to a multiple of a float4 size. // Ensure that we pass along enough content to cover this extra space even if it is never actually accessed by the shader. size_t pcSizeAlign = getDevice()->_pMetalFeatures->pushConstantSizeAlignment; - size_t pcSize = pushConstants.size; + size_t pcSize = pushConstants.size(); size_t pcBuffSize = mvkAlignByteCount(offset + pcSize, pcSizeAlign); mvkEnsureSize(_pushConstants, pcBuffSize); copy(pushConstants.begin(), pushConstants.end(), _pushConstants.begin() + offset); @@ -488,7 +488,7 @@ void MVKResourcesCommandEncoderState::bindDescriptorSet(uint32_t descSetIndex, // Update dynamic buffer offsets uint32_t baseDynOfstIdx = dslMTLRezIdxOffsets.getMetalResourceIndexes().dynamicOffsetBufferIndex; uint32_t doCnt = descSet->getDynamicOffsetDescriptorCount(); - for (uint32_t doIdx = 0; doIdx < doCnt && dynamicOffsetIndex < dynamicOffsets.size; doIdx++) { + for (uint32_t doIdx = 0; doIdx < doCnt && dynamicOffsetIndex < dynamicOffsets.size(); doIdx++) { updateImplicitBuffer(_dynamicOffsets, baseDynOfstIdx + doIdx, dynamicOffsets[dynamicOffsetIndex++]); } @@ -797,8 +797,8 @@ void MVKGraphicsResourcesCommandEncoderState::encodeImpl(uint32_t stage) { }, [](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b, const MVKArrayRef s)->void { cmdEncoder->setComputeBytes(cmdEncoder->getMTLComputeEncoder(kMVKCommandUseTessellationVertexTessCtl), - s.data, - s.size * sizeof(uint32_t), + s.data(), + s.byteSize(), b.index); }, [](MVKCommandEncoder* cmdEncoder, MVKMTLTextureBinding& b)->void { @@ -848,8 +848,8 @@ void MVKGraphicsResourcesCommandEncoderState::encodeImpl(uint32_t stage) { }, [](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b, const MVKArrayRef s)->void { cmdEncoder->setVertexBytes(cmdEncoder->_mtlRenderEncoder, - s.data, - s.size * sizeof(uint32_t), + s.data(), + s.byteSize(), b.index); }, [](MVKCommandEncoder* cmdEncoder, MVKMTLTextureBinding& b)->void { @@ -881,8 +881,8 @@ void MVKGraphicsResourcesCommandEncoderState::encodeImpl(uint32_t stage) { }, [](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b, const MVKArrayRef s)->void { cmdEncoder->setComputeBytes(cmdEncoder->getMTLComputeEncoder(kMVKCommandUseTessellationVertexTessCtl), - s.data, - s.size * sizeof(uint32_t), + s.data(), + s.byteSize(), b.index); }, [](MVKCommandEncoder* cmdEncoder, MVKMTLTextureBinding& b)->void { @@ -914,8 +914,8 @@ void MVKGraphicsResourcesCommandEncoderState::encodeImpl(uint32_t stage) { }, [](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b, const MVKArrayRef s)->void { cmdEncoder->setVertexBytes(cmdEncoder->_mtlRenderEncoder, - s.data, - s.size * sizeof(uint32_t), + s.data(), + s.byteSize(), b.index); }, [](MVKCommandEncoder* cmdEncoder, MVKMTLTextureBinding& b)->void { @@ -947,8 +947,8 @@ void MVKGraphicsResourcesCommandEncoderState::encodeImpl(uint32_t stage) { }, [](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b, const MVKArrayRef s)->void { cmdEncoder->setFragmentBytes(cmdEncoder->_mtlRenderEncoder, - s.data, - s.size * sizeof(uint32_t), + s.data(), + s.byteSize(), b.index); }, [](MVKCommandEncoder* cmdEncoder, MVKMTLTextureBinding& b)->void { diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDescriptor.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDescriptor.mm index a3f02ea8..ac83d697 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDescriptor.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDescriptor.mm @@ -729,7 +729,7 @@ void MVKBufferDescriptor::bind(MVKCommandEncoder* cmdEncoder, MVKArrayRef dynamicOffsets, uint32_t& dynamicOffsetIndex) { MVKMTLBufferBinding bb; - NSUInteger bufferDynamicOffset = (usesDynamicBufferOffsets() && dynamicOffsets.size > dynamicOffsetIndex + NSUInteger bufferDynamicOffset = (usesDynamicBufferOffsets() && dynamicOffsets.size() > dynamicOffsetIndex ? dynamicOffsets[dynamicOffsetIndex++] : 0); if (_mvkBuffer) { bb.mtlBuffer = _mvkBuffer->getMTLBuffer(); diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm index acd50514..20bad33e 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm @@ -1530,7 +1530,7 @@ MVKArrayRef MVKPhysicalDevice::getQueueFamilies() { VkResult MVKPhysicalDevice::getQueueFamilyProperties(uint32_t* pCount, VkQueueFamilyProperties* pQueueFamilyProperties) { auto qFams = getQueueFamilies(); - uint32_t qfCnt = uint32_t(qFams.size); + uint32_t qfCnt = uint32_t(qFams.size()); // If properties aren't actually being requested yet, simply update the returned count if ( !pQueueFamilyProperties ) { diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm index e3da96b3..779eb75a 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm @@ -49,7 +49,7 @@ void MVKPipelineLayout::bindDescriptorSets(MVKCommandEncoder* cmdEncoder, MVKArrayRef dynamicOffsets) { if (!cmdEncoder) { clearConfigurationResult(); } uint32_t dynamicOffsetIndex = 0; - size_t dsCnt = descriptorSets.size; + size_t dsCnt = descriptorSets.size(); for (uint32_t dsIdx = 0; dsIdx < dsCnt; dsIdx++) { MVKDescriptorSet* descSet = descriptorSets[dsIdx]; uint32_t dslIdx = firstSet + dsIdx; diff --git a/MoltenVK/MoltenVK/Utility/MVKFoundation.h b/MoltenVK/MoltenVK/Utility/MVKFoundation.h index 16c7fd2e..8ea9f658 100644 --- a/MoltenVK/MoltenVK/Utility/MVKFoundation.h +++ b/MoltenVK/MoltenVK/Utility/MVKFoundation.h @@ -478,20 +478,23 @@ std::size_t mvkHash(const N* pVals, std::size_t count = 1, std::size_t seed = 53 */ template struct MVKArrayRef { - Type* data; - const size_t size; +public: + constexpr const Type* begin() const { return _data; } + constexpr const Type* end() const { return &_data[_size]; } + constexpr const Type* data() const { return _data; } + constexpr Type* begin() { return _data; } + constexpr Type* end() { return &_data[_size]; } + constexpr Type* data() { return _data; } + constexpr const size_t size() const { return _size; } + constexpr const size_t byteSize() const { return _size * sizeof(Type); } + constexpr const Type& operator[]( const size_t i ) const { return _data[i]; } + constexpr Type& operator[]( const size_t i ) { return _data[i]; } + constexpr MVKArrayRef() : MVKArrayRef(nullptr, 0) {} + constexpr MVKArrayRef(Type* d, size_t s) : _data(d), _size(s) {} - const Type* begin() const { return data; } - const Type* end() const { return &data[size]; } - const Type& operator[]( const size_t i ) const { return data[i]; } - Type& operator[]( const size_t i ) { return data[i]; } - MVKArrayRef& operator=(const MVKArrayRef& other) { - data = other.data; - *(size_t*)&size = other.size; - return *this; - } - MVKArrayRef() : MVKArrayRef(nullptr, 0) {} - MVKArrayRef(Type* d, size_t s) : data(d), size(s) {} +protected: + Type* _data; + size_t _size; }; /** Ensures the size of the specified container is at least the specified size. */ diff --git a/MoltenVK/MoltenVK/Vulkan/vulkan.mm b/MoltenVK/MoltenVK/Vulkan/vulkan.mm index cfa133fb..c44dd7d1 100644 --- a/MoltenVK/MoltenVK/Vulkan/vulkan.mm +++ b/MoltenVK/MoltenVK/Vulkan/vulkan.mm @@ -1964,7 +1964,7 @@ static void mvkCmdBeginRenderPass( MVKAddCmdFrom5Thresholds(BeginRenderPass, pRenderPassBegin->clearValueCount, 1, 2, - attachments.size, 0, 1, 2, + attachments.size(), 0, 1, 2, commandBuffer, pRenderPassBegin, pSubpassBeginInfo, From 27f4f6a6a017cb7e9ddad72f7fb7b87f85707788 Mon Sep 17 00:00:00 2001 From: Evan Tang Date: Thu, 15 Jun 2023 13:24:58 -0500 Subject: [PATCH 5/5] Use MVKArrayRef, not const MVKArrayRef It's very easy to accidentally un-const a `const MVKArrayRef`, since ArrayRefs are meant to be passed by value --- MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h | 2 +- MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm | 2 +- .../MoltenVK/Commands/MVKCommandEncoderState.h | 8 ++++---- .../Commands/MVKCommandEncoderState.mm | 18 +++++++++--------- MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.h | 4 ++-- MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.mm | 4 ++-- MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.h | 10 +++++----- MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.mm | 10 +++++----- MoltenVK/MoltenVK/Utility/MVKFoundation.h | 18 ++++++++---------- MoltenVK/MoltenVK/Utility/MVKSmallVector.h | 8 ++++---- 10 files changed, 41 insertions(+), 43 deletions(-) diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h index 8f8b2c0b..07b4c202 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h +++ b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h @@ -143,7 +143,7 @@ public: bool _needsVisibilityResultMTLBuffer; /** Called when a MVKCmdExecuteCommands is added to this command buffer. */ - void recordExecuteCommands(const MVKArrayRef secondaryCommandBuffers); + void recordExecuteCommands(MVKArrayRef secondaryCommandBuffers); /** Called when a timestamp command is added. */ void recordTimestampCommand(); diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm index e92a57c1..5f32996e 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm @@ -310,7 +310,7 @@ MVKCommandBuffer::~MVKCommandBuffer() { } // Promote the initial visibility buffer and indication of timestamp use from the secondary buffers. -void MVKCommandBuffer::recordExecuteCommands(const MVKArrayRef secondaryCommandBuffers) { +void MVKCommandBuffer::recordExecuteCommands(MVKArrayRef secondaryCommandBuffers) { for (MVKCommandBuffer* cmdBuff : secondaryCommandBuffers) { if (cmdBuff->_needsVisibilityResultMTLBuffer) { _needsVisibilityResultMTLBuffer = true; } if (cmdBuff->_hasStageCounterTimestampCommand) { _hasStageCounterTimestampCommand = true; } diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h index 06152dd7..6dbeb647 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h +++ b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h @@ -143,7 +143,7 @@ public: * The isSettingDynamically indicates that the scissor is being changed dynamically, * which is only allowed if the pipeline was created as VK_DYNAMIC_STATE_SCISSOR. */ - void setViewports(const MVKArrayRef viewports, + void setViewports(MVKArrayRef viewports, uint32_t firstViewport, bool isSettingDynamically); @@ -171,7 +171,7 @@ public: * The isSettingDynamically indicates that the scissor is being changed dynamically, * which is only allowed if the pipeline was created as VK_DYNAMIC_STATE_SCISSOR. */ - void setScissors(const MVKArrayRef scissors, + void setScissors(MVKArrayRef scissors, uint32_t firstScissor, bool isSettingDynamically); @@ -457,7 +457,7 @@ protected: contents[index] = value; } - void assertMissingSwizzles(bool needsSwizzle, const char* stageName, const MVKArrayRef texBindings); + void assertMissingSwizzles(bool needsSwizzle, const char* stageName, MVKArrayRef texBindings); void encodeMetalArgumentBuffer(MVKShaderStage stage); virtual void bindMetalArgumentBuffer(MVKShaderStage stage, MVKMTLBufferBinding& buffBind) = 0; @@ -547,7 +547,7 @@ public: const char* pStageName, bool fullImageViewSwizzle, std::function bindBuffer, - std::function)> bindImplicitBuffer, + std::function)> bindImplicitBuffer, std::function bindTexture, std::function bindSampler); diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm index 2817343d..37f0194f 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm @@ -54,7 +54,7 @@ void MVKPipelineCommandEncoderState::encodeImpl(uint32_t stage) { #pragma mark - #pragma mark MVKViewportCommandEncoderState -void MVKViewportCommandEncoderState::setViewports(const MVKArrayRef viewports, +void MVKViewportCommandEncoderState::setViewports(MVKArrayRef viewports, uint32_t firstViewport, bool isSettingDynamically) { @@ -107,7 +107,7 @@ void MVKViewportCommandEncoderState::encodeImpl(uint32_t stage) { #pragma mark - #pragma mark MVKScissorCommandEncoderState -void MVKScissorCommandEncoderState::setScissors(const MVKArrayRef scissors, +void MVKScissorCommandEncoderState::setScissors(MVKArrayRef scissors, uint32_t firstScissor, bool isSettingDynamically) { @@ -594,7 +594,7 @@ void MVKResourcesCommandEncoderState::markDirty() { } // If a swizzle is needed for this stage, iterates all the bindings and logs errors for those that need texture swizzling. -void MVKResourcesCommandEncoderState::assertMissingSwizzles(bool needsSwizzle, const char* stageName, const MVKArrayRef texBindings) { +void MVKResourcesCommandEncoderState::assertMissingSwizzles(bool needsSwizzle, const char* stageName, MVKArrayRef texBindings) { if (needsSwizzle) { for (auto& tb : texBindings) { VkComponentMapping vkcm = mvkUnpackSwizzle(tb.swizzle); @@ -684,7 +684,7 @@ void MVKGraphicsResourcesCommandEncoderState::encodeBindings(MVKShaderStage stag const char* pStageName, bool fullImageViewSwizzle, std::function bindBuffer, - std::function)> bindImplicitBuffer, + std::function)> bindImplicitBuffer, std::function bindTexture, std::function bindSampler) { @@ -795,7 +795,7 @@ void MVKGraphicsResourcesCommandEncoderState::encodeImpl(uint32_t stage) { offset: b.offset atIndex: b.index]; }, - [](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b, const MVKArrayRef s)->void { + [](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b, MVKArrayRef s)->void { cmdEncoder->setComputeBytes(cmdEncoder->getMTLComputeEncoder(kMVKCommandUseTessellationVertexTessCtl), s.data(), s.byteSize(), @@ -846,7 +846,7 @@ void MVKGraphicsResourcesCommandEncoderState::encodeImpl(uint32_t stage) { b.isDirty = true; // We haven't written it out, so leave dirty until next time. } }, - [](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b, const MVKArrayRef s)->void { + [](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b, MVKArrayRef s)->void { cmdEncoder->setVertexBytes(cmdEncoder->_mtlRenderEncoder, s.data(), s.byteSize(), @@ -879,7 +879,7 @@ void MVKGraphicsResourcesCommandEncoderState::encodeImpl(uint32_t stage) { offset: b.offset atIndex: b.index]; }, - [](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b, const MVKArrayRef s)->void { + [](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b, MVKArrayRef s)->void { cmdEncoder->setComputeBytes(cmdEncoder->getMTLComputeEncoder(kMVKCommandUseTessellationVertexTessCtl), s.data(), s.byteSize(), @@ -912,7 +912,7 @@ void MVKGraphicsResourcesCommandEncoderState::encodeImpl(uint32_t stage) { offset: b.offset atIndex: b.index]; }, - [](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b, const MVKArrayRef s)->void { + [](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b, MVKArrayRef s)->void { cmdEncoder->setVertexBytes(cmdEncoder->_mtlRenderEncoder, s.data(), s.byteSize(), @@ -945,7 +945,7 @@ void MVKGraphicsResourcesCommandEncoderState::encodeImpl(uint32_t stage) { offset: b.offset atIndex: b.index]; }, - [](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b, const MVKArrayRef s)->void { + [](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b, MVKArrayRef s)->void { cmdEncoder->setFragmentBytes(cmdEncoder->_mtlRenderEncoder, s.data(), s.byteSize(), diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.h b/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.h index 80c3a357..5f44a95f 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.h @@ -56,7 +56,7 @@ public: virtual void endQuery(uint32_t query, MVKCommandEncoder* cmdEncoder); /** Finishes the specified queries and marks them as available. */ - virtual void finishQueries(const MVKArrayRef queries); + virtual void finishQueries(MVKArrayRef queries); /** Resets the results and availability status of the specified queries. */ virtual void resetResults(uint32_t firstQuery, uint32_t queryCount, MVKCommandEncoder* cmdEncoder); @@ -212,7 +212,7 @@ class MVKTimestampQueryPool : public MVKGPUCounterQueryPool { public: void endQuery(uint32_t query, MVKCommandEncoder* cmdEncoder) override; - void finishQueries(const MVKArrayRef queries) override; + void finishQueries(MVKArrayRef queries) override; #pragma mark Construction diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.mm b/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.mm index 2e0e1368..1bd0a6d0 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.mm @@ -52,7 +52,7 @@ void MVKQueryPool::endQuery(uint32_t query, MVKCommandEncoder* cmdEncoder) { } // Mark queries as available -void MVKQueryPool::finishQueries(const MVKArrayRef queries) { +void MVKQueryPool::finishQueries(MVKArrayRef queries) { lock_guard lock(_availabilityLock); for (uint32_t qry : queries) { if (_availability[qry] == DeviceAvailable) { @@ -379,7 +379,7 @@ void MVKTimestampQueryPool::endQuery(uint32_t query, MVKCommandEncoder* cmdEncod } // If not using MTLCounterSampleBuffer, update timestamp values, then mark queries as available -void MVKTimestampQueryPool::finishQueries(const MVKArrayRef queries) { +void MVKTimestampQueryPool::finishQueries(MVKArrayRef queries) { if ( !_mtlCounterBuffer ) { uint64_t ts = mvkGetTimestamp(); for (uint32_t qry : queries) { _timestamps[qry] = ts; } diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.h b/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.h index 6cbe2e4e..cb9c8e44 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.h @@ -116,8 +116,8 @@ public: void populateMTLRenderPassDescriptor(MTLRenderPassDescriptor* mtlRPDesc, uint32_t passIdx, MVKFramebuffer* framebuffer, - const MVKArrayRef attachments, - const MVKArrayRef clearValues, + MVKArrayRef attachments, + MVKArrayRef clearValues, bool isRenderingEntireAttachment, bool loadOverride = false); @@ -126,7 +126,7 @@ public: * when the render area is smaller than the full framebuffer size. */ void populateClearAttachments(MVKClearAttachments& clearAtts, - const MVKArrayRef clearValues); + MVKArrayRef clearValues); /** * Populates the specified vector with VkClearRects for clearing views of a specified multiview @@ -140,11 +140,11 @@ public: /** If a render encoder is active, sets the store actions for all attachments to it. */ void encodeStoreActions(MVKCommandEncoder* cmdEncoder, bool isRenderingEntireAttachment, - const MVKArrayRef attachments, + MVKArrayRef attachments, bool storeOverride = false); /** Resolves any resolve attachments that cannot be handled by native Metal subpass resolve behavior. */ - void resolveUnresolvableAttachments(MVKCommandEncoder* cmdEncoder, const MVKArrayRef attachments); + void resolveUnresolvableAttachments(MVKCommandEncoder* cmdEncoder, MVKArrayRef attachments); MVKRenderSubpass(MVKRenderPass* renderPass, const VkSubpassDescription* pCreateInfo, const VkRenderPassInputAttachmentAspectCreateInfo* pInputAspects, diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.mm b/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.mm index 3bf8a188..a742690d 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.mm @@ -138,8 +138,8 @@ uint32_t MVKRenderSubpass::getViewCountUpToMetalPass(uint32_t passIdx) const { void MVKRenderSubpass::populateMTLRenderPassDescriptor(MTLRenderPassDescriptor* mtlRPDesc, uint32_t passIdx, MVKFramebuffer* framebuffer, - const MVKArrayRef attachments, - const MVKArrayRef clearValues, + MVKArrayRef attachments, + MVKArrayRef clearValues, bool isRenderingEntireAttachment, bool loadOverride) { MVKPixelFormats* pixFmts = _renderPass->getPixelFormats(); @@ -279,7 +279,7 @@ void MVKRenderSubpass::populateMTLRenderPassDescriptor(MTLRenderPassDescriptor* void MVKRenderSubpass::encodeStoreActions(MVKCommandEncoder* cmdEncoder, bool isRenderingEntireAttachment, - const MVKArrayRef attachments, + MVKArrayRef attachments, bool storeOverride) { if (!cmdEncoder->_mtlRenderEncoder) { return; } if (!_renderPass->getDevice()->_pMetalFeatures->deferredStoreActions) { return; } @@ -308,7 +308,7 @@ void MVKRenderSubpass::encodeStoreActions(MVKCommandEncoder* cmdEncoder, } void MVKRenderSubpass::populateClearAttachments(MVKClearAttachments& clearAtts, - const MVKArrayRef clearValues) { + MVKArrayRef clearValues) { uint32_t caCnt = getColorAttachmentCount(); for (uint32_t caIdx = 0; caIdx < caCnt; caIdx++) { uint32_t attIdx = _colorAttachments[caIdx].attachment; @@ -394,7 +394,7 @@ MVKMTLFmtCaps MVKRenderSubpass::getRequiredFormatCapabilitiesForAttachmentAt(uin return caps; } -void MVKRenderSubpass::resolveUnresolvableAttachments(MVKCommandEncoder* cmdEncoder, const MVKArrayRef attachments) { +void MVKRenderSubpass::resolveUnresolvableAttachments(MVKCommandEncoder* cmdEncoder, MVKArrayRef attachments) { MVKPixelFormats* pixFmts = cmdEncoder->getPixelFormats(); size_t raCnt = _resolveAttachments.size(); for (uint32_t raIdx = 0; raIdx < raCnt; raIdx++) { diff --git a/MoltenVK/MoltenVK/Utility/MVKFoundation.h b/MoltenVK/MoltenVK/Utility/MVKFoundation.h index 8ea9f658..d26b53a4 100644 --- a/MoltenVK/MoltenVK/Utility/MVKFoundation.h +++ b/MoltenVK/MoltenVK/Utility/MVKFoundation.h @@ -479,18 +479,16 @@ std::size_t mvkHash(const N* pVals, std::size_t count = 1, std::size_t seed = 53 template struct MVKArrayRef { public: - constexpr const Type* begin() const { return _data; } - constexpr const Type* end() const { return &_data[_size]; } - constexpr const Type* data() const { return _data; } - constexpr Type* begin() { return _data; } - constexpr Type* end() { return &_data[_size]; } - constexpr Type* data() { return _data; } - constexpr const size_t size() const { return _size; } - constexpr const size_t byteSize() const { return _size * sizeof(Type); } - constexpr const Type& operator[]( const size_t i ) const { return _data[i]; } - constexpr Type& operator[]( const size_t i ) { return _data[i]; } + constexpr Type* begin() const { return _data; } + constexpr Type* end() const { return &_data[_size]; } + constexpr Type* data() const { return _data; } + constexpr size_t size() const { return _size; } + constexpr size_t byteSize() const { return _size * sizeof(Type); } + constexpr Type& operator[]( const size_t i ) const { return _data[i]; } constexpr MVKArrayRef() : MVKArrayRef(nullptr, 0) {} constexpr MVKArrayRef(Type* d, size_t s) : _data(d), _size(s) {} + template , bool> = true> + constexpr MVKArrayRef(MVKArrayRef other) : _data(other.data()), _size(other.size()) {} protected: Type* _data; diff --git a/MoltenVK/MoltenVK/Utility/MVKSmallVector.h b/MoltenVK/MoltenVK/Utility/MVKSmallVector.h index 6294f913..b6e1277c 100755 --- a/MoltenVK/MoltenVK/Utility/MVKSmallVector.h +++ b/MoltenVK/MoltenVK/Utility/MVKSmallVector.h @@ -298,12 +298,12 @@ public: reverse_iterator rbegin() const { return reverse_iterator( end() ); } reverse_iterator rend() const { return reverse_iterator( begin() ); } - const MVKArrayRef contents() const { return MVKArrayRef(data(), size()); } - MVKArrayRef contents() { return MVKArrayRef(data(), size()); } + MVKArrayRef contents() const { return MVKArrayRef(data(), size()); } + MVKArrayRef< Type> contents() { return MVKArrayRef< Type>(data(), size()); } - const Type &operator[]( const size_t i ) const { return alc[i]; } + const Type &operator[]( const size_t i ) const { return alc[i]; } Type &operator[]( const size_t i ) { return alc[i]; } - const Type &at( const size_t i ) const { return alc[i]; } + const Type &at( const size_t i ) const { return alc[i]; } Type &at( const size_t i ) { return alc[i]; } const Type &front() const { return alc[0]; } Type &front() { return alc[0]; }