Merge pull request #288 from billhollings/master

Update glslang version and What's New document.
This commit is contained in:
Bill Hollings 2018-09-27 22:36:08 -04:00 committed by GitHub
commit 26c7b69a3f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 152 additions and 38 deletions

View File

@ -12,6 +12,28 @@ Copyright (c) 2014-2018 [The Brenwill Workshop Ltd.](http://www.brenwill.com)
For best results, use a Markdown reader.* For best results, use a Markdown reader.*
MoltenVK 1.0.23
---------------
Released 2018/09/28
- Add support for features:
- shaderStorageImageMultisample
- shaderStorageImageReadWithoutFormat
- shaderStorageImageWriteWithoutFormat
- shaderUniformBufferArrayDynamicIndexing
- shaderSampledImageArrayDynamicIndexing
- shaderStorageBufferArrayDynamicIndexing
- shaderStorageImageArrayDynamicIndexing
- Support reduced render area
- Support rasterization to missing attachment
- Allocate MVKCommandBuffers from a pool within MVKCommandPool.
- Update glslang version
- Update to latest SPIRV-Cross version:
- MSL: Improve coordinate handling for buffer reads.
- MSL: Expand arrays of buffers passed as input.
MoltenVK 1.0.22 MoltenVK 1.0.22
--------------- ---------------

View File

@ -1 +1 @@
a8453d4bc00998049db0d448764784a6a0767539 91ac4290bcf2cb930b4fb0981f09c00c0b6797e1

View File

@ -77,7 +77,7 @@ 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 command in the linked list. This value should only be * this is a reference to the next instance in the linked list. This value should only be
* managed and set by the linked list. * managed and set by the linked list.
*/ */
MVKCommand* _next = nullptr; MVKCommand* _next = nullptr;

View File

@ -21,6 +21,7 @@
#include "MVKDevice.h" #include "MVKDevice.h"
#include "MVKCommand.h" #include "MVKCommand.h"
#include "MVKCommandEncoderState.h" #include "MVKCommandEncoderState.h"
#include "MVKMTLBufferAllocation.h"
#include "MVKCmdPipeline.h" #include "MVKCmdPipeline.h"
#include <vector> #include <vector>
#include <unordered_map> #include <unordered_map>
@ -90,15 +91,15 @@ 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 command in the linked list. This value should only be * this is a reference to the next instance in the linked list. This value should only be
* managed and set by the linked list. * managed and set by the linked list.
*/ */
MVKCommandBuffer* _next; MVKCommandBuffer* _next;
#pragma mark Construction #pragma mark Construction
MVKCommandBuffer(MVKDevice* device, const VkCommandBufferAllocateInfo* pAllocateInfo); MVKCommandBuffer(MVKDevice* device) : MVKDispatchableDeviceObject(device) {}
~MVKCommandBuffer() override; ~MVKCommandBuffer() override;
@ -118,7 +119,9 @@ public:
protected: protected:
friend class MVKCommandEncoder; friend class MVKCommandEncoder;
friend class MVKCommandPool;
void init(const VkCommandBufferAllocateInfo* pAllocateInfo);
bool canExecute(); bool canExecute();
bool canPrefill(); bool canPrefill();
void prefill(); void prefill();
@ -140,6 +143,33 @@ 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

View File

@ -175,11 +175,9 @@ void MVKCommandBuffer::clearPrefilledMTLCommandBuffer() {
#pragma mark Construction #pragma mark Construction
MVKCommandBuffer::MVKCommandBuffer(MVKDevice* device, // Initializes this instance after it has been created retrieved from a pool.
const VkCommandBufferAllocateInfo* pAllocateInfo) : MVKDispatchableDeviceObject(device) { void MVKCommandBuffer::init(const VkCommandBufferAllocateInfo* pAllocateInfo) {
_commandPool = (MVKCommandPool*)pAllocateInfo->commandPool; _commandPool = (MVKCommandPool*)pAllocateInfo->commandPool;
_commandPool->addCommandBuffer(this);
_isSecondary = (pAllocateInfo->level == VK_COMMAND_BUFFER_LEVEL_SECONDARY); _isSecondary = (pAllocateInfo->level == VK_COMMAND_BUFFER_LEVEL_SECONDARY);
_head = nullptr; _head = nullptr;
_tail = nullptr; _tail = nullptr;
@ -190,7 +188,6 @@ MVKCommandBuffer::MVKCommandBuffer(MVKDevice* device,
MVKCommandBuffer::~MVKCommandBuffer() { MVKCommandBuffer::~MVKCommandBuffer() {
reset(0); reset(0);
_commandPool->removeCommandBuffer(this);
} }

View File

@ -18,7 +18,8 @@
#pragma once #pragma once
#include "MVKCommandPool.h" #include "MVKMTLResourceBindings.h"
#include "MVKCommandResourceFactory.h"
#include <vector> #include <vector>
class MVKCommandEncoder; class MVKCommandEncoder;

View File

@ -97,6 +97,9 @@ public:
/** Returns a MTLComputePipelineState for filling a buffer. */ /** Returns a MTLComputePipelineState for filling a buffer. */
id<MTLComputePipelineState> getCmdFillBufferMTLComputePipelineState(); id<MTLComputePipelineState> getCmdFillBufferMTLComputePipelineState();
/** Deletes all the internal resources. */
void clear();
#pragma mark Construction #pragma mark Construction
MVKCommandEncodingPool(MVKDevice* device); MVKCommandEncodingPool(MVKDevice* device);

View File

@ -105,6 +105,12 @@ id<MTLComputePipelineState> MVKCommandEncodingPool::getCmdFillBufferMTLComputePi
MVK_ENC_REZ_ACCESS(_mtlFillBufferComputePipelineState, newCmdFillBufferMTLComputePipelineState()); MVK_ENC_REZ_ACCESS(_mtlFillBufferComputePipelineState, newCmdFillBufferMTLComputePipelineState());
} }
void MVKCommandEncodingPool::clear() {
lock_guard<mutex> lock(_lock);
destroyMetalResources();
}
#pragma mark Construction #pragma mark Construction
MVKCommandEncodingPool::MVKCommandEncodingPool(MVKDevice* device) : MVKBaseDeviceObject(device), MVKCommandEncodingPool::MVKCommandEncodingPool(MVKDevice* device) : MVKBaseDeviceObject(device),

View File

@ -19,6 +19,7 @@
#pragma once #pragma once
#include "MVKDevice.h" #include "MVKDevice.h"
#include "MVKCommandBuffer.h"
#include "MVKCommandResourceFactory.h" #include "MVKCommandResourceFactory.h"
#include "MVKCommandEncodingPool.h" #include "MVKCommandEncodingPool.h"
#include "MVKCommand.h" #include "MVKCommand.h"
@ -169,12 +170,10 @@ public:
~MVKCommandPool() override; ~MVKCommandPool() override;
private: protected:
friend class MVKCommandBuffer; void freeCommandBuffer(MVKCommandBuffer* mvkCmdBuff);
void addCommandBuffer(MVKCommandBuffer* cmdBuffer);
void removeCommandBuffer(MVKCommandBuffer* cmdBuffer);
MVKCommandBufferPool _commandBufferPool;
std::unordered_set<MVKCommandBuffer*> _commandBuffers; std::unordered_set<MVKCommandBuffer*> _commandBuffers;
MVKCommandEncodingPool _commandEncodingPool; MVKCommandEncodingPool _commandEncodingPool;
uint32_t _queueFamilyIndex; uint32_t _queueFamilyIndex;

View File

@ -33,9 +33,14 @@ using namespace std;
// Reset all of the command buffers // Reset all of the command buffers
VkResult MVKCommandPool::reset(VkCommandPoolResetFlags flags) { VkResult MVKCommandPool::reset(VkCommandPoolResetFlags flags) {
for (auto& cb : _commandBuffers) { bool releaseRez = mvkAreFlagsEnabled(flags, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
cb->reset(VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
} VkCommandBufferResetFlags cmdBuffFlags = releaseRez ? VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT : 0;
for (auto& cb : _commandBuffers) { cb->reset(cmdBuffFlags); }
if (releaseRez) { trim(); }
return VK_SUCCESS; return VK_SUCCESS;
} }
@ -47,7 +52,9 @@ VkResult MVKCommandPool::allocateCommandBuffers(const VkCommandBufferAllocateInf
VkResult rslt = VK_SUCCESS; VkResult rslt = VK_SUCCESS;
uint32_t cbCnt = pAllocateInfo->commandBufferCount; uint32_t cbCnt = pAllocateInfo->commandBufferCount;
for (uint32_t cbIdx = 0; cbIdx < cbCnt; cbIdx++) { for (uint32_t cbIdx = 0; cbIdx < cbCnt; cbIdx++) {
MVKCommandBuffer* mvkCmdBuff = new MVKCommandBuffer(_device, pAllocateInfo); MVKCommandBuffer* mvkCmdBuff = _commandBufferPool.acquireObject();
mvkCmdBuff->init(pAllocateInfo);
_commandBuffers.insert(mvkCmdBuff);
pCmdBuffer[cbIdx] = mvkCmdBuff->getVkCommandBuffer(); pCmdBuffer[cbIdx] = mvkCmdBuff->getVkCommandBuffer();
if (rslt == VK_SUCCESS) { rslt = mvkCmdBuff->getConfigurationResult(); } if (rslt == VK_SUCCESS) { rslt = mvkCmdBuff->getConfigurationResult(); }
} }
@ -57,25 +64,66 @@ 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++) {
VkCommandBuffer cmdBuff = pCommandBuffers[cbIdx]; freeCommandBuffer(MVKCommandBuffer::getMVKCommandBuffer(pCommandBuffers[cbIdx]));
if (cmdBuff) { MVKCommandBuffer::getMVKCommandBuffer(cmdBuff)->destroy(); }
} }
} }
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];
} }
void MVKCommandPool::trim() { void MVKCommandPool::trim() {
// TODO: Implement. _commandBufferPool.clear();
} _commandEncodingPool.clear();
_cmdPipelineBarrierPool.clear();
void MVKCommandPool::addCommandBuffer(MVKCommandBuffer* cmdBuffer) { _cmdBindPipelinePool.clear();
_commandBuffers.insert(cmdBuffer); _cmdBeginRenderPassPool.clear();
} _cmdNextSubpassPool.clear();
_cmdExecuteCommandsPool.clear();
void MVKCommandPool::removeCommandBuffer(MVKCommandBuffer* cmdBuffer) { _cmdEndRenderPassPool.clear();
_commandBuffers.erase(cmdBuffer); _cmdBindDescriptorSetsPool.clear();
_cmdSetViewportPool.clear();
_cmdSetScissorPool.clear();
_cmdSetLineWidthPool.clear();
_cmdSetDepthBiasPool.clear();
_cmdSetBlendConstantsPool.clear();
_cmdSetDepthBoundsPool.clear();
_cmdSetStencilCompareMaskPool.clear();
_cmdSetStencilWriteMaskPool.clear();
_cmdSetStencilReferencePool.clear();
_cmdBindVertexBuffersPool.clear();
_cmdBindIndexBufferPool.clear();
_cmdDrawPool.clear();
_cmdDrawIndexedPool.clear();
_cmdDrawIndirectPool.clear();
_cmdDrawIndexedIndirectPool.clear();
_cmdCopyImagePool.clear();
_cmdBlitImagePool.clear();
_cmdResolveImagePool.clear();
_cmdFillBufferPool.clear();
_cmdUpdateBufferPool.clear();
_cmdCopyBufferPool.clear();
_cmdBufferImageCopyPool.clear();
_cmdClearAttachmentsPool.clear();
_cmdClearImagePool.clear();
_cmdBeginQueryPool.clear();
_cmdEndQueryPool.clear();
_cmdWriteTimestampPool.clear();
_cmdResetQueryPoolPool.clear();
_cmdCopyQueryPoolResultsPool.clear();
_cmdPushConstantsPool.clear();
_cmdDispatchPool.clear();
_cmdDispatchIndirectPool.clear();
_cmdPushDescriptorSetPool.clear();
_cmdPushSetWithTemplatePool.clear();
} }
@ -83,6 +131,7 @@ void MVKCommandPool::removeCommandBuffer(MVKCommandBuffer* cmdBuffer) {
MVKCommandPool::MVKCommandPool(MVKDevice* device, MVKCommandPool::MVKCommandPool(MVKDevice* device,
const VkCommandPoolCreateInfo* pCreateInfo) : MVKBaseDeviceObject(device), const VkCommandPoolCreateInfo* pCreateInfo) : MVKBaseDeviceObject(device),
_commandBufferPool(device),
_commandEncodingPool(device), _commandEncodingPool(device),
_queueFamilyIndex(pCreateInfo->queueFamilyIndex), _queueFamilyIndex(pCreateInfo->queueFamilyIndex),
_cmdPipelineBarrierPool(this, true), _cmdPipelineBarrierPool(this, true),
@ -128,7 +177,8 @@ MVKCommandPool::MVKCommandPool(MVKDevice* device,
_cmdPushSetWithTemplatePool(this, true) _cmdPushSetWithTemplatePool(this, true)
{} {}
// TODO: Destroying a command pool implicitly destroys all command buffers and commands created from it. MVKCommandPool::~MVKCommandPool() {
auto cmdBuffs = _commandBuffers;
MVKCommandPool::~MVKCommandPool() {} for (auto& cb : cmdBuffs) { freeCommandBuffer(cb); }
}

View File

@ -55,7 +55,7 @@ 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 command in the linked list. This value should only be * this is a reference to the next instance in the linked list. This value should only be
* managed and set by the linked list. * managed and set by the linked list.
*/ */
MVKMTLBufferAllocation* _next = nullptr; MVKMTLBufferAllocation* _next = nullptr;

View File

@ -313,8 +313,8 @@ public:
protected: protected:
uint32_t _maxSets; uint32_t _maxSets;
uint32_t _allocatedSetCount;
std::forward_list<MVKDescriptorSet*> _allocatedSets; std::forward_list<MVKDescriptorSet*> _allocatedSets;
size_t _allocatedSetCount;
}; };

View File

@ -868,6 +868,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 (_allocatedSetCount + 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.
@ -888,6 +889,7 @@ VkResult MVKDescriptorPool::allocateDescriptorSets(uint32_t count,
} }
VkResult MVKDescriptorPool::freeDescriptorSets(uint32_t count, const VkDescriptorSet* pDescriptorSets) { 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++) { for (uint32_t dsIdx = 0; dsIdx < count; dsIdx++) {
MVKDescriptorSet* mvkDS = (MVKDescriptorSet*)pDescriptorSets[dsIdx]; MVKDescriptorSet* mvkDS = (MVKDescriptorSet*)pDescriptorSets[dsIdx];
if (mvkDS) { if (mvkDS) {
@ -900,6 +902,7 @@ VkResult MVKDescriptorPool::freeDescriptorSets(uint32_t count, const VkDescripto
} }
VkResult MVKDescriptorPool::reset(VkDescriptorPoolResetFlags flags) { VkResult MVKDescriptorPool::reset(VkDescriptorPoolResetFlags flags) {
// MVKLogDebug("Descriptor pool %p resetting with %d descriptor sets.", this, _allocatedSetCount);
mvkDestroyContainerContents(_allocatedSets); mvkDestroyContainerContents(_allocatedSets);
_allocatedSetCount = 0; _allocatedSetCount = 0;
return VK_SUCCESS; return VK_SUCCESS;
@ -909,12 +912,13 @@ MVKDescriptorPool::MVKDescriptorPool(MVKDevice* device,
const VkDescriptorPoolCreateInfo* pCreateInfo) : MVKBaseDeviceObject(device) { const VkDescriptorPoolCreateInfo* pCreateInfo) : MVKBaseDeviceObject(device) {
_maxSets = pCreateInfo->maxSets; _maxSets = pCreateInfo->maxSets;
_allocatedSetCount = 0; _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. // TODO: Destroying a descriptor pool implicitly destroys all descriptor sets created from it.
MVKDescriptorPool::~MVKDescriptorPool() { MVKDescriptorPool::~MVKDescriptorPool() {
// MVKLogDebug("Pool %p destroyed with %d descriptor sets.", this, _allocatedSetCount); // MVKLogDebug("Descriptor pool %p destroyed with %d descriptor sets.", this, _allocatedSetCount);
reset(0); reset(0);
} }

View File

@ -95,7 +95,7 @@ public:
* This is the compliment of the getVkHandle() method. * This is the compliment of the getVkHandle() method.
*/ */
static inline MVKDispatchableObject* getDispatchableObject(void* vkHandle) { static inline MVKDispatchableObject* getDispatchableObject(void* vkHandle) {
return ((MVKDispatchableObjectICDRef*)vkHandle)->mvkObject; return vkHandle ? ((MVKDispatchableObjectICDRef*)vkHandle)->mvkObject : nullptr;
} }
protected: protected:

View File

@ -76,6 +76,8 @@ public:
* aquireObject() and returnObject() must be made from the same thread. * aquireObject() and returnObject() must be made from the same thread.
*/ */
void returnObject(T* obj) { void returnObject(T* obj) {
if ( !obj ) { return; }
if (_isPooling) { if (_isPooling) {
if (_tail) { _tail->_next = obj; } if (_tail) { _tail->_next = obj; }
obj->_next = VK_NULL_HANDLE; obj->_next = VK_NULL_HANDLE;