Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for VK_EXT_extended_dynamic_state3 extension. #2066

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Docs/MoltenVK_Runtime_UserGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,8 @@ In addition to core *Vulkan* functionality, **MoltenVK** also supports the foll
- *Requires Metal 3.1 for `VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE`.*
- `VK_EXT_extended_dynamic_state2`
- *Primitive restart is always enabled, as Metal does not support disabling it (`VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT`).*
- `VK_EXT_extended_dynamic_state3`
- *Metal does not support `VK_POLYGON_MODE_POINT`*
- `VK_EXT_external_memory_host`
- `VK_EXT_fragment_shader_interlock`
- *Requires Metal 2.0 and Raster Order Groups.*
Expand Down
4 changes: 4 additions & 0 deletions Docs/Whats_New.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ MoltenVK 1.2.7

Released TBD

- Add support for extensions:
- `VK_EXT_extended_dynamic_state3` *(Metal does not support `VK_POLYGON_MODE_POINT`)*
- Fix regression that broke `VK_POLYGON_MODE_LINE`.
- Fix regression in marking rendering state dirty after `vkCmdClearAttachments()`.
- Reduce disk space consumed after running `fetchDependencies` script by removing intermediate file caches.
- Update to latest SPIRV-Cross:
- MSL: Fix regression error in argument buffer runtime arrays.
Expand Down
25 changes: 13 additions & 12 deletions MoltenVK/MoltenVK/Commands/MVKCmdDraw.mm
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,9 @@

void MVKCmdDraw::encode(MVKCommandEncoder* cmdEncoder) {

if (_vertexCount == 0 || _instanceCount == 0) {
// Nothing to do.
return;
}
if (_vertexCount == 0 || _instanceCount == 0) { return; } // Nothing to do.

cmdEncoder->restartMetalRenderPassIfNeeded();

auto* pipeline = cmdEncoder->_graphicsPipelineState.getGraphicsPipeline();

Expand All @@ -172,7 +171,7 @@
} tessParams;
uint32_t outControlPointCount = 0;
if (pipeline->isTessellationPipeline()) {
tessParams.inControlPointCount = cmdEncoder->_graphicsPipelineState.getPatchControlPoints();
tessParams.inControlPointCount = cmdEncoder->_renderingState.getPatchControlPoints();
outControlPointCount = pipeline->getOutputControlPointCount();
tessParams.patchCount = mvkCeilingDivide(_vertexCount, tessParams.inControlPointCount) * _instanceCount;
}
Expand Down Expand Up @@ -369,10 +368,9 @@

void MVKCmdDrawIndexed::encode(MVKCommandEncoder* cmdEncoder) {

if (_indexCount == 0 || _instanceCount == 0) {
// Nothing to do.
return;
}
if (_indexCount == 0 || _instanceCount == 0) { return; } // Nothing to do.

cmdEncoder->restartMetalRenderPassIfNeeded();

auto* pipeline = cmdEncoder->_graphicsPipelineState.getGraphicsPipeline();

Expand Down Expand Up @@ -401,7 +399,7 @@
} tessParams;
uint32_t outControlPointCount = 0;
if (pipeline->isTessellationPipeline()) {
tessParams.inControlPointCount = cmdEncoder->_graphicsPipelineState.getPatchControlPoints();
tessParams.inControlPointCount = cmdEncoder->_renderingState.getPatchControlPoints();
outControlPointCount = pipeline->getOutputControlPointCount();
tessParams.patchCount = mvkCeilingDivide(_indexCount, tessParams.inControlPointCount) * _instanceCount;
}
Expand Down Expand Up @@ -649,6 +647,8 @@

void MVKCmdDrawIndirect::encode(MVKCommandEncoder* cmdEncoder) {

cmdEncoder->restartMetalRenderPassIfNeeded();

auto* pipeline = cmdEncoder->_graphicsPipelineState.getGraphicsPipeline();

// Metal doesn't support triangle fans, so encode it as indexed indirect triangles instead.
Expand Down Expand Up @@ -686,7 +686,7 @@
// encoding and execution. So we don't know how big to make the buffers.
// We must assume an arbitrarily large number of vertices may be submitted.
// But not too many, or we'll exhaust available VRAM.
inControlPointCount = cmdEncoder->_graphicsPipelineState.getPatchControlPoints();
inControlPointCount = cmdEncoder->_renderingState.getPatchControlPoints();
outControlPointCount = pipeline->getOutputControlPointCount();
vertexCount = kMVKMaxDrawIndirectVertexCount;
patchCount = mvkCeilingDivide(vertexCount, inControlPointCount);
Expand Down Expand Up @@ -990,6 +990,7 @@
}

void MVKCmdDrawIndexedIndirect::encode(MVKCommandEncoder* cmdEncoder) {
cmdEncoder->restartMetalRenderPassIfNeeded();
encode(cmdEncoder, cmdEncoder->_graphicsResourcesState._mtlIndexBufferBinding);
}

Expand Down Expand Up @@ -1034,7 +1035,7 @@
// encoding and execution. So we don't know how big to make the buffers.
// We must assume an arbitrarily large number of vertices may be submitted.
// But not too many, or we'll exhaust available VRAM.
inControlPointCount = cmdEncoder->_graphicsPipelineState.getPatchControlPoints();
inControlPointCount = cmdEncoder->_renderingState.getPatchControlPoints();
outControlPointCount = pipeline->getOutputControlPointCount();
vertexCount = kMVKMaxDrawIndirectVertexCount;
patchCount = mvkCeilingDivide(vertexCount, inControlPointCount);
Expand Down
60 changes: 58 additions & 2 deletions MoltenVK/MoltenVK/Commands/MVKCmdRendering.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ class MVKCmdBeginRenderPassBase : public MVKCommand {

protected:

MVKSmallVector<MVKSmallVector<MTLSamplePosition>> _subpassSamplePositions;
MVKRenderPass* _renderPass;
MVKFramebuffer* _framebuffer;
VkRect2D _renderArea;
Expand Down Expand Up @@ -203,7 +202,26 @@ class MVKCmdSetSampleLocations : public MVKCommand {
protected:
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;

MVKSmallVector<MTLSamplePosition, 8> _samplePositions;
MVKSmallVector<VkSampleLocationEXT, kMVKMaxSampleCount> _sampleLocations;
};


#pragma mark -
#pragma mark MVKCmdSetSampleLocationsEnable

/** Vulkan command to dynamically enable custom sample locations. */
class MVKCmdSetSampleLocationsEnable : public MVKCommand {

public:
VkResult setContent(MVKCommandBuffer* cmdBuff,
VkBool32 sampleLocationsEnable);

void encode(MVKCommandEncoder* cmdEncoder) override;

protected:
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;

VkBool32 _sampleLocationsEnable;
};


Expand Down Expand Up @@ -366,6 +384,25 @@ class MVKCmdSetDepthWriteEnable : public MVKCommand {
};


#pragma mark -
#pragma mark MVKCmdSetDepthClipEnable

/** Vulkan command to dynamically enable depth clip. */
class MVKCmdSetDepthClipEnable : public MVKCommand {

public:
VkResult setContent(MVKCommandBuffer* cmdBuff,
VkBool32 depthClipEnable);

void encode(MVKCommandEncoder* cmdEncoder) override;

protected:
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;

VkBool32 _depthClipEnable;
};


#pragma mark -
#pragma mark MVKCmdSetDepthCompareOp

Expand Down Expand Up @@ -551,6 +588,25 @@ class MVKCmdSetPatchControlPoints : public MVKCommand {
};


#pragma mark -
#pragma mark MVKCmdSetPolygonMode

/** Vulkan command to dynamically set the polygon mode. */
class MVKCmdSetPolygonMode : public MVKCommand {

public:
VkResult setContent(MVKCommandBuffer* cmdBuff,
VkPolygonMode polygonMode);

void encode(MVKCommandEncoder* cmdEncoder) override;

protected:
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;

VkPolygonMode _polygonMode;
};


#pragma mark -
#pragma mark MVKCmdSetPrimitiveTopology

Expand Down
91 changes: 49 additions & 42 deletions MoltenVK/MoltenVK/Commands/MVKCmdRendering.mm
Original file line number Diff line number Diff line change
Expand Up @@ -36,30 +36,6 @@
_renderPass = (MVKRenderPass*)pRenderPassBegin->renderPass;
_framebuffer = (MVKFramebuffer*)pRenderPassBegin->framebuffer;
_renderArea = pRenderPassBegin->renderArea;
_subpassSamplePositions.clear();

for (const auto* next = (VkBaseInStructure*)pRenderPassBegin->pNext; next; next = next->pNext) {
switch (next->sType) {
case VK_STRUCTURE_TYPE_RENDER_PASS_SAMPLE_LOCATIONS_BEGIN_INFO_EXT: {
// Build an array of arrays, one array of sample positions for each subpass index.
// For subpasses not included in VkRenderPassSampleLocationsBeginInfoEXT, the resulting array of samples will be empty.
_subpassSamplePositions.resize(_renderPass->getSubpassCount());
auto* pRPSampLocnsInfo = (VkRenderPassSampleLocationsBeginInfoEXT*)next;
for (uint32_t spSLIdx = 0; spSLIdx < pRPSampLocnsInfo->postSubpassSampleLocationsCount; spSLIdx++) {
auto& spsl = pRPSampLocnsInfo->pPostSubpassSampleLocations[spSLIdx];
uint32_t spIdx = spsl.subpassIndex;
auto& spSampPosns = _subpassSamplePositions[spIdx];
for (uint32_t slIdx = 0; slIdx < spsl.sampleLocationsInfo.sampleLocationsCount; slIdx++) {
auto& sl = spsl.sampleLocationsInfo.pSampleLocations[slIdx];
spSampPosns.push_back(MTLSamplePositionMake(sl.x, sl.y));
}
}
break;
}
default:
break;
}
}

cmdBuff->_currentSubpassInfo.beginRenderpass(_renderPass);

Expand All @@ -86,23 +62,14 @@

template <size_t N_CV, size_t N_A>
void MVKCmdBeginRenderPass<N_CV, N_A>::encode(MVKCommandEncoder* cmdEncoder) {

// Convert the sample position array of arrays to an array of array-references,
// so that it can be passed to the command encoder.
size_t spSPCnt = _subpassSamplePositions.size();
MVKArrayRef<MTLSamplePosition> spSPRefs[spSPCnt];
for (uint32_t spSPIdx = 0; spSPIdx < spSPCnt; spSPIdx++) {
spSPRefs[spSPIdx] = _subpassSamplePositions[spSPIdx].contents();
}

cmdEncoder->beginRenderpass(this,
_contents,
_renderPass,
_framebuffer,
_renderArea,
_clearValues.contents(),
_attachments.contents(),
MVKArrayRef(spSPRefs, spSPCnt));
kMVKCommandUseBeginRenderPass);
}

template class MVKCmdBeginRenderPass<1, 0>;
Expand Down Expand Up @@ -217,17 +184,29 @@

VkResult MVKCmdSetSampleLocations::setContent(MVKCommandBuffer* cmdBuff,
const VkSampleLocationsInfoEXT* pSampleLocationsInfo) {

_sampleLocations.clear();
for (uint32_t slIdx = 0; slIdx < pSampleLocationsInfo->sampleLocationsCount; slIdx++) {
auto& sl = pSampleLocationsInfo->pSampleLocations[slIdx];
_samplePositions.push_back(MTLSamplePositionMake(sl.x, sl.y));
_sampleLocations.push_back(pSampleLocationsInfo->pSampleLocations[slIdx]);
}

return VK_SUCCESS;
}

void MVKCmdSetSampleLocations::encode(MVKCommandEncoder* cmdEncoder) {
cmdEncoder->setDynamicSamplePositions(_samplePositions.contents());
cmdEncoder->_renderingState.setSampleLocations(_sampleLocations.contents(), true);
}


#pragma mark -
#pragma mark MVKCmdSetSampleLocationsEnable

VkResult MVKCmdSetSampleLocationsEnable::setContent(MVKCommandBuffer* cmdBuff,
VkBool32 sampleLocationsEnable) {
_sampleLocationsEnable = sampleLocationsEnable;
return VK_SUCCESS;
}

void MVKCmdSetSampleLocationsEnable::encode(MVKCommandEncoder* cmdEncoder) {
cmdEncoder->_renderingState.setSampleLocationsEnable(_sampleLocationsEnable, true);
}


Expand All @@ -240,7 +219,7 @@
uint32_t viewportCount,
const VkViewport* pViewports) {
_firstViewport = firstViewport;
_viewports.clear(); // Clear for reuse
_viewports.clear();
_viewports.reserve(viewportCount);
for (uint32_t vpIdx = 0; vpIdx < viewportCount; vpIdx++) {
_viewports.push_back(pViewports[vpIdx]);
Expand All @@ -267,7 +246,7 @@
uint32_t scissorCount,
const VkRect2D* pScissors) {
_firstScissor = firstScissor;
_scissors.clear(); // Clear for reuse
_scissors.clear();
_scissors.reserve(scissorCount);
for (uint32_t sIdx = 0; sIdx < scissorCount; sIdx++) {
_scissors.push_back(pScissors[sIdx]);
Expand Down Expand Up @@ -362,6 +341,20 @@
}


#pragma mark -
#pragma mark MVKCmdSetDepthClipEnable

VkResult MVKCmdSetDepthClipEnable::setContent(MVKCommandBuffer* cmdBuff,
VkBool32 depthClipEnable) {
_depthClipEnable = depthClipEnable;
return VK_SUCCESS;
}

void MVKCmdSetDepthClipEnable::encode(MVKCommandEncoder* cmdEncoder) {
cmdEncoder->_renderingState.setDepthClipEnable(_depthClipEnable, true);
}


#pragma mark -
#pragma mark MVKCmdSetDepthCompareOp

Expand Down Expand Up @@ -501,7 +494,21 @@
}

void MVKCmdSetPatchControlPoints::encode(MVKCommandEncoder* cmdEncoder) {
cmdEncoder->_graphicsPipelineState.setPatchControlPoints(_patchControlPoints);
cmdEncoder->_renderingState.setPatchControlPoints(_patchControlPoints, true);
}


#pragma mark -
#pragma mark MVKCmdSetPolygonMode

VkResult MVKCmdSetPolygonMode::setContent(MVKCommandBuffer* cmdBuff,
VkPolygonMode polygonMode) {
_polygonMode = polygonMode;
return VK_SUCCESS;
}

void MVKCmdSetPolygonMode::encode(MVKCommandEncoder* cmdEncoder) {
cmdEncoder->_renderingState.setPolygonMode(_polygonMode, true);
}


Expand Down
2 changes: 2 additions & 0 deletions MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1506,8 +1506,10 @@ static inline MTLSize mvkClampMTLSize(MTLSize size, MTLOrigin origin, MTLSize ma

// Return to the previous rendering state on the next render activity
cmdEncoder->_graphicsPipelineState.markDirty();
cmdEncoder->_graphicsResourcesState.markDirty();
cmdEncoder->_depthStencilState.markDirty();
cmdEncoder->_renderingState.markDirty();
cmdEncoder->_occlusionQueryState.markDirty();
}

template <size_t N>
Expand Down
Loading