Skip to content

Commit

Permalink
Merge pull request #2221 from billhollings/refactor-device-public-con…
Browse files Browse the repository at this point in the history
…tent

Refactor public MVKDevice content into MVKDeviceTrackingMixin functions.
  • Loading branch information
billhollings authored May 2, 2024
2 parents 0d62a42 + e1baea9 commit e361c2a
Show file tree
Hide file tree
Showing 29 changed files with 459 additions and 459 deletions.
92 changes: 50 additions & 42 deletions MoltenVK/MoltenVK/Commands/MVKCmdDraw.mm

Large diffs are not rendered by default.

10 changes: 6 additions & 4 deletions MoltenVK/MoltenVK/Commands/MVKCmdPipeline.mm
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,13 @@

template <size_t N>
void MVKCmdPipelineBarrier<N>::encode(MVKCommandEncoder* cmdEncoder) {

auto& mtlFeats = cmdEncoder->getMetalFeatures();

#if MVK_MACOS
// Calls below invoke MTLBlitCommandEncoder so must apply this first.
// Check if pipeline barriers are available and we are in a renderpass.
if (cmdEncoder->getDevice()->_pMetalFeatures->memoryBarriers && cmdEncoder->_mtlRenderEncoder) {
if (mtlFeats.memoryBarriers && cmdEncoder->_mtlRenderEncoder) {
for (auto& b : _barriers) {
MTLRenderStages srcStages = mvkMTLRenderStagesFromVkPipelineStageFlags(b.srcStageMask, false);
MTLRenderStages dstStages = mvkMTLRenderStagesFromVkPipelineStageFlags(b.dstStageMask, true);
Expand Down Expand Up @@ -161,7 +163,7 @@
// into separate Metal renderpasses. Since this is a potentially expensive operation,
// verify that at least one attachment is being used both as an input and render attachment
// by checking for a VK_IMAGE_LAYOUT_GENERAL layout.
if (cmdEncoder->_mtlRenderEncoder && cmdEncoder->getDevice()->_pMetalFeatures->tileBasedDeferredRendering) {
if (cmdEncoder->_mtlRenderEncoder && mtlFeats.tileBasedDeferredRendering) {
bool needsRenderpassRestart = false;
for (auto& b : _barriers) {
if (b.type == MVKPipelineBarrier::Image && b.newLayout == VK_IMAGE_LAYOUT_GENERAL) {
Expand Down Expand Up @@ -388,7 +390,7 @@
_pipelineLayout->retain();

// Add the descriptor writes
MVKDevice* mvkDvc = cmdBuff->getDevice();
auto& enabledExtns = cmdBuff->getEnabledExtensions();
clearDescriptorWrites(); // Clear for reuse
_descriptorWrites.reserve(descriptorWriteCount);
for (uint32_t dwIdx = 0; dwIdx < descriptorWriteCount; dwIdx++) {
Expand All @@ -410,7 +412,7 @@
std::copy_n(descWrite.pTexelBufferView, descWrite.descriptorCount, pNewTexelBufferView);
descWrite.pTexelBufferView = pNewTexelBufferView;
}
if (mvkDvc->_enabledExtensions.vk_EXT_inline_uniform_block.enabled) {
if (enabledExtns.vk_EXT_inline_uniform_block.enabled) {
const VkWriteDescriptorSetInlineUniformBlockEXT* pInlineUniformBlock = nullptr;
for (const auto* next = (VkBaseInStructure*)descWrite.pNext; next; next = next->pNext) {
switch (next->sType) {
Expand Down
32 changes: 17 additions & 15 deletions MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ static inline MTLSize mvkClampMTLSize(MTLSize size, MTLOrigin origin, MTLSize ma

_filter = filter;

bool isDestUnwritableLinear = MVK_MACOS && !cmdBuff->getDevice()->_pMetalFeatures->renderLinearTextures && _dstImage->getIsLinear();
bool isDestUnwritableLinear = MVK_MACOS && !cmdBuff->getMetalFeatures().renderLinearTextures && _dstImage->getIsLinear();

_vkImageBlits.clear(); // Clear for reuse
for (uint32_t rIdx = 0; rIdx < regionCount; rIdx++) {
Expand Down Expand Up @@ -350,7 +350,7 @@ static inline MTLSize mvkClampMTLSize(MTLSize size, MTLOrigin origin, MTLSize ma

_filter = pBlitImageInfo->filter;

bool isDestUnwritableLinear = MVK_MACOS && !cmdBuff->getDevice()->_pMetalFeatures->renderLinearTextures && _dstImage->getIsLinear();
bool isDestUnwritableLinear = MVK_MACOS && !cmdBuff->getMetalFeatures().renderLinearTextures && _dstImage->getIsLinear();

_vkImageBlits.clear(); // Clear for reuse
_vkImageBlits.reserve(pBlitImageInfo->regionCount);
Expand Down Expand Up @@ -457,6 +457,7 @@ static inline MTLSize mvkClampMTLSize(MTLSize size, MTLOrigin origin, MTLSize ma
template <size_t N>
void MVKCmdBlitImage<N>::encode(MVKCommandEncoder* cmdEncoder, MVKCommandUse commandUse) {

auto& mtlFeats = cmdEncoder->getMetalFeatures();
size_t vkIBCnt = _vkImageBlits.size();
VkImageCopy vkImageCopies[vkIBCnt];
MVKImageBlitRender mvkBlitRenders[vkIBCnt];
Expand Down Expand Up @@ -507,7 +508,7 @@ static inline MTLSize mvkClampMTLSize(MTLSize size, MTLOrigin origin, MTLSize ma
id<MTLTexture> srcMTLTex = _srcImage->getMTLTexture(srcPlaneIndex);
id<MTLTexture> dstMTLTex = _dstImage->getMTLTexture(dstPlaneIndex);
if (blitCnt && srcMTLTex && dstMTLTex) {
if (cmdEncoder->getDevice()->_pMetalFeatures->nativeTextureSwizzle &&
if (mtlFeats.nativeTextureSwizzle &&
_srcImage->needsSwizzle()) {
// Use a view that has a swizzle on it.
srcMTLTex = [srcMTLTex newTextureViewWithPixelFormat:srcMTLTex.pixelFormat
Expand Down Expand Up @@ -564,7 +565,7 @@ static inline MTLSize mvkClampMTLSize(MTLSize size, MTLOrigin origin, MTLSize ma
blitKey.srcFilter = mvkMTLSamplerMinMagFilterFromVkFilter(_filter);
blitKey.srcAspect = mvkIBR.region.srcSubresource.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
blitKey.dstSampleCount = mvkSampleCountFromVkSampleCountFlagBits(_dstImage->getSampleCount());
if (!cmdEncoder->getDevice()->_pMetalFeatures->nativeTextureSwizzle &&
if (!mtlFeats.nativeTextureSwizzle &&
_srcImage->needsSwizzle()) {
VkComponentMapping vkMapping = _srcImage->getPixelFormats()->getVkComponentMapping(_srcImage->getVkFormat());
blitKey.srcSwizzleR = vkMapping.r;
Expand All @@ -581,7 +582,7 @@ static inline MTLSize mvkClampMTLSize(MTLSize size, MTLOrigin origin, MTLSize ma
mtlDepthAttDesc.level = mvkIBR.region.dstSubresource.mipLevel;
mtlStencilAttDesc.level = mvkIBR.region.dstSubresource.mipLevel;

bool isLayeredBlit = blitKey.dstSampleCount > 1 ? cmdEncoder->getDevice()->_pMetalFeatures->multisampleLayeredRendering : cmdEncoder->getDevice()->_pMetalFeatures->layeredRendering;
bool isLayeredBlit = blitKey.dstSampleCount > 1 ? mtlFeats.multisampleLayeredRendering : mtlFeats.layeredRendering;

uint32_t layCnt = mvkIBR.region.srcSubresource.layerCount;
if (_dstImage->getMTLTextureType() == MTLTextureType3D) {
Expand Down Expand Up @@ -761,13 +762,14 @@ static inline MTLSize mvkClampMTLSize(MTLSize size, MTLOrigin origin, MTLSize ma
template <size_t N>
void MVKCmdResolveImage<N>::encode(MVKCommandEncoder* cmdEncoder) {

auto& mtlFeats = cmdEncoder->getMetalFeatures();
size_t vkIRCnt = _vkImageResolves.size();
VkImageBlit expansionRegions[vkIRCnt];
VkImageCopy copyRegions[vkIRCnt];

// If we can do layered rendering to a multisample texture, I can resolve all the layers at once.
uint32_t layerCnt = 0;
if (cmdEncoder->getDevice()->_pMetalFeatures->multisampleLayeredRendering) {
if (mtlFeats.multisampleLayeredRendering) {
layerCnt = (uint32_t)_vkImageResolves.size();
} else {
for (VkImageResolve2& vkIR : _vkImageResolves) { layerCnt += vkIR.dstSubresource.layerCount; }
Expand Down Expand Up @@ -820,7 +822,7 @@ static inline MTLSize mvkClampMTLSize(MTLSize size, MTLOrigin origin, MTLSize ma
// direct resolve, but that of the DESTINATION if we need a temporary transfer image.
mtlResolveSlices[sliceCnt].dstSubresource = vkIR.dstSubresource;
mtlResolveSlices[sliceCnt].srcSubresource = needXfrImage ? vkIR.dstSubresource : vkIR.srcSubresource;
if (cmdEncoder->getDevice()->_pMetalFeatures->multisampleLayeredRendering) {
if (mtlFeats.multisampleLayeredRendering) {
sliceCnt++;
} else {
uint32_t layCnt = vkIR.dstSubresource.layerCount;
Expand Down Expand Up @@ -961,7 +963,7 @@ static inline MTLSize mvkClampMTLSize(MTLSize size, MTLOrigin origin, MTLSize ma
id<MTLBuffer> dstMTLBuff = _dstBuffer->getMTLBuffer();
NSUInteger dstMTLBuffOffset = _dstBuffer->getMTLBufferOffset();

VkDeviceSize buffAlign = cmdEncoder->getDevice()->_pMetalFeatures->mtlCopyBufferAlignment;
VkDeviceSize buffAlign = cmdEncoder->getMetalFeatures().mtlCopyBufferAlignment;

for (const auto& cpyRgn : _bufferCopyRegions) {
const bool useComputeCopy = buffAlign > 1 && (cpyRgn.srcOffset % buffAlign != 0 ||
Expand Down Expand Up @@ -1149,7 +1151,7 @@ static inline MTLSize mvkClampMTLSize(MTLSize size, MTLOrigin origin, MTLSize ma
// If we're copying to mip level 0, we can skip the copy and just decode
// directly into the image. Otherwise, we need to use an intermediate buffer.
if (_toImage && _image->getIsCompressed() && mtlTexture.textureType == MTLTextureType3D &&
!cmdEncoder->getDevice()->_pMetalFeatures->native3DCompressedTextures) {
!cmdEncoder->getMetalFeatures().native3DCompressedTextures) {

MVKCmdCopyBufferToImageInfo info;
info.srcRowStride = bytesPerRow & 0xffffffff;
Expand Down Expand Up @@ -1496,7 +1498,7 @@ static inline MTLSize mvkClampMTLSize(MTLSize size, MTLOrigin origin, MTLSize ma
// Apple GPUs do not support rendering/writing to an attachment and then reading from
// that attachment within a single Metal renderpass. So, if any of the attachments just
// cleared is an input attachment, we need to restart into separate Metal renderpasses.
if (cmdEncoder->getDevice()->_pMetalFeatures->tileBasedDeferredRendering) {
if (cmdEncoder->getMetalFeatures().tileBasedDeferredRendering) {
bool needsRenderpassRestart = false;
for (uint32_t caIdx = 0; caIdx < caCnt; caIdx++) {
if (_rpsKey.isAttachmentEnabled(caIdx) && subpass->isColorAttachmentAlsoInputAttachment(caIdx)) {
Expand Down Expand Up @@ -1562,7 +1564,7 @@ static inline MTLSize mvkClampMTLSize(MTLSize size, MTLOrigin origin, MTLSize ma

// Validate
MVKMTLFmtCaps mtlFmtCaps = cmdBuff->getPixelFormats()->getCapabilities(_image->getMTLPixelFormat(planeIndex));
bool isDestUnwritableLinear = MVK_MACOS && !cmdBuff->getDevice()->_pMetalFeatures->renderLinearTextures && _image->getIsLinear();
bool isDestUnwritableLinear = MVK_MACOS && !cmdBuff->getMetalFeatures().renderLinearTextures && _image->getIsLinear();
uint32_t reqCap = isDS ? kMVKMTLFmtCapsDSAtt : (isDestUnwritableLinear ? kMVKMTLFmtCapsWrite : kMVKMTLFmtCapsColorAtt);
if (!mvkAreAllFlagsEnabled(mtlFmtCaps, reqCap)) {
return cmdBuff->reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCmdClear%sImage(): Format %s cannot be cleared on this device.", (isDS ? "DepthStencil" : "Color"), cmdBuff->getPixelFormats()->getName(_image->getVkFormat()));
Expand All @@ -1588,14 +1590,15 @@ static inline MTLSize mvkClampMTLSize(MTLSize size, MTLOrigin origin, MTLSize ma

cmdEncoder->endCurrentMetalEncoding();

auto& mtlFeats = cmdEncoder->getMetalFeatures();
MVKPixelFormats* pixFmts = cmdEncoder->getPixelFormats();
for (auto& srRange : _subresourceRanges) {
uint8_t planeIndex = MVKImage::getPlaneFromVkImageAspectFlags(srRange.aspectMask);
id<MTLTexture> imgMTLTex = _image->getMTLTexture(planeIndex);
if ( !imgMTLTex ) { continue; }

#if MVK_MACOS
if ( _image->getIsLinear() && !cmdEncoder->getDevice()->_pMetalFeatures->renderLinearTextures ) {
if (_image->getIsLinear() && !mtlFeats.renderLinearTextures) {
// These images cannot be rendered. Instead, use a compute shader.
// Luckily for us, linear images only have one mip and one array layer under Metal.
assert( !isDS );
Expand All @@ -1608,7 +1611,7 @@ static inline MTLSize mvkClampMTLSize(MTLSize size, MTLOrigin origin, MTLSize ma
cmdEncoder->setComputeBytes(mtlComputeEnc, &_clearValue, sizeof(_clearValue), 0);
MTLSize gridSize = mvkMTLSizeFromVkExtent3D(_image->getExtent3D());
MTLSize tgSize = MTLSizeMake(mtlClearState.threadExecutionWidth, 1, 1);
if (cmdEncoder->getDevice()->_pMetalFeatures->nonUniformThreadgroups) {
if (mtlFeats.nonUniformThreadgroups) {
[mtlComputeEnc dispatchThreads: gridSize threadsPerThreadgroup: tgSize];
} else {
MTLSize tgCount = MTLSizeMake(gridSize.width / tgSize.width, gridSize.height, gridSize.depth);
Expand Down Expand Up @@ -1681,8 +1684,7 @@ static inline MTLSize mvkClampMTLSize(MTLSize size, MTLOrigin origin, MTLSize ma
}

// If we can do layered rendering, I can clear all the layers at once.
if (cmdEncoder->getDevice()->_pMetalFeatures->layeredRendering &&
(_image->getSampleCount() == VK_SAMPLE_COUNT_1_BIT || cmdEncoder->getDevice()->_pMetalFeatures->multisampleLayeredRendering)) {
if (mtlFeats.layeredRendering && (mtlFeats.multisampleLayeredRendering || _image->getSampleCount() == VK_SAMPLE_COUNT_1_BIT)) {
if (is3D) {
mtlRPCADesc.depthPlane = layerStart;
mtlRPDADesc.depthPlane = layerStart;
Expand Down
12 changes: 0 additions & 12 deletions MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -421,18 +421,6 @@ class MVKCommandEncoder : public MVKBaseDeviceObject {
/** Context for tracking information across multiple encodings. */
MVKCommandEncodingContext* _pEncodingContext;

/** A reference to the Metal features supported by the device. */
const MVKPhysicalDeviceMetalFeatures* _pDeviceMetalFeatures;

/** A reference to the Vulkan features supported by the device. */
const VkPhysicalDeviceFeatures* _pDeviceFeatures;

/** Pointer to the properties of the device. */
const VkPhysicalDeviceProperties* _pDeviceProperties;

/** Pointer to the memory properties of the device. */
const VkPhysicalDeviceMemoryProperties* _pDeviceMemoryProperties;

/** The command buffer whose commands are being encoded. */
MVKCommandBuffer* _cmdBuffer;

Expand Down
33 changes: 15 additions & 18 deletions MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@
// Track whether a stage-based timestamp command has been added, so we know
// to update the timestamp command fence when ending a Metal command encoder.
void MVKCommandBuffer::recordTimestampCommand() {
_hasStageCounterTimestampCommand = mvkIsAnyFlagEnabled(_device->_pMetalFeatures->counterSamplingPoints, MVK_COUNTER_SAMPLING_AT_PIPELINE_STAGE);
_hasStageCounterTimestampCommand = mvkIsAnyFlagEnabled(getMetalFeatures().counterSamplingPoints, MVK_COUNTER_SAMPLING_AT_PIPELINE_STAGE);
}


Expand All @@ -340,14 +340,13 @@
// because that would include app time between command submissions.
void MVKCommandEncoder::encode(id<MTLCommandBuffer> mtlCmdBuff,
MVKCommandEncodingContext* pEncodingContext) {
MVKDevice* mvkDev = getDevice();
uint64_t startTime = mvkDev->getPerformanceTimestamp();
uint64_t startTime = getPerformanceTimestamp();

beginEncoding(mtlCmdBuff, pEncodingContext);
encodeCommands(_cmdBuffer->_head);
endEncoding();

mvkDev->addPerformanceInterval(mvkDev->_performanceStatistics.queue.commandBufferEncoding, startTime);
addPerformanceInterval(getPerformanceStats().queue.commandBufferEncoding, startTime);
}

void MVKCommandEncoder::beginEncoding(id<MTLCommandBuffer> mtlCmdBuff, MVKCommandEncodingContext* pEncodingContext) {
Expand Down Expand Up @@ -494,9 +493,8 @@
_renderSubpassIndex = subpassIndex;
_multiviewPassIndex = 0;

_canUseLayeredRendering = (_device->_pMetalFeatures->layeredRendering &&
(_device->_pMetalFeatures->multisampleLayeredRendering ||
(getSubpass()->getSampleCount() == VK_SAMPLE_COUNT_1_BIT)));
auto& mtlFeats = getMetalFeatures();
_canUseLayeredRendering = mtlFeats.layeredRendering && (mtlFeats.multisampleLayeredRendering || getSubpass()->getSampleCount() == VK_SAMPLE_COUNT_1_BIT);

beginMetalRenderPass(cmdUse);
}
Expand Down Expand Up @@ -539,7 +537,7 @@
isRestart);
if (_cmdBuffer->_needsVisibilityResultMTLBuffer) {
if ( !_pEncodingContext->visibilityResultBuffer ) {
_pEncodingContext->visibilityResultBuffer = getTempMTLBuffer(_pDeviceMetalFeatures->maxQueryBufferSize, true, true);
_pEncodingContext->visibilityResultBuffer = getTempMTLBuffer(getMetalFeatures().maxQueryBufferSize, true, true);
}
mtlRPDesc.visibilityResultBuffer = _pEncodingContext->visibilityResultBuffer->_mtlBuffer;
}
Expand Down Expand Up @@ -577,7 +575,7 @@
// If programmable sample positions are supported, set them into the render pass descriptor.
// If no custom sample positions are established, size will be zero,
// and Metal will default to using default sample postions.
if (_pDeviceMetalFeatures->programmableSamplePositions) {
if (getMetalFeatures().programmableSamplePositions) {
auto sampPosns = _renderingState.getSamplePositions();
[mtlRPDesc setSamplePositions: sampPosns.data() count: sampPosns.size()];
}
Expand Down Expand Up @@ -892,7 +890,8 @@
NSUInteger length,
uint32_t mtlBuffIndex,
bool descOverride) {
if (_pDeviceMetalFeatures->dynamicMTLBufferSize && length <= _pDeviceMetalFeatures->dynamicMTLBufferSize) {
auto& mtlFeats = getMetalFeatures();
if (mtlFeats.dynamicMTLBufferSize && length <= mtlFeats.dynamicMTLBufferSize) {
[mtlEncoder setVertexBytes: bytes length: length atIndex: mtlBuffIndex];
} else {
const MVKMTLBufferAllocation* mtlBuffAlloc = copyToTempMTLBufferAllocation(bytes, length);
Expand All @@ -905,7 +904,7 @@
}

void MVKCommandEncoder::encodeVertexAttributeBuffer(MVKMTLBufferBinding& b, bool isDynamicStride) {
if (_device->_pMetalFeatures->dynamicVertexStride) {
if (getMetalFeatures().dynamicVertexStride) {
#if MVK_XCODE_15
NSUInteger mtlStride = isDynamicStride ? b.stride : MTLAttributeStrideStatic;
if (b.isInline) {
Expand Down Expand Up @@ -945,7 +944,8 @@
NSUInteger length,
uint32_t mtlBuffIndex,
bool descOverride) {
if (_pDeviceMetalFeatures->dynamicMTLBufferSize && length <= _pDeviceMetalFeatures->dynamicMTLBufferSize) {
auto& mtlFeats = getMetalFeatures();
if (mtlFeats.dynamicMTLBufferSize && length <= mtlFeats.dynamicMTLBufferSize) {
[mtlEncoder setFragmentBytes: bytes length: length atIndex: mtlBuffIndex];
} else {
const MVKMTLBufferAllocation* mtlBuffAlloc = copyToTempMTLBufferAllocation(bytes, length);
Expand All @@ -962,7 +962,8 @@
NSUInteger length,
uint32_t mtlBuffIndex,
bool descOverride) {
if (_pDeviceMetalFeatures->dynamicMTLBufferSize && length <= _pDeviceMetalFeatures->dynamicMTLBufferSize) {
auto& mtlFeats = getMetalFeatures();
if (mtlFeats.dynamicMTLBufferSize && length <= mtlFeats.dynamicMTLBufferSize) {
[mtlEncoder setBytes: bytes length: length atIndex: mtlBuffIndex];
} else {
const MVKMTLBufferAllocation* mtlBuffAlloc = copyToTempMTLBufferAllocation(bytes, length);
Expand Down Expand Up @@ -1035,7 +1036,7 @@
addActivatedQueries(pQueryPool, query, queryCount);

if (pQueryPool->hasMTLCounterBuffer()) {
MVKCounterSamplingFlags sampPts = _device->_pMetalFeatures->counterSamplingPoints;
MVKCounterSamplingFlags sampPts = getMetalFeatures().counterSamplingPoints;
for (uint32_t qOfst = 0; qOfst < queryCount; qOfst++) {
if (mvkIsAnyFlagEnabled(sampPts, MVK_COUNTER_SAMPLING_AT_PIPELINE_STAGE)) {
_timestampStageCounterQueries.push_back({ pQueryPool, query + qOfst });
Expand Down Expand Up @@ -1155,10 +1156,6 @@
_computePushConstants(this, VK_SHADER_STAGE_COMPUTE_BIT),
_prefillStyle(prefillStyle){

_pDeviceFeatures = &_device->_enabledFeatures;
_pDeviceMetalFeatures = _device->_pMetalFeatures;
_pDeviceProperties = _device->_pProperties;
_pDeviceMemoryProperties = _device->_pMemoryProperties;
_pActivatedQueries = nullptr;
_mtlCmdBuffer = nil;
_mtlRenderEncoder = nil;
Expand Down
Loading

0 comments on commit e361c2a

Please sign in to comment.