Allocate MVKDescriptorSets from a pool within MVKDescriptorPool,
keyed by MVKDescriptorSetLayout reference. Add MVKObjectPool subclass MVKDeviceObjectPool. Enlarge window dimensions on macOS Cube demo.
This commit is contained in:
parent
26c7b69a3f
commit
c933330406
@ -1,8 +1,9 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15G26a" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
|
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="14313.18" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="macosx"/>
|
<deployment identifier="macosx"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14313.18"/>
|
||||||
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<scenes>
|
<scenes>
|
||||||
<!--Application-->
|
<!--Application-->
|
||||||
@ -100,11 +101,14 @@
|
|||||||
<scene sceneID="R2V-B0-nI4">
|
<scene sceneID="R2V-B0-nI4">
|
||||||
<objects>
|
<objects>
|
||||||
<windowController id="B8D-0N-5wS" sceneMemberID="viewController">
|
<windowController id="B8D-0N-5wS" sceneMemberID="viewController">
|
||||||
<window key="window" title="MoltenVK Demo" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" visibleAtLaunch="NO" animationBehavior="default" id="IQv-IB-iLA">
|
<window key="window" title="MoltenVK Demo" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="IQv-IB-iLA">
|
||||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||||
<rect key="contentRect" x="1051" y="656" width="300" height="200"/>
|
<rect key="contentRect" x="1051" y="656" width="500" height="500"/>
|
||||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
|
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
|
||||||
<value key="minSize" type="size" width="300" height="200"/>
|
<value key="minSize" type="size" width="500" height="500"/>
|
||||||
|
<connections>
|
||||||
|
<outlet property="delegate" destination="B8D-0N-5wS" id="W4e-Xs-vl5"/>
|
||||||
|
</connections>
|
||||||
</window>
|
</window>
|
||||||
<connections>
|
<connections>
|
||||||
<segue destination="XfG-lQ-9wD" kind="relationship" relationship="window.shadowedContentViewController" id="cq2-FE-JQM"/>
|
<segue destination="XfG-lQ-9wD" kind="relationship" relationship="window.shadowedContentViewController" id="cq2-FE-JQM"/>
|
||||||
@ -119,13 +123,13 @@
|
|||||||
<objects>
|
<objects>
|
||||||
<viewController id="XfG-lQ-9wD" customClass="DemoViewController" sceneMemberID="viewController">
|
<viewController id="XfG-lQ-9wD" customClass="DemoViewController" sceneMemberID="viewController">
|
||||||
<view key="view" id="m2S-Jp-Qdl" customClass="DemoView">
|
<view key="view" id="m2S-Jp-Qdl" customClass="DemoView">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="400" height="300"/>
|
<rect key="frame" x="0.0" y="0.0" width="500" height="500"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
</view>
|
</view>
|
||||||
</viewController>
|
</viewController>
|
||||||
<customObject id="rPt-NT-nkU" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
<customObject id="rPt-NT-nkU" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
||||||
</objects>
|
</objects>
|
||||||
<point key="canvasLocation" x="83" y="564"/>
|
<point key="canvasLocation" x="83" y="777"/>
|
||||||
</scene>
|
</scene>
|
||||||
</scenes>
|
</scenes>
|
||||||
</document>
|
</document>
|
||||||
|
@ -494,8 +494,8 @@
|
|||||||
A98149411FB6A3F7005F00B4 /* MVKBaseObject.cpp */,
|
A98149411FB6A3F7005F00B4 /* MVKBaseObject.cpp */,
|
||||||
A98149421FB6A3F7005F00B4 /* MVKBaseObject.h */,
|
A98149421FB6A3F7005F00B4 /* MVKBaseObject.h */,
|
||||||
A98149431FB6A3F7005F00B4 /* MVKEnvironment.h */,
|
A98149431FB6A3F7005F00B4 /* MVKEnvironment.h */,
|
||||||
A98149441FB6A3F7005F00B4 /* MVKFoundation.h */,
|
|
||||||
A98149451FB6A3F7005F00B4 /* MVKFoundation.cpp */,
|
A98149451FB6A3F7005F00B4 /* MVKFoundation.cpp */,
|
||||||
|
A98149441FB6A3F7005F00B4 /* MVKFoundation.h */,
|
||||||
A98149461FB6A3F7005F00B4 /* MVKObjectPool.h */,
|
A98149461FB6A3F7005F00B4 /* MVKObjectPool.h */,
|
||||||
A98149491FB6A3F7005F00B4 /* MVKWatermark.h */,
|
A98149491FB6A3F7005F00B4 /* MVKWatermark.h */,
|
||||||
A981494A1FB6A3F7005F00B4 /* MVKWatermark.mm */,
|
A981494A1FB6A3F7005F00B4 /* MVKWatermark.mm */,
|
||||||
|
@ -77,8 +77,8 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Instances of this class can participate in a linked list or pool. When so participating,
|
* Instances of this class can participate in a linked list or pool. When so participating,
|
||||||
* this is a reference to the next instance in the linked list. This value should only be
|
* this is a reference to the next instance in the list or pool. This value should only be
|
||||||
* managed and set by the linked list.
|
* managed and set by the list or pool.
|
||||||
*/
|
*/
|
||||||
MVKCommand* _next = nullptr;
|
MVKCommand* _next = nullptr;
|
||||||
|
|
||||||
|
@ -91,8 +91,8 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Instances of this class can participate in a linked list or pool. When so participating,
|
* Instances of this class can participate in a linked list or pool. When so participating,
|
||||||
* this is a reference to the next instance in the linked list. This value should only be
|
* this is a reference to the next instance in the list or pool. This value should only be
|
||||||
* managed and set by the linked list.
|
* managed and set by the list or pool.
|
||||||
*/
|
*/
|
||||||
MVKCommandBuffer* _next;
|
MVKCommandBuffer* _next;
|
||||||
|
|
||||||
@ -127,13 +127,13 @@ protected:
|
|||||||
void prefill();
|
void prefill();
|
||||||
void clearPrefilledMTLCommandBuffer();
|
void clearPrefilledMTLCommandBuffer();
|
||||||
|
|
||||||
MVKCommand* _head;
|
MVKCommand* _head = nullptr;
|
||||||
MVKCommand* _tail;
|
MVKCommand* _tail = nullptr;
|
||||||
uint32_t _commandCount;
|
uint32_t _commandCount;
|
||||||
std::atomic_flag _isExecutingNonConcurrently;
|
std::atomic_flag _isExecutingNonConcurrently;
|
||||||
VkResult _recordingResult;
|
VkResult _recordingResult;
|
||||||
VkCommandBufferInheritanceInfo _secondaryInheritanceInfo;
|
VkCommandBufferInheritanceInfo _secondaryInheritanceInfo;
|
||||||
id<MTLCommandBuffer> _prefilledMTLCmdBuffer;
|
id<MTLCommandBuffer> _prefilledMTLCmdBuffer = nil;
|
||||||
bool _isSecondary;
|
bool _isSecondary;
|
||||||
bool _doesContinueRenderPass;
|
bool _doesContinueRenderPass;
|
||||||
bool _canAcceptCommands;
|
bool _canAcceptCommands;
|
||||||
@ -143,33 +143,6 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
|
||||||
#pragma mark MVKCommandBufferPool
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A pool of MVKCommandBuffer instances.
|
|
||||||
*
|
|
||||||
* To return a MVKCommandBuffer retrieved from this pool, back to this pool,
|
|
||||||
* call the returnToPool() function on the MVKCommandBuffer instance.
|
|
||||||
*/
|
|
||||||
class MVKCommandBufferPool : public MVKObjectPool<MVKCommandBuffer> {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/** Returns a new command instance. */
|
|
||||||
MVKCommandBuffer* newObject() override { return new MVKCommandBuffer(_device); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configures this instance to either use pooling, or not, depending on the
|
|
||||||
* value of isPooling, which defaults to true if not indicated explicitly.
|
|
||||||
*/
|
|
||||||
MVKCommandBufferPool(MVKDevice* device, bool isPooling = true) : MVKObjectPool<MVKCommandBuffer>(isPooling), _device(device) {}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
MVKDevice* _device;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark MVKCommandEncoder
|
#pragma mark MVKCommandEncoder
|
||||||
|
|
||||||
|
@ -179,9 +179,6 @@ void MVKCommandBuffer::clearPrefilledMTLCommandBuffer() {
|
|||||||
void MVKCommandBuffer::init(const VkCommandBufferAllocateInfo* pAllocateInfo) {
|
void MVKCommandBuffer::init(const VkCommandBufferAllocateInfo* pAllocateInfo) {
|
||||||
_commandPool = (MVKCommandPool*)pAllocateInfo->commandPool;
|
_commandPool = (MVKCommandPool*)pAllocateInfo->commandPool;
|
||||||
_isSecondary = (pAllocateInfo->level == VK_COMMAND_BUFFER_LEVEL_SECONDARY);
|
_isSecondary = (pAllocateInfo->level == VK_COMMAND_BUFFER_LEVEL_SECONDARY);
|
||||||
_head = nullptr;
|
|
||||||
_tail = nullptr;
|
|
||||||
_prefilledMTLCmdBuffer = nil;
|
|
||||||
|
|
||||||
reset(0);
|
reset(0);
|
||||||
}
|
}
|
||||||
|
@ -171,10 +171,8 @@ public:
|
|||||||
~MVKCommandPool() override;
|
~MVKCommandPool() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void freeCommandBuffer(MVKCommandBuffer* mvkCmdBuff);
|
MVKDeviceObjectPool<MVKCommandBuffer> _commandBufferPool;
|
||||||
|
std::unordered_set<MVKCommandBuffer*> _allocatedCommandBuffers;
|
||||||
MVKCommandBufferPool _commandBufferPool;
|
|
||||||
std::unordered_set<MVKCommandBuffer*> _commandBuffers;
|
|
||||||
MVKCommandEncodingPool _commandEncodingPool;
|
MVKCommandEncodingPool _commandEncodingPool;
|
||||||
uint32_t _queueFamilyIndex;
|
uint32_t _queueFamilyIndex;
|
||||||
};
|
};
|
||||||
|
@ -37,7 +37,7 @@ VkResult MVKCommandPool::reset(VkCommandPoolResetFlags flags) {
|
|||||||
|
|
||||||
VkCommandBufferResetFlags cmdBuffFlags = releaseRez ? VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT : 0;
|
VkCommandBufferResetFlags cmdBuffFlags = releaseRez ? VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT : 0;
|
||||||
|
|
||||||
for (auto& cb : _commandBuffers) { cb->reset(cmdBuffFlags); }
|
for (auto& cb : _allocatedCommandBuffers) { cb->reset(cmdBuffFlags); }
|
||||||
|
|
||||||
if (releaseRez) { trim(); }
|
if (releaseRez) { trim(); }
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ VkResult MVKCommandPool::allocateCommandBuffers(const VkCommandBufferAllocateInf
|
|||||||
for (uint32_t cbIdx = 0; cbIdx < cbCnt; cbIdx++) {
|
for (uint32_t cbIdx = 0; cbIdx < cbCnt; cbIdx++) {
|
||||||
MVKCommandBuffer* mvkCmdBuff = _commandBufferPool.acquireObject();
|
MVKCommandBuffer* mvkCmdBuff = _commandBufferPool.acquireObject();
|
||||||
mvkCmdBuff->init(pAllocateInfo);
|
mvkCmdBuff->init(pAllocateInfo);
|
||||||
_commandBuffers.insert(mvkCmdBuff);
|
_allocatedCommandBuffers.insert(mvkCmdBuff);
|
||||||
pCmdBuffer[cbIdx] = mvkCmdBuff->getVkCommandBuffer();
|
pCmdBuffer[cbIdx] = mvkCmdBuff->getVkCommandBuffer();
|
||||||
if (rslt == VK_SUCCESS) { rslt = mvkCmdBuff->getConfigurationResult(); }
|
if (rslt == VK_SUCCESS) { rslt = mvkCmdBuff->getConfigurationResult(); }
|
||||||
}
|
}
|
||||||
@ -64,18 +64,14 @@ VkResult MVKCommandPool::allocateCommandBuffers(const VkCommandBufferAllocateInf
|
|||||||
void MVKCommandPool::freeCommandBuffers(uint32_t commandBufferCount,
|
void MVKCommandPool::freeCommandBuffers(uint32_t commandBufferCount,
|
||||||
const VkCommandBuffer* pCommandBuffers) {
|
const VkCommandBuffer* pCommandBuffers) {
|
||||||
for (uint32_t cbIdx = 0; cbIdx < commandBufferCount; cbIdx++) {
|
for (uint32_t cbIdx = 0; cbIdx < commandBufferCount; cbIdx++) {
|
||||||
freeCommandBuffer(MVKCommandBuffer::getMVKCommandBuffer(pCommandBuffers[cbIdx]));
|
MVKCommandBuffer* mvkCmdBuff = MVKCommandBuffer::getMVKCommandBuffer(pCommandBuffers[cbIdx]);
|
||||||
|
if (_allocatedCommandBuffers.erase(mvkCmdBuff)) {
|
||||||
|
mvkCmdBuff->reset(VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
|
||||||
|
_commandBufferPool.returnObject(mvkCmdBuff);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MVKCommandPool::freeCommandBuffer(MVKCommandBuffer* mvkCmdBuff) {
|
|
||||||
if ( !mvkCmdBuff ) { return; }
|
|
||||||
|
|
||||||
mvkCmdBuff->reset(VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
|
|
||||||
_commandBuffers.erase(mvkCmdBuff);
|
|
||||||
_commandBufferPool.returnObject(mvkCmdBuff);
|
|
||||||
}
|
|
||||||
|
|
||||||
id<MTLCommandBuffer> MVKCommandPool::newMTLCommandBuffer(uint32_t queueIndex) {
|
id<MTLCommandBuffer> MVKCommandPool::newMTLCommandBuffer(uint32_t queueIndex) {
|
||||||
return [[_device->getQueue(_queueFamilyIndex, queueIndex)->getMTLCommandQueue() commandBuffer] retain];
|
return [[_device->getQueue(_queueFamilyIndex, queueIndex)->getMTLCommandQueue() commandBuffer] retain];
|
||||||
}
|
}
|
||||||
@ -130,7 +126,8 @@ void MVKCommandPool::trim() {
|
|||||||
#pragma mark Construction
|
#pragma mark Construction
|
||||||
|
|
||||||
MVKCommandPool::MVKCommandPool(MVKDevice* device,
|
MVKCommandPool::MVKCommandPool(MVKDevice* device,
|
||||||
const VkCommandPoolCreateInfo* pCreateInfo) : MVKBaseDeviceObject(device),
|
const VkCommandPoolCreateInfo* pCreateInfo) :
|
||||||
|
MVKBaseDeviceObject(device),
|
||||||
_commandBufferPool(device),
|
_commandBufferPool(device),
|
||||||
_commandEncodingPool(device),
|
_commandEncodingPool(device),
|
||||||
_queueFamilyIndex(pCreateInfo->queueFamilyIndex),
|
_queueFamilyIndex(pCreateInfo->queueFamilyIndex),
|
||||||
@ -178,7 +175,8 @@ MVKCommandPool::MVKCommandPool(MVKDevice* device,
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
MVKCommandPool::~MVKCommandPool() {
|
MVKCommandPool::~MVKCommandPool() {
|
||||||
auto cmdBuffs = _commandBuffers;
|
for (auto& mvkCB : _allocatedCommandBuffers) {
|
||||||
for (auto& cb : cmdBuffs) { freeCommandBuffer(cb); }
|
_commandBufferPool.returnObject(mvkCB);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,8 +55,8 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Instances of this class can participate in a linked list or pool. When so participating,
|
* Instances of this class can participate in a linked list or pool. When so participating,
|
||||||
* this is a reference to the next instance in the linked list. This value should only be
|
* this is a reference to the next instance in the list or pool. This value should only be
|
||||||
* managed and set by the linked list.
|
* managed and set by the list or pool.
|
||||||
*/
|
*/
|
||||||
MVKMTLBufferAllocation* _next = nullptr;
|
MVKMTLBufferAllocation* _next = nullptr;
|
||||||
|
|
||||||
|
@ -21,7 +21,8 @@
|
|||||||
#include "MVKDevice.h"
|
#include "MVKDevice.h"
|
||||||
#include "MVKImage.h"
|
#include "MVKImage.h"
|
||||||
#include <MoltenVKSPIRVToMSLConverter/SPIRVToMSLConverter.h>
|
#include <MoltenVKSPIRVToMSLConverter/SPIRVToMSLConverter.h>
|
||||||
#include <forward_list>
|
#include <unordered_set>
|
||||||
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
using namespace mvk;
|
using namespace mvk;
|
||||||
@ -274,14 +275,23 @@ public:
|
|||||||
VkDescriptorBufferInfo* pBufferInfo,
|
VkDescriptorBufferInfo* pBufferInfo,
|
||||||
VkBufferView* pTexelBufferView);
|
VkBufferView* pTexelBufferView);
|
||||||
|
|
||||||
/** Constructs an instance for the specified device. */
|
/**
|
||||||
MVKDescriptorSet(MVKDevice* device, MVKDescriptorSetLayout* layout);
|
* Instances of this class can participate in a linked list or pool. When so participating,
|
||||||
|
* this is a reference to the next instance in the list or pool. This value should only be
|
||||||
|
* managed and set by the list or pool.
|
||||||
|
*/
|
||||||
|
MVKDescriptorSet* _next;
|
||||||
|
|
||||||
|
MVKDescriptorSet(MVKDevice* device) : MVKBaseDeviceObject(device) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class MVKDescriptorSetLayout;
|
friend class MVKDescriptorSetLayout;
|
||||||
|
friend class MVKDescriptorPool;
|
||||||
|
|
||||||
|
void setLayout(MVKDescriptorSetLayout* layout);
|
||||||
MVKDescriptorBinding* getBinding(uint32_t binding);
|
MVKDescriptorBinding* getBinding(uint32_t binding);
|
||||||
|
|
||||||
|
MVKDescriptorSetLayout* _pLayout = nullptr;
|
||||||
std::vector<MVKDescriptorBinding> _bindings;
|
std::vector<MVKDescriptorBinding> _bindings;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -289,6 +299,8 @@ protected:
|
|||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark MVKDescriptorPool
|
#pragma mark MVKDescriptorPool
|
||||||
|
|
||||||
|
typedef MVKDeviceObjectPool<MVKDescriptorSet> MVKDescriptorSetPool;
|
||||||
|
|
||||||
/** Represents a Vulkan descriptor pool. */
|
/** Represents a Vulkan descriptor pool. */
|
||||||
class MVKDescriptorPool : public MVKBaseDeviceObject {
|
class MVKDescriptorPool : public MVKBaseDeviceObject {
|
||||||
|
|
||||||
@ -312,9 +324,11 @@ public:
|
|||||||
~MVKDescriptorPool() override;
|
~MVKDescriptorPool() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint32_t _maxSets;
|
MVKDescriptorSetPool* getDescriptorSetPool(MVKDescriptorSetLayout* mvkDescSetLayout);
|
||||||
uint32_t _allocatedSetCount;
|
|
||||||
std::forward_list<MVKDescriptorSet*> _allocatedSets;
|
uint32_t _maxSets;
|
||||||
|
std::unordered_set<MVKDescriptorSet*> _allocatedSets;
|
||||||
|
std::unordered_map<MVKDescriptorSetLayout*, MVKDescriptorSetPool*> _descriptorSetPools;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -374,9 +374,6 @@ void MVKDescriptorSetLayoutBinding::populateShaderConverterContext(SPIRVToMSLCon
|
|||||||
|
|
||||||
MVKDescriptorSetLayoutBinding::MVKDescriptorSetLayoutBinding(MVKDescriptorSetLayout* layout,
|
MVKDescriptorSetLayoutBinding::MVKDescriptorSetLayoutBinding(MVKDescriptorSetLayout* layout,
|
||||||
const VkDescriptorSetLayoutBinding* pBinding) : MVKConfigurableObject() {
|
const VkDescriptorSetLayoutBinding* pBinding) : MVKConfigurableObject() {
|
||||||
|
|
||||||
// MVKLogDebug("Creating MVKDescriptorSetLayoutBinding binding %d.", pBinding->binding);
|
|
||||||
|
|
||||||
// Determine the shader stages used by this binding
|
// Determine the shader stages used by this binding
|
||||||
_applyToVertexStage = mvkAreFlagsEnabled(pBinding->stageFlags, VK_SHADER_STAGE_VERTEX_BIT);
|
_applyToVertexStage = mvkAreFlagsEnabled(pBinding->stageFlags, VK_SHADER_STAGE_VERTEX_BIT);
|
||||||
_applyToFragmentStage = mvkAreFlagsEnabled(pBinding->stageFlags, VK_SHADER_STAGE_FRAGMENT_BIT);
|
_applyToFragmentStage = mvkAreFlagsEnabled(pBinding->stageFlags, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||||
@ -790,17 +787,11 @@ void MVKDescriptorSet::writeDescriptorSets(const DescriptorAction* pDescriptorAc
|
|||||||
uint32_t origCnt = pDescriptorAction->descriptorCount;
|
uint32_t origCnt = pDescriptorAction->descriptorCount;
|
||||||
uint32_t remainCnt = origCnt;
|
uint32_t remainCnt = origCnt;
|
||||||
|
|
||||||
// MVKLogDebug("Writing descriptor sets with buffer info %p starting at binding point %d.", pBufferInfo, binding);
|
|
||||||
|
|
||||||
MVKDescriptorBinding* mvkDescBind = getBinding(binding);
|
MVKDescriptorBinding* mvkDescBind = getBinding(binding);
|
||||||
while (mvkDescBind && remainCnt > 0) {
|
while (mvkDescBind && remainCnt > 0) {
|
||||||
|
|
||||||
// MVKLogDebug("Writing MVKDescriptorBinding with binding point %d.", binding);
|
|
||||||
|
|
||||||
uint32_t srcStartIdx = origCnt - remainCnt;
|
uint32_t srcStartIdx = origCnt - remainCnt;
|
||||||
remainCnt = mvkDescBind->writeBindings(srcStartIdx, dstStartIdx, remainCnt,
|
remainCnt = mvkDescBind->writeBindings(srcStartIdx, dstStartIdx, remainCnt,
|
||||||
stride, pData);
|
stride, pData);
|
||||||
|
|
||||||
binding++; // If not consumed, move to next consecutive binding point
|
binding++; // If not consumed, move to next consecutive binding point
|
||||||
mvkDescBind = getBinding(binding);
|
mvkDescBind = getBinding(binding);
|
||||||
dstStartIdx = 0; // Subsequent bindings start reading at first element
|
dstStartIdx = 0; // Subsequent bindings start reading at first element
|
||||||
@ -826,17 +817,11 @@ void MVKDescriptorSet::readDescriptorSets(const VkCopyDescriptorSet* pDescriptor
|
|||||||
uint32_t origCnt = pDescriptorCopy->descriptorCount;
|
uint32_t origCnt = pDescriptorCopy->descriptorCount;
|
||||||
uint32_t remainCnt = origCnt;
|
uint32_t remainCnt = origCnt;
|
||||||
|
|
||||||
// MVKLogDebug("Reading descriptor sets with buffer info %p starting at binding point %d.", pBufferInfo, binding);
|
|
||||||
|
|
||||||
MVKDescriptorBinding* mvkDescBind = getBinding(binding);
|
MVKDescriptorBinding* mvkDescBind = getBinding(binding);
|
||||||
while (mvkDescBind && remainCnt > 0) {
|
while (mvkDescBind && remainCnt > 0) {
|
||||||
|
|
||||||
// MVKLogDebug("Reading MVKDescriptorBinding with binding point %d.", binding);
|
|
||||||
|
|
||||||
uint32_t dstStartIdx = origCnt - remainCnt;
|
uint32_t dstStartIdx = origCnt - remainCnt;
|
||||||
remainCnt = mvkDescBind->readBindings(srcStartIdx, dstStartIdx, remainCnt, descType,
|
remainCnt = mvkDescBind->readBindings(srcStartIdx, dstStartIdx, remainCnt, descType,
|
||||||
pImageInfo, pBufferInfo, pTexelBufferView);
|
pImageInfo, pBufferInfo, pTexelBufferView);
|
||||||
|
|
||||||
binding++; // If not consumed, move to next consecutive binding point
|
binding++; // If not consumed, move to next consecutive binding point
|
||||||
mvkDescBind = getBinding(binding);
|
mvkDescBind = getBinding(binding);
|
||||||
srcStartIdx = 0; // Subsequent bindings start reading at first element
|
srcStartIdx = 0; // Subsequent bindings start reading at first element
|
||||||
@ -850,14 +835,17 @@ MVKDescriptorBinding* MVKDescriptorSet::getBinding(uint32_t binding) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
MVKDescriptorSet::MVKDescriptorSet(MVKDevice* device,
|
// If the layout has changed, create the binding slots, each referencing a corresponding binding layout
|
||||||
MVKDescriptorSetLayout* layout) : MVKBaseDeviceObject(device) {
|
void MVKDescriptorSet::setLayout(MVKDescriptorSetLayout* layout) {
|
||||||
|
if (layout != _pLayout) {
|
||||||
|
_pLayout = layout;
|
||||||
|
uint32_t bindCnt = (uint32_t)layout->_bindings.size();
|
||||||
|
|
||||||
// Create the binding slots, each referencing a corresponding binding layout
|
_bindings.clear();
|
||||||
uint32_t bindCnt = (uint32_t)layout->_bindings.size();
|
_bindings.reserve(bindCnt);
|
||||||
_bindings.reserve(bindCnt);
|
for (uint32_t i = 0; i < bindCnt; i++) {
|
||||||
for (uint32_t i = 0; i < bindCnt; i++) {
|
_bindings.emplace_back(&layout->_bindings[i]);
|
||||||
_bindings.emplace_back(&layout->_bindings[i]);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -868,8 +856,7 @@ MVKDescriptorSet::MVKDescriptorSet(MVKDevice* device,
|
|||||||
VkResult MVKDescriptorPool::allocateDescriptorSets(uint32_t count,
|
VkResult MVKDescriptorPool::allocateDescriptorSets(uint32_t count,
|
||||||
const VkDescriptorSetLayout* pSetLayouts,
|
const VkDescriptorSetLayout* pSetLayouts,
|
||||||
VkDescriptorSet* pDescriptorSets) {
|
VkDescriptorSet* pDescriptorSets) {
|
||||||
// MVKLogDebug("Descriptor pool %p allocating %d descriptor sets for total %d.", this, count, _allocatedSetCount + count);
|
if (_allocatedSets.size() + count > _maxSets) {
|
||||||
if (_allocatedSetCount + count > _maxSets) {
|
|
||||||
if (_device->_enabledExtensions.vk_KHR_maintenance1.enabled) {
|
if (_device->_enabledExtensions.vk_KHR_maintenance1.enabled) {
|
||||||
return VK_ERROR_OUT_OF_POOL_MEMORY; // Failure is an acceptable test...don't log as error.
|
return VK_ERROR_OUT_OF_POOL_MEMORY; // Failure is an acceptable test...don't log as error.
|
||||||
} else {
|
} else {
|
||||||
@ -879,47 +866,55 @@ VkResult MVKDescriptorPool::allocateDescriptorSets(uint32_t count,
|
|||||||
|
|
||||||
for (uint32_t dsIdx = 0; dsIdx < count; dsIdx++) {
|
for (uint32_t dsIdx = 0; dsIdx < count; dsIdx++) {
|
||||||
MVKDescriptorSetLayout* mvkDSL = (MVKDescriptorSetLayout*)pSetLayouts[dsIdx];
|
MVKDescriptorSetLayout* mvkDSL = (MVKDescriptorSetLayout*)pSetLayouts[dsIdx];
|
||||||
if (mvkDSL->isPushDescriptorLayout()) continue;
|
if ( !mvkDSL->isPushDescriptorLayout() ) {
|
||||||
MVKDescriptorSet* mvkDescSet = new MVKDescriptorSet(_device, mvkDSL);
|
MVKDescriptorSet* mvkDS = getDescriptorSetPool(mvkDSL)->acquireObject();
|
||||||
_allocatedSets.push_front(mvkDescSet);
|
mvkDS->setLayout(mvkDSL);
|
||||||
pDescriptorSets[dsIdx] = (VkDescriptorSet)mvkDescSet;
|
_allocatedSets.insert(mvkDS);
|
||||||
_allocatedSetCount++;
|
pDescriptorSets[dsIdx] = (VkDescriptorSet)mvkDS;
|
||||||
}
|
|
||||||
return VK_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkResult MVKDescriptorPool::freeDescriptorSets(uint32_t count, const VkDescriptorSet* pDescriptorSets) {
|
|
||||||
// MVKLogDebug("Descriptor pool %p freeing %d descriptor sets from total %d.", this, count, _allocatedSetCount);
|
|
||||||
for (uint32_t dsIdx = 0; dsIdx < count; dsIdx++) {
|
|
||||||
MVKDescriptorSet* mvkDS = (MVKDescriptorSet*)pDescriptorSets[dsIdx];
|
|
||||||
if (mvkDS) {
|
|
||||||
_allocatedSets.remove(mvkDS);
|
|
||||||
_allocatedSetCount--;
|
|
||||||
mvkDS->destroy();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return VK_SUCCESS;
|
return VK_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkResult MVKDescriptorPool::reset(VkDescriptorPoolResetFlags flags) {
|
// Ensure descriptor set was actually allocated, then return to pool
|
||||||
// MVKLogDebug("Descriptor pool %p resetting with %d descriptor sets.", this, _allocatedSetCount);
|
VkResult MVKDescriptorPool::freeDescriptorSets(uint32_t count, const VkDescriptorSet* pDescriptorSets) {
|
||||||
mvkDestroyContainerContents(_allocatedSets);
|
for (uint32_t dsIdx = 0; dsIdx < count; dsIdx++) {
|
||||||
_allocatedSetCount = 0;
|
MVKDescriptorSet* mvkDS = (MVKDescriptorSet*)pDescriptorSets[dsIdx];
|
||||||
|
if (_allocatedSets.erase(mvkDS)) {
|
||||||
|
getDescriptorSetPool(mvkDS->_pLayout)->returnObject(mvkDS);
|
||||||
|
}
|
||||||
|
}
|
||||||
return VK_SUCCESS;
|
return VK_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return any allocated descriptor sets to their pools
|
||||||
|
VkResult MVKDescriptorPool::reset(VkDescriptorPoolResetFlags flags) {
|
||||||
|
for (auto& mvkDS : _allocatedSets) {
|
||||||
|
getDescriptorSetPool(mvkDS->_pLayout)->returnObject(mvkDS);
|
||||||
|
}
|
||||||
|
_allocatedSets.clear();
|
||||||
|
return VK_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the pool of descriptor sets that use a specific layout, lazily creating it if necessary
|
||||||
|
MVKDescriptorSetPool* MVKDescriptorPool::getDescriptorSetPool(MVKDescriptorSetLayout* mvkDescSetLayout) {
|
||||||
|
MVKDescriptorSetPool* dsp = _descriptorSetPools[mvkDescSetLayout];
|
||||||
|
if ( !dsp ) {
|
||||||
|
dsp = new MVKDescriptorSetPool(_device);
|
||||||
|
_descriptorSetPools[mvkDescSetLayout] = dsp;
|
||||||
|
}
|
||||||
|
return dsp;
|
||||||
|
}
|
||||||
|
|
||||||
MVKDescriptorPool::MVKDescriptorPool(MVKDevice* device,
|
MVKDescriptorPool::MVKDescriptorPool(MVKDevice* device,
|
||||||
const VkDescriptorPoolCreateInfo* pCreateInfo) : MVKBaseDeviceObject(device) {
|
const VkDescriptorPoolCreateInfo* pCreateInfo) : MVKBaseDeviceObject(device) {
|
||||||
_maxSets = pCreateInfo->maxSets;
|
_maxSets = pCreateInfo->maxSets;
|
||||||
_allocatedSetCount = 0;
|
|
||||||
// MVKLogDebug("Descriptor pool %p created with max %d sets.", this, _maxSets);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Destroying a descriptor pool implicitly destroys all descriptor sets created from it.
|
// Return any allocated sets to their pools and then destroy all the pools.
|
||||||
|
|
||||||
MVKDescriptorPool::~MVKDescriptorPool() {
|
MVKDescriptorPool::~MVKDescriptorPool() {
|
||||||
// MVKLogDebug("Descriptor pool %p destroyed with %d descriptor sets.", this, _allocatedSetCount);
|
|
||||||
reset(0);
|
reset(0);
|
||||||
|
for (auto& pair : _descriptorSetPools) { pair.second->destroy(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1019,5 +1014,3 @@ void mvkPopulateShaderConverterContext(SPIRVToMSLConverterContext& context,
|
|||||||
ctxRB.mslSampler = ssRB.samplerIndex;
|
ctxRB.mslSampler = ssRB.samplerIndex;
|
||||||
context.resourceBindings.push_back(ctxRB);
|
context.resourceBindings.push_back(ctxRB);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "MVKFoundation.h"
|
#include "MVKFoundation.h"
|
||||||
#include "MVKBaseObject.h"
|
#include "MVKBaseObject.h"
|
||||||
#include "MVKLayers.h"
|
#include "MVKLayers.h"
|
||||||
|
#include "MVKObjectPool.h"
|
||||||
#include "vk_mvk_moltenvk.h"
|
#include "vk_mvk_moltenvk.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -631,3 +632,26 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark MVKDeviceObjectPool
|
||||||
|
|
||||||
|
/** Manages a pool of instances of a particular object type that requires an MVKDevice during construction. */
|
||||||
|
template <class T>
|
||||||
|
class MVKDeviceObjectPool : public MVKObjectPool<T> {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/** Returns a new instance. */
|
||||||
|
T* newObject() override { return new T(_device); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures this instance for the device, and either use pooling, or not, depending
|
||||||
|
* on the value of isPooling, which defaults to true if not indicated explicitly.
|
||||||
|
*/
|
||||||
|
MVKDeviceObjectPool(MVKDevice* device, bool isPooling = true) : MVKObjectPool<T>(isPooling), _device(device) {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
MVKDevice* _device;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user