Merge pull request #864 from billhollings/master
In MVKCommand subclasses, replace holding Metal content with holding smaller Vulkan equivalents.
diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdDispatch.h b/MoltenVK/MoltenVK/Commands/MVKCmdDispatch.h
index 1dd9afc..336355d 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCmdDispatch.h
+++ b/MoltenVK/MoltenVK/Commands/MVKCmdDispatch.h
@@ -40,7 +40,12 @@
protected:
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
- MTLRegion _mtlThreadgroupCount;
+ uint32_t _baseGroupX;
+ uint32_t _baseGroupY;
+ uint32_t _baseGroupZ;
+ uint32_t _groupCountX;
+ uint32_t _groupCountY;
+ uint32_t _groupCountZ;
};
@@ -59,6 +64,6 @@
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
id<MTLBuffer> _mtlIndirectBuffer;
- NSUInteger _mtlIndirectBufferOffset;
+ VkDeviceSize _mtlIndirectBufferOffset;
};
diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdDispatch.mm b/MoltenVK/MoltenVK/Commands/MVKCmdDispatch.mm
index fd4479b..4a4fc48 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCmdDispatch.mm
+++ b/MoltenVK/MoltenVK/Commands/MVKCmdDispatch.mm
@@ -33,7 +33,13 @@
VkResult MVKCmdDispatch::setContent(MVKCommandBuffer* cmdBuff,
uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ,
uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ) {
- _mtlThreadgroupCount = MTLRegionMake3D(baseGroupX, baseGroupY, baseGroupZ, groupCountX, groupCountY, groupCountZ);
+ _baseGroupX = baseGroupX;
+ _baseGroupY = baseGroupY;
+ _baseGroupZ = baseGroupZ;
+
+ _groupCountX = groupCountX;
+ _groupCountY = groupCountY;
+ _groupCountZ = groupCountZ;
return VK_SUCCESS;
}
@@ -41,6 +47,7 @@
void MVKCmdDispatch::encode(MVKCommandEncoder* cmdEncoder) {
// MVKLogDebug("vkCmdDispatch() dispatching (%d, %d, %d) threadgroups.", _x, _y, _z);
+ MTLRegion mtlThreadgroupCount = MTLRegionMake3D(_baseGroupX, _baseGroupY, _baseGroupZ, _groupCountX, _groupCountY, _groupCountZ);
cmdEncoder->finalizeDispatchState(); // Ensure all updated state has been submitted to Metal
id<MTLComputeCommandEncoder> mtlEncoder = cmdEncoder->getMTLComputeEncoder(kMVKCommandUseDispatch);
auto* pipeline = (MVKComputePipeline*)cmdEncoder->_computePipelineState.getPipeline();
@@ -48,14 +55,14 @@
if ([mtlEncoder respondsToSelector: @selector(setStageInRegion:)]) {
// We'll use the stage-input region to pass the base along to the shader.
// Hopefully Metal won't complain that we didn't set up a stage-input descriptor.
- [mtlEncoder setStageInRegion: _mtlThreadgroupCount];
+ [mtlEncoder setStageInRegion: mtlThreadgroupCount];
} else {
// We have to pass the base group in a buffer.
- unsigned int base[3] = {(uint32_t)_mtlThreadgroupCount.origin.x, (uint32_t)_mtlThreadgroupCount.origin.y, (uint32_t)_mtlThreadgroupCount.origin.z};
+ uint32_t base[3] = {(uint32_t)mtlThreadgroupCount.origin.x, (uint32_t)mtlThreadgroupCount.origin.y, (uint32_t)mtlThreadgroupCount.origin.z};
cmdEncoder->setComputeBytes(mtlEncoder, base, sizeof(base), pipeline->getIndirectParamsIndex().stages[kMVKShaderStageCompute]);
}
}
- [mtlEncoder dispatchThreadgroups: _mtlThreadgroupCount.size
+ [mtlEncoder dispatchThreadgroups: mtlThreadgroupCount.size
threadsPerThreadgroup: cmdEncoder->_mtlThreadgroupSize];
}
diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdDraw.h b/MoltenVK/MoltenVK/Commands/MVKCmdDraw.h
index 4039a63..8d453fe 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCmdDraw.h
+++ b/MoltenVK/MoltenVK/Commands/MVKCmdDraw.h
@@ -139,7 +139,7 @@
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
id<MTLBuffer> _mtlIndirectBuffer;
- NSUInteger _mtlIndirectBufferOffset;
+ VkDeviceSize _mtlIndirectBufferOffset;
uint32_t _mtlIndirectBufferStride;
uint32_t _drawCount;
};
diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.h b/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.h
index 78bc7e0..330c21e 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.h
+++ b/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.h
@@ -125,7 +125,7 @@
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
uint32_t _firstViewport;
- MVKVectorInline<MTLViewport, kMVKCachedViewportScissorCount> _mtlViewports;
+ MVKVectorInline<VkViewport, kMVKCachedViewportScissorCount> _viewports;
};
@@ -147,7 +147,7 @@
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
uint32_t _firstScissor;
- MVKVectorInline<MTLScissorRect, kMVKCachedViewportScissorCount> _mtlScissors;
+ MVKVectorInline<VkRect2D, kMVKCachedViewportScissorCount> _scissors;
};
diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.mm b/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.mm
index d8b4925..d4a58a1 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.mm
+++ b/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.mm
@@ -124,17 +124,17 @@
uint32_t viewportCount,
const VkViewport* pViewports) {
_firstViewport = firstViewport;
- _mtlViewports.clear(); // Clear for reuse
- _mtlViewports.reserve(viewportCount);
- for (uint32_t i = 0; i < viewportCount; i++) {
- _mtlViewports.push_back(mvkMTLViewportFromVkViewport(pViewports[i]));
+ _viewports.clear(); // Clear for reuse
+ _viewports.reserve(viewportCount);
+ for (uint32_t vpIdx = 0; vpIdx < viewportCount; vpIdx++) {
+ _viewports.push_back(pViewports[vpIdx]);
}
return VK_SUCCESS;
}
void MVKCmdSetViewport::encode(MVKCommandEncoder* cmdEncoder) {
- cmdEncoder->_viewportState.setViewports(_mtlViewports, _firstViewport, true);
+ cmdEncoder->_viewportState.setViewports(_viewports, _firstViewport, true);
}
@@ -148,17 +148,17 @@
uint32_t scissorCount,
const VkRect2D* pScissors) {
_firstScissor = firstScissor;
- _mtlScissors.clear(); // Clear for reuse
- _mtlScissors.reserve(scissorCount);
- for (uint32_t i = 0; i < scissorCount; i++) {
- _mtlScissors.push_back(mvkMTLScissorRectFromVkRect2D(pScissors[i]));
+ _scissors.clear(); // Clear for reuse
+ _scissors.reserve(scissorCount);
+ for (uint32_t sIdx = 0; sIdx < scissorCount; sIdx++) {
+ _scissors.push_back(pScissors[sIdx]);
}
return VK_SUCCESS;
}
void MVKCmdSetScissor::encode(MVKCommandEncoder* cmdEncoder) {
- cmdEncoder->_scissorState.setScissors(_mtlScissors, _firstScissor, true);
+ cmdEncoder->_scissorState.setScissors(_scissors, _firstScissor, true);
}
diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.h b/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.h
index 1f73921..66e316a 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.h
+++ b/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.h
@@ -64,8 +64,6 @@
VkImageLayout _srcLayout;
MVKImage* _dstImage;
VkImageLayout _dstLayout;
- MTLPixelFormat _srcMTLPixFmt;
- MTLPixelFormat _dstMTLPixFmt;
uint32_t _srcSampleCount;
uint32_t _dstSampleCount;
bool _isSrcCompressed;
@@ -131,8 +129,8 @@
/** Describes Metal texture resolve parameters. */
typedef struct {
- NSUInteger level;
- NSUInteger slice;
+ uint32_t level;
+ uint32_t slice;
} MVKMetalResolveSlice;
/** Vulkan command to resolve image regions. */
@@ -282,9 +280,7 @@
MVKImage* _image;
VkImageLayout _imgLayout;
MVKVectorInline<VkImageSubresourceRange, 4> _subresourceRanges;
- MTLClearColor _mtlColorClearValue;
- double _mtlDepthClearValue;
- uint32_t _mtlStencilClearValue;
+ VkClearValue _clearValue;
bool _isDepthStencilClear;
};
diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm b/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm
index 5af4cae..604887d 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm
+++ b/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm
@@ -88,23 +88,23 @@
_srcImage = (MVKImage*)srcImage;
_srcLayout = srcImageLayout;
- _srcMTLPixFmt = _srcImage->getMTLPixelFormat();
_srcSampleCount = mvkSampleCountFromVkSampleCountFlagBits(_srcImage->getSampleCount());
_isSrcCompressed = _srcImage->getIsCompressed();
- uint32_t srcBytesPerBlock = pixFmts->getMTLPixelFormatBytesPerBlock(_srcMTLPixFmt);
+ MTLPixelFormat srcMTLPixFmt = _srcImage->getMTLPixelFormat();
+ uint32_t srcBytesPerBlock = pixFmts->getMTLPixelFormatBytesPerBlock(srcMTLPixFmt);
_dstImage = (MVKImage*)dstImage;
_dstLayout = dstImageLayout;
- _dstMTLPixFmt = _dstImage->getMTLPixelFormat();
_dstSampleCount = mvkSampleCountFromVkSampleCountFlagBits(_dstImage->getSampleCount());
_isDstCompressed = _dstImage->getIsCompressed();
- uint32_t dstBytesPerBlock = pixFmts->getMTLPixelFormatBytesPerBlock(_dstMTLPixFmt);
+ MTLPixelFormat dstMTLPixFmt = _dstImage->getMTLPixelFormat();
+ uint32_t dstBytesPerBlock = pixFmts->getMTLPixelFormatBytesPerBlock(dstMTLPixFmt);
_canCopyFormats = (_dstSampleCount == _srcSampleCount) && (formatsMustMatch
- ? (_dstMTLPixFmt == _srcMTLPixFmt)
+ ? (dstMTLPixFmt == srcMTLPixFmt)
: (dstBytesPerBlock == srcBytesPerBlock));
- _useTempBuffer = (_srcMTLPixFmt != _dstMTLPixFmt) && (_isSrcCompressed || _isDstCompressed); // Different formats and at least one is compressed
+ _useTempBuffer = (srcMTLPixFmt != dstMTLPixFmt) && (_isSrcCompressed || _isDstCompressed); // Different formats and at least one is compressed
_commandUse = commandUse;
_tmpBuffSize = 0;
@@ -141,9 +141,10 @@
// Extent is provided in source texels. If the source is compressed but the
// destination is not, each destination pixel will consume an entire source block,
// so we must downscale the destination extent by the size of the source block.
+ MTLPixelFormat srcMTLPixFmt = _srcImage->getMTLPixelFormat();
VkExtent3D dstExtent = region.extent;
if (_isSrcCompressed && !_isDstCompressed) {
- VkExtent2D srcBlockExtent = pixFmts->getMTLPixelFormatBlockTexelSize(_srcMTLPixFmt);
+ VkExtent2D srcBlockExtent = pixFmts->getMTLPixelFormatBlockTexelSize(srcMTLPixFmt);
dstExtent.width /= srcBlockExtent.width;
dstExtent.height /= srcBlockExtent.height;
}
@@ -155,8 +156,8 @@
buffImgCpy.imageExtent = dstExtent;
_dstTmpBuffImgCopies.push_back(buffImgCpy);
- NSUInteger bytesPerRow = pixFmts->getMTLPixelFormatBytesPerRow(_srcMTLPixFmt, region.extent.width);
- NSUInteger bytesPerRegion = pixFmts->getMTLPixelFormatBytesPerLayer(_srcMTLPixFmt, bytesPerRow, region.extent.height);
+ NSUInteger bytesPerRow = pixFmts->getMTLPixelFormatBytesPerRow(srcMTLPixFmt, region.extent.width);
+ NSUInteger bytesPerRegion = pixFmts->getMTLPixelFormatBytesPerLayer(srcMTLPixFmt, bytesPerRow, region.extent.height);
_tmpBuffSize += bytesPerRegion;
}
@@ -164,7 +165,7 @@
// Unless we need to use an intermediary buffer copy, map the source pixel format to the
// dest pixel format through a texture view on the source texture. If the source and dest
// pixel formats are the same, this will simply degenerate to the source texture itself.
- MTLPixelFormat mapSrcMTLPixFmt = _useTempBuffer ? _srcMTLPixFmt : _dstMTLPixFmt;
+ MTLPixelFormat mapSrcMTLPixFmt = (_useTempBuffer ? _srcImage : _dstImage)->getMTLPixelFormat();
id<MTLTexture> srcMTLTex = _srcImage->getMTLTexture(mapSrcMTLPixFmt);
id<MTLTexture> dstMTLTex = _dstImage->getMTLTexture();
if ( !srcMTLTex || !dstMTLTex ) { return; }
@@ -251,9 +252,9 @@
VkResult rslt = MVKCmdCopyImage::setContent(cmdBuff, srcImage, srcImageLayout, dstImage, dstImageLayout, true, commandUse);
- _blitKey.srcMTLPixelFormat = _srcMTLPixFmt;
+ _blitKey.srcMTLPixelFormat = _srcImage->getMTLPixelFormat();
_blitKey.srcMTLTextureType = _srcImage->getMTLTextureType();
- _blitKey.dstMTLPixelFormat = _dstMTLPixFmt;
+ _blitKey.dstMTLPixelFormat = _dstImage->getMTLPixelFormat();
_blitKey.srcFilter = mvkMTLSamplerMinMagFilterFromVkFilter(filter);
_blitKey.dstSampleCount = _dstSampleCount;
@@ -265,9 +266,10 @@
}
// Validate
+ MTLPixelFormat srcMTLPixFmt = _srcImage->getMTLPixelFormat();
if ( !_mvkImageBlitRenders.empty() &&
- (pixFmts->mtlPixelFormatIsDepthFormat(_srcMTLPixFmt) ||
- pixFmts->mtlPixelFormatIsStencilFormat(_srcMTLPixFmt)) ) {
+ (pixFmts->mtlPixelFormatIsDepthFormat(srcMTLPixFmt) ||
+ pixFmts->mtlPixelFormatIsStencilFormat(srcMTLPixFmt)) ) {
_mvkImageBlitRenders.clear();
return reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCmdBlitImage(): Scaling or inverting depth/stencil images is not supported.");
@@ -1118,13 +1120,9 @@
bool isDepthStencilClear) {
_image = (MVKImage*)image;
_imgLayout = imageLayout;
+ _clearValue = clearValue;
_isDepthStencilClear = isDepthStencilClear;
- MVKPixelFormats* pixFmts = cmdBuff->getPixelFormats();
- _mtlColorClearValue = pixFmts->getMTLClearColorFromVkClearValue(clearValue, _image->getVkFormat());
- _mtlDepthClearValue = pixFmts->getMTLClearDepthFromVkClearValue(clearValue);
- _mtlStencilClearValue = pixFmts->getMTLClearStencilFromVkClearValue(clearValue);
-
// Add subresource ranges
_subresourceRanges.clear(); // Clear for reuse
_subresourceRanges.reserve(rangeCount);
@@ -1136,10 +1134,10 @@
if (_image->getImageType() == VK_IMAGE_TYPE_1D) {
return reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCmdClearImage(): Native 1D images cannot be cleared on this device. Consider enabling MVK_CONFIG_TEXTURE_1D_AS_2D.");
}
- MVKMTLFmtCaps mtlFmtCaps = pixFmts->getMTLPixelFormatCapabilities(_image->getMTLPixelFormat());
+ MVKMTLFmtCaps mtlFmtCaps = cmdBuff->getPixelFormats()->getMTLPixelFormatCapabilities(_image->getMTLPixelFormat());
if ((_isDepthStencilClear && !mvkAreAllFlagsEnabled(mtlFmtCaps, kMVKMTLFmtCapsDSAtt)) ||
( !_isDepthStencilClear && !mvkAreAllFlagsEnabled(mtlFmtCaps, kMVKMTLFmtCapsColorAtt))) {
- return reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCmdClearImage(): Format %s cannot be cleared on this device.", pixFmts->getVkFormatName(_image->getVkFormat()));
+ return reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCmdClearImage(): Format %s cannot be cleared on this device.", cmdBuff->getPixelFormats()->getVkFormatName(_image->getVkFormat()));
}
return VK_SUCCESS;
@@ -1155,6 +1153,7 @@
cmdEncoder->endCurrentMetalEncoding();
+ MVKPixelFormats* pixFmts = cmdEncoder->getPixelFormats();
for (auto& srRange : _subresourceRanges) {
MTLRenderPassDescriptor* mtlRPDesc = [MTLRenderPassDescriptor renderPassDescriptor];
@@ -1171,7 +1170,7 @@
mtlRPCADesc.texture = imgMTLTex;
mtlRPCADesc.loadAction = MTLLoadActionClear;
mtlRPCADesc.storeAction = MTLStoreActionStore;
- mtlRPCADesc.clearColor = _mtlColorClearValue;
+ mtlRPCADesc.clearColor = pixFmts->getMTLClearColorFromVkClearValue(_clearValue, _image->getVkFormat());
}
if (isClearingDepth) {
@@ -1179,7 +1178,7 @@
mtlRPDADesc.texture = imgMTLTex;
mtlRPDADesc.loadAction = MTLLoadActionClear;
mtlRPDADesc.storeAction = MTLStoreActionStore;
- mtlRPDADesc.clearDepth = _mtlDepthClearValue;
+ mtlRPDADesc.clearDepth = pixFmts->getMTLClearDepthFromVkClearValue(_clearValue);
}
if (isClearingStencil) {
@@ -1187,7 +1186,7 @@
mtlRPSADesc.texture = imgMTLTex;
mtlRPSADesc.loadAction = MTLLoadActionClear;
mtlRPSADesc.storeAction = MTLStoreActionStore;
- mtlRPSADesc.clearStencil = _mtlStencilClearValue;
+ mtlRPSADesc.clearStencil = pixFmts->getMTLClearStencilFromVkClearValue(_clearValue);
}
// Extract the mipmap levels that are to be updated
diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h
index 90ecccf..8b12e05 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h
+++ b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h
@@ -295,7 +295,7 @@
bool supportsDynamicState(VkDynamicState state);
/** Clips the scissor to ensure it fits inside the render area. */
- MTLScissorRect clipToRenderArea(MTLScissorRect mtlScissor);
+ VkRect2D clipToRenderArea(VkRect2D scissor);
/** Called by each graphics draw command to establish any outstanding state just prior to performing the draw. */
void finalizeDrawState(MVKGraphicsStage stage);
diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm
index ec6dbae..27af9e8 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm
+++ b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm
@@ -373,19 +373,19 @@
return !gpl || gpl->supportsDynamicState(state);
}
-MTLScissorRect MVKCommandEncoder::clipToRenderArea(MTLScissorRect mtlScissor) {
+VkRect2D MVKCommandEncoder::clipToRenderArea(VkRect2D scissor) {
- NSUInteger raLeft = _renderArea.offset.x;
- NSUInteger raRight = raLeft + _renderArea.extent.width;
- NSUInteger raBottom = _renderArea.offset.y;
- NSUInteger raTop = raBottom + _renderArea.extent.height;
+ int32_t raLeft = _renderArea.offset.x;
+ int32_t raRight = raLeft + _renderArea.extent.width;
+ int32_t raBottom = _renderArea.offset.y;
+ int32_t raTop = raBottom + _renderArea.extent.height;
- mtlScissor.x = mvkClamp(mtlScissor.x, raLeft, max(raRight - 1, raLeft));
- mtlScissor.y = mvkClamp(mtlScissor.y, raBottom, max(raTop - 1, raBottom));
- mtlScissor.width = min(mtlScissor.width, raRight - mtlScissor.x);
- mtlScissor.height = min(mtlScissor.height, raTop - mtlScissor.y);
+ scissor.offset.x = mvkClamp(scissor.offset.x, raLeft, max(raRight - 1, raLeft));
+ scissor.offset.y = mvkClamp(scissor.offset.y, raBottom, max(raTop - 1, raBottom));
+ scissor.extent.width = min<int32_t>(scissor.extent.width, raRight - scissor.offset.x);
+ scissor.extent.height = min<int32_t>(scissor.extent.height, raTop - scissor.offset.y);
- return mtlScissor;
+ return scissor;
}
void MVKCommandEncoder::finalizeDrawState(MVKGraphicsStage stage) {
diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h
index eec378c..0464e7f 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h
+++ b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h
@@ -140,7 +140,7 @@
* 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 MVKVector<MTLViewport> &mtlViewports,
+ void setViewports(const MVKVector<VkViewport> &viewports,
uint32_t firstViewport,
bool isSettingDynamically);
@@ -152,7 +152,7 @@
void encodeImpl(uint32_t stage) override;
void resetImpl() override;
- MVKVectorInline<MTLViewport, kMVKCachedViewportScissorCount> _mtlViewports, _mtlDynamicViewports;
+ MVKVectorInline<VkViewport, kMVKCachedViewportScissorCount> _viewports, _dynamicViewports;
};
@@ -169,7 +169,7 @@
* 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 MVKVector<MTLScissorRect> &mtlScissors,
+ void setScissors(const MVKVector<VkRect2D> &scissors,
uint32_t firstScissor,
bool isSettingDynamically);
@@ -181,7 +181,7 @@
void encodeImpl(uint32_t stage) override;
void resetImpl() override;
- MVKVectorInline<MTLScissorRect, kMVKCachedViewportScissorCount> _mtlScissors, _mtlDynamicScissors;
+ MVKVectorInline<VkRect2D, kMVKCachedViewportScissorCount> _scissors, _dynamicScissors;
};
diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm
index 03c812b..2940c9a 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm
+++ b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm
@@ -58,98 +58,106 @@
#pragma mark -
#pragma mark MVKViewportCommandEncoderState
-void MVKViewportCommandEncoderState::setViewports(const MVKVector<MTLViewport> &mtlViewports,
+void MVKViewportCommandEncoderState::setViewports(const MVKVector<VkViewport> &viewports,
uint32_t firstViewport,
bool isSettingDynamically) {
+ size_t vpCnt = viewports.size();
uint32_t maxViewports = _cmdEncoder->getDevice()->_pProperties->limits.maxViewports;
- if ((firstViewport + mtlViewports.size() > maxViewports) ||
+ if ((firstViewport + vpCnt > maxViewports) ||
(firstViewport >= maxViewports) ||
- (isSettingDynamically && mtlViewports.size() == 0))
+ (isSettingDynamically && vpCnt == 0))
return;
- auto& usingMTLViewports = isSettingDynamically ? _mtlDynamicViewports : _mtlViewports;
+ auto& usingViewports = isSettingDynamically ? _dynamicViewports : _viewports;
- if (firstViewport + mtlViewports.size() > usingMTLViewports.size()) {
- usingMTLViewports.resize(firstViewport + mtlViewports.size());
+ if (firstViewport + vpCnt > usingViewports.size()) {
+ usingViewports.resize(firstViewport + vpCnt);
}
bool mustSetDynamically = _cmdEncoder->supportsDynamicState(VK_DYNAMIC_STATE_VIEWPORT);
-
- if (isSettingDynamically ||
- (!mustSetDynamically && mtlViewports.size() > 0))
- std::copy(mtlViewports.begin(), mtlViewports.end(), usingMTLViewports.begin() + firstViewport);
- else
- usingMTLViewports.clear();
+ if (isSettingDynamically || (!mustSetDynamically && vpCnt > 0)) {
+ std::copy(viewports.begin(), viewports.end(), usingViewports.begin() + firstViewport);
+ } else {
+ usingViewports.clear();
+ }
markDirty();
}
void MVKViewportCommandEncoderState::encodeImpl(uint32_t stage) {
if (stage != kMVKGraphicsStageRasterization) { return; }
- auto& usingMTLViewports = _mtlViewports.size() > 0 ? _mtlViewports : _mtlDynamicViewports;
- if (usingMTLViewports.empty()) { return; }
+ auto& usingViewports = _viewports.size() > 0 ? _viewports : _dynamicViewports;
+ if (usingViewports.empty()) { return; }
+
if (_cmdEncoder->_pDeviceFeatures->multiViewport) {
- [_cmdEncoder->_mtlRenderEncoder setViewports: &usingMTLViewports[0] count: usingMTLViewports.size()];
+ size_t vpCnt = usingViewports.size();
+ MTLViewport mtlViewports[vpCnt];
+ for (uint32_t vpIdx = 0; vpIdx < vpCnt; vpIdx++) {
+ mtlViewports[vpIdx] = mvkMTLViewportFromVkViewport(usingViewports[vpIdx]);
+ }
+ [_cmdEncoder->_mtlRenderEncoder setViewports: mtlViewports count: vpCnt];
} else {
- [_cmdEncoder->_mtlRenderEncoder setViewport: usingMTLViewports[0]];
+ [_cmdEncoder->_mtlRenderEncoder setViewport: mvkMTLViewportFromVkViewport(usingViewports[0])];
}
}
void MVKViewportCommandEncoderState::resetImpl() {
- _mtlViewports.clear();
- _mtlDynamicViewports.clear();
+ _viewports.clear();
+ _dynamicViewports.clear();
}
#pragma mark -
#pragma mark MVKScissorCommandEncoderState
-void MVKScissorCommandEncoderState::setScissors(const MVKVector<MTLScissorRect> &mtlScissors,
+void MVKScissorCommandEncoderState::setScissors(const MVKVector<VkRect2D> &scissors,
uint32_t firstScissor,
bool isSettingDynamically) {
+ size_t sCnt = scissors.size();
uint32_t maxScissors = _cmdEncoder->getDevice()->_pProperties->limits.maxViewports;
- if ((firstScissor + mtlScissors.size() > maxScissors) ||
+ if ((firstScissor + sCnt > maxScissors) ||
(firstScissor >= maxScissors) ||
- (isSettingDynamically && mtlScissors.size() == 0))
+ (isSettingDynamically && sCnt == 0))
return;
- auto& usingMTLScissors = isSettingDynamically ? _mtlDynamicScissors : _mtlScissors;
+ auto& usingScissors = isSettingDynamically ? _dynamicScissors : _scissors;
- if (firstScissor + mtlScissors.size() > usingMTLScissors.size()) {
- usingMTLScissors.resize(firstScissor + mtlScissors.size());
+ if (firstScissor + sCnt > usingScissors.size()) {
+ usingScissors.resize(firstScissor + sCnt);
}
bool mustSetDynamically = _cmdEncoder->supportsDynamicState(VK_DYNAMIC_STATE_SCISSOR);
-
- if (isSettingDynamically ||
- (!mustSetDynamically && mtlScissors.size() > 0))
- std::copy(mtlScissors.begin(), mtlScissors.end(), usingMTLScissors.begin() + firstScissor);
- else
- usingMTLScissors.clear();
+ if (isSettingDynamically || (!mustSetDynamically && sCnt > 0)) {
+ std::copy(scissors.begin(), scissors.end(), usingScissors.begin() + firstScissor);
+ } else {
+ usingScissors.clear();
+ }
markDirty();
}
void MVKScissorCommandEncoderState::encodeImpl(uint32_t stage) {
if (stage != kMVKGraphicsStageRasterization) { return; }
- auto& usingMTLScissors = _mtlScissors.size() > 0 ? _mtlScissors : _mtlDynamicScissors;
- if (usingMTLScissors.empty()) { return; }
- auto clippedScissors(usingMTLScissors);
- std::for_each(clippedScissors.begin(), clippedScissors.end(), [this](MTLScissorRect& scissor) {
- scissor = _cmdEncoder->clipToRenderArea(scissor);
- });
+ auto& usingScissors = _scissors.size() > 0 ? _scissors : _dynamicScissors;
+ if (usingScissors.empty()) { return; }
+
if (_cmdEncoder->_pDeviceFeatures->multiViewport) {
- [_cmdEncoder->_mtlRenderEncoder setScissorRects: &clippedScissors[0] count: clippedScissors.size()];
+ size_t sCnt = usingScissors.size();
+ MTLScissorRect mtlScissors[sCnt];
+ for (uint32_t sIdx = 0; sIdx < sCnt; sIdx++) {
+ mtlScissors[sIdx] = mvkMTLScissorRectFromVkRect2D(_cmdEncoder->clipToRenderArea(usingScissors[sIdx]));
+ }
+ [_cmdEncoder->_mtlRenderEncoder setScissorRects: mtlScissors count: sCnt];
} else {
- [_cmdEncoder->_mtlRenderEncoder setScissorRect: clippedScissors[0]];
+ [_cmdEncoder->_mtlRenderEncoder setScissorRect: mvkMTLScissorRectFromVkRect2D(_cmdEncoder->clipToRenderArea(usingScissors[0]))];
}
}
void MVKScissorCommandEncoderState::resetImpl() {
- _mtlScissors.clear();
- _mtlDynamicScissors.clear();
+ _scissors.clear();
+ _dynamicScissors.clear();
}
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h
index 8bc35c8..431f02f 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h
@@ -269,8 +269,8 @@
VkPipelineRasterizationStateCreateInfo _rasterInfo;
VkPipelineDepthStencilStateCreateInfo _depthStencilInfo;
- MVKVectorInline<MTLViewport, kMVKCachedViewportScissorCount> _mtlViewports;
- MVKVectorInline<MTLScissorRect, kMVKCachedViewportScissorCount> _mtlScissors;
+ MVKVectorInline<VkViewport, kMVKCachedViewportScissorCount> _viewports;
+ MVKVectorInline<VkRect2D, kMVKCachedViewportScissorCount> _scissors;
MTLComputePipelineDescriptor* _mtlTessControlStageDesc = nil;
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm
index 6fe1bb2..ab6f1e8 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm
@@ -254,8 +254,8 @@
cmdEncoder->_blendColorState.setBlendColor(_blendConstants[0], _blendConstants[1],
_blendConstants[2], _blendConstants[3], false);
cmdEncoder->_depthBiasState.setDepthBias(_rasterInfo);
- cmdEncoder->_viewportState.setViewports(_mtlViewports, 0, false);
- cmdEncoder->_scissorState.setScissors(_mtlScissors, 0, false);
+ cmdEncoder->_viewportState.setViewports(_viewports, 0, false);
+ cmdEncoder->_scissorState.setScissors(_scissors, 0, false);
cmdEncoder->_mtlPrimitiveType = _mtlPrimitiveType;
[mtlCmdEnc setCullMode: _mtlCullMode];
@@ -376,24 +376,24 @@
_hasDepthStencilInfo = mvkSetOrClear(&_depthStencilInfo, pCreateInfo->pDepthStencilState);
// Viewports and scissors
- if (pCreateInfo->pViewportState) {
- _mtlViewports.reserve(pCreateInfo->pViewportState->viewportCount);
- for (uint32_t i = 0; i < pCreateInfo->pViewportState->viewportCount; i++) {
+ auto pVPState = pCreateInfo->pViewportState;
+ if (pVPState) {
+ uint32_t vpCnt = pVPState->viewportCount;
+ _viewports.reserve(vpCnt);
+ for (uint32_t vpIdx = 0; vpIdx < vpCnt; vpIdx++) {
// If viewport is dyanamic, we still add a dummy so that the count will be tracked.
- MTLViewport mtlVP;
- if ( !_dynamicStateEnabled[VK_DYNAMIC_STATE_VIEWPORT] ) {
- mtlVP = mvkMTLViewportFromVkViewport(pCreateInfo->pViewportState->pViewports[i]);
- }
- _mtlViewports.push_back(mtlVP);
+ VkViewport vp;
+ if ( !_dynamicStateEnabled[VK_DYNAMIC_STATE_VIEWPORT] ) { vp = pVPState->pViewports[vpIdx]; }
+ _viewports.push_back(vp);
}
- _mtlScissors.reserve(pCreateInfo->pViewportState->scissorCount);
- for (uint32_t i = 0; i < pCreateInfo->pViewportState->scissorCount; i++) {
+
+ uint32_t sCnt = pVPState->scissorCount;
+ _scissors.reserve(sCnt);
+ for (uint32_t sIdx = 0; sIdx < sCnt; sIdx++) {
// If scissor is dyanamic, we still add a dummy so that the count will be tracked.
- MTLScissorRect mtlSc;
- if ( !_dynamicStateEnabled[VK_DYNAMIC_STATE_SCISSOR] ) {
- mtlSc = mvkMTLScissorRectFromVkRect2D(pCreateInfo->pViewportState->pScissors[i]);
- }
- _mtlScissors.push_back(mtlSc);
+ VkRect2D sc;
+ if ( !_dynamicStateEnabled[VK_DYNAMIC_STATE_SCISSOR] ) { sc = pVPState->pScissors[sIdx]; }
+ _scissors.push_back(sc);
}
}
}