MVKCommandBuffer track rendering viewMask from commands.

This commit is contained in:
Bill Hollings 2023-02-22 17:24:46 -05:00
parent b6835f7298
commit 5d96a849b0
5 changed files with 70 additions and 14 deletions

View File

@ -299,12 +299,13 @@ typedef struct {
uint32_t maxActiveMetalCommandBuffersPerQueue;
/**
* Metal allows only 8192 occlusion queries per MTLBuffer. If enabled, MoltenVK
* allocates a MTLBuffer for each query pool, allowing each query pool to support
* 8192 queries, which may slow performance or cause unexpected behaviour if the query
* pool is not established prior to a Metal renderpass, or if the query pool is changed
* within a renderpass. If disabled, one MTLBuffer will be shared by all query pools,
* which improves performance, but limits the total device queries to 8192.
* Depending on the GPU, Metal allows 8192 or 32768 occlusion queries per MTLBuffer.
* If enabled, MoltenVK allocates a MTLBuffer for each query pool, allowing each query
* pool to support that permitted number of queries. This may slow performance or cause
* unexpected behaviour if the query pool is not established prior to a Metal renderpass,
* or if the query pool is changed within a renderpass. If disabled, one MTLBuffer will
* be shared by all query pools, which improves performance, but limits the total device
* queries to the permitted number.
*
* The value of this parameter may be changed at any time during application runtime,
* and the changed value will immediately effect subsequent MoltenVK behaviour.

View File

@ -61,6 +61,8 @@ VkResult MVKCmdBeginRenderPassBase::setContent(MVKCommandBuffer* cmdBuff,
}
}
cmdBuff->_currentSubpassInfo.beginRenderpass(_renderPass);
return VK_SUCCESS;
}
@ -126,6 +128,8 @@ VkResult MVKCmdNextSubpass::setContent(MVKCommandBuffer* cmdBuff,
VkSubpassContents contents) {
_contents = contents;
cmdBuff->_currentSubpassInfo.nextSubpass();
return VK_SUCCESS;
}
@ -144,12 +148,13 @@ void MVKCmdNextSubpass::encode(MVKCommandEncoder* cmdEncoder) {
#pragma mark MVKCmdEndRenderPass
VkResult MVKCmdEndRenderPass::setContent(MVKCommandBuffer* cmdBuff) {
cmdBuff->_currentSubpassInfo = {};
return VK_SUCCESS;
}
VkResult MVKCmdEndRenderPass::setContent(MVKCommandBuffer* cmdBuff,
const VkSubpassEndInfo* pEndSubpassInfo) {
return VK_SUCCESS;
return setContent(cmdBuff);
}
void MVKCmdEndRenderPass::encode(MVKCommandEncoder* cmdEncoder) {
@ -178,6 +183,8 @@ VkResult MVKCmdBeginRendering<N>::setContent(MVKCommandBuffer* cmdBuff,
_renderingInfo.pStencilAttachment = &_stencilAttachment;
}
cmdBuff->_currentSubpassInfo.beginRendering(pRenderingInfo->viewMask);
return VK_SUCCESS;
}
@ -196,6 +203,7 @@ template class MVKCmdBeginRendering<8>;
#pragma mark MVKCmdEndRendering
VkResult MVKCmdEndRendering::setContent(MVKCommandBuffer* cmdBuff) {
cmdBuff->_currentSubpassInfo = {};
return VK_SUCCESS;
}

View File

@ -65,6 +65,24 @@ private:
} MVKCommandEncodingContext;
#pragma mark -
#pragma mark MVKCurrentSubpassInfo
/** Tracks current render subpass information. */
typedef struct MVKCurrentSubpassInfo {
MVKRenderPass* renderpass;
uint32_t subpassIndex;
uint32_t subpassViewMask;
void beginRenderpass(MVKRenderPass* rp);
void nextSubpass();
void beginRendering(uint32_t viewMask);
private:
void updateViewMask();
} MVKCurrentSubpassInfo;
#pragma mark -
#pragma mark MVKCommandBuffer
@ -113,6 +131,9 @@ public:
*/
uint32_t getViewCount() const;
/** Updated as renderpass commands are added. */
MVKCurrentSubpassInfo _currentSubpassInfo;
/**
* Metal requires that a visibility buffer is established when a render pass is created,
* but Vulkan permits it to be set during a render pass. When the first occlusion query
@ -176,7 +197,7 @@ protected:
MVKSmallVector<VkFormat, kMVKDefaultAttachmentCount> _colorAttachmentFormats;
MVKCommandPool* _commandPool;
VkCommandBufferInheritanceInfo _secondaryInheritanceInfo;
VkCommandBufferInheritanceRenderingInfo _secondaryInerhitanceRenderingInfo;
VkCommandBufferInheritanceRenderingInfo _secondaryInheritanceRenderingInfo;
id<MTLCommandBuffer> _prefilledMTLCmdBuffer = nil;
MVKCommandEncodingContext* _immediateCmdEncodingContext = nullptr;
MVKCommandEncoder* _immediateCmdEncoder = nullptr;

View File

@ -30,6 +30,7 @@
using namespace std;
#pragma mark -
#pragma mark MVKCommandEncodingContext
@ -57,6 +58,28 @@ MVKCommandEncodingContext::~MVKCommandEncodingContext() {
}
#pragma mark -
#pragma mark MVKCurrentSubpassInfo
void MVKCurrentSubpassInfo::beginRenderpass(MVKRenderPass* rp) {
renderpass = rp;
subpassIndex = 0;
updateViewMask();
}
void MVKCurrentSubpassInfo::nextSubpass() {
subpassIndex++;
updateViewMask();
}
void MVKCurrentSubpassInfo::beginRendering(uint32_t viewMask) {
renderpass = nullptr;
subpassIndex = 0;
subpassViewMask = viewMask;
}
void MVKCurrentSubpassInfo::updateViewMask() {
subpassViewMask = renderpass ? renderpass->getSubpass(subpassIndex)->getViewMask() : 0;
}
#pragma mark -
#pragma mark MVKCommandBuffer
@ -80,11 +103,11 @@ VkResult MVKCommandBuffer::begin(const VkCommandBufferBeginInfo* pBeginInfo) {
for (const auto* next = (VkBaseInStructure*)_secondaryInheritanceInfo.pNext; next; next = next->pNext) {
switch (next->sType) {
case VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO: {
if (mvkSetOrClear(&_secondaryInerhitanceRenderingInfo, (VkCommandBufferInheritanceRenderingInfo*)next)) {
for (uint32_t caIdx = 0; caIdx < _secondaryInerhitanceRenderingInfo.colorAttachmentCount; caIdx++) {
_colorAttachmentFormats.push_back(_secondaryInerhitanceRenderingInfo.pColorAttachmentFormats[caIdx]);
if (mvkSetOrClear(&_secondaryInheritanceRenderingInfo, (VkCommandBufferInheritanceRenderingInfo*)next)) {
for (uint32_t caIdx = 0; caIdx < _secondaryInheritanceRenderingInfo.colorAttachmentCount; caIdx++) {
_colorAttachmentFormats.push_back(_secondaryInheritanceRenderingInfo.pColorAttachmentFormats[caIdx]);
}
_secondaryInerhitanceRenderingInfo.pColorAttachmentFormats = _colorAttachmentFormats.data();
_secondaryInheritanceRenderingInfo.pColorAttachmentFormats = _colorAttachmentFormats.data();
}
break;
}
@ -147,6 +170,7 @@ VkResult MVKCommandBuffer::reset(VkCommandBufferResetFlags flags) {
_wasExecuted = false;
_isExecutingNonConcurrently.clear();
_commandCount = 0;
_currentSubpassInfo = {};
_needsVisibilityResultMTLBuffer = false;
_hasStageCounterTimestampCommand = false;
_lastTessellationPipeline = nullptr;
@ -247,8 +271,10 @@ uint32_t MVKCommandBuffer::getViewCount() const {
if (inheritedRenderPass) {
viewMask = inheritedRenderPass->getSubpass(_secondaryInheritanceInfo.subpass)->getViewMask();
} else {
viewMask = _secondaryInerhitanceRenderingInfo.viewMask;
viewMask = _secondaryInheritanceRenderingInfo.viewMask;
}
} else {
viewMask = _currentSubpassInfo.subpassViewMask;
}
return max(__builtin_popcount(viewMask), 1);
}

View File

@ -118,7 +118,7 @@ void mvkSetConfig(const MVKConfiguration& mvkConfig);
# define MVK_CONFIG_MAX_ACTIVE_METAL_COMMAND_BUFFERS_PER_QUEUE 64
#endif
/** Support more than 8192 occlusion queries per buffer. Enabled by default. */
/** Support more than 8192 or 32768 occlusion queries per device. Enabled by default. */
#ifndef MVK_CONFIG_SUPPORT_LARGE_QUERY_POOLS
# define MVK_CONFIG_SUPPORT_LARGE_QUERY_POOLS 1
#endif