Skip to content

Commit

Permalink
Merge pull request #1878 from billhollings/dyn-rend-separate-depth-st…
Browse files Browse the repository at this point in the history
…encil

Support separate depth and stencil attachments during dynamic rendering
  • Loading branch information
billhollings authored Apr 28, 2023
2 parents 331cea9 + fd6b973 commit e50cb32
Show file tree
Hide file tree
Showing 20 changed files with 588 additions and 575 deletions.
1 change: 1 addition & 0 deletions Docs/Whats_New.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Released TBD
- Add support for extensions:
- `VK_KHR_map_memory2`
- Support BC compression on iOS/tvOS where available (iOS/tvOS 16.4 and above and supported by the GPU).
- Support separate depth and stencil attachments during dynamic rendering.
- Fix memory leak when waiting on timeline semaphores.
- Ensure shaders that use `PhysicalStorageBufferAddresses` encode the use of the associated `MTLBuffer`.
- Disable pipeline cache compression prior to macOS 10.15 and iOS/tvOS 13.0.
Expand Down
4 changes: 2 additions & 2 deletions MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ class MVKCmdSetViewport : public MVKCommand {

// Concrete template class implementations.
typedef MVKCmdSetViewport<1> MVKCmdSetViewport1;
typedef MVKCmdSetViewport<kMVKCachedViewportScissorCount> MVKCmdSetViewportMulti;
typedef MVKCmdSetViewport<kMVKMaxViewportScissorCount> MVKCmdSetViewportMulti;


#pragma mark -
Expand Down Expand Up @@ -292,7 +292,7 @@ class MVKCmdSetScissor : public MVKCommand {

// Concrete template class implementations.
typedef MVKCmdSetScissor<1> MVKCmdSetScissor1;
typedef MVKCmdSetScissor<kMVKCachedViewportScissorCount> MVKCmdSetScissorMulti;
typedef MVKCmdSetScissor<kMVKMaxViewportScissorCount> MVKCmdSetScissorMulti;


#pragma mark -
Expand Down
4 changes: 2 additions & 2 deletions MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.mm
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@
}

template class MVKCmdSetViewport<1>;
template class MVKCmdSetViewport<kMVKCachedViewportScissorCount>;
template class MVKCmdSetViewport<kMVKMaxViewportScissorCount>;


#pragma mark -
Expand All @@ -309,7 +309,7 @@
}

template class MVKCmdSetScissor<1>;
template class MVKCmdSetScissor<kMVKCachedViewportScissorCount>;
template class MVKCmdSetScissor<kMVKMaxViewportScissorCount>;


#pragma mark -
Expand Down
4 changes: 1 addition & 3 deletions MoltenVK/MoltenVK/Commands/MVKCmdTransfer.h
Original file line number Diff line number Diff line change
Expand Up @@ -284,8 +284,6 @@ class MVKCmdClearAttachments : public MVKCommand {
float _mtlDepthVal;
uint32_t _mtlStencilValue;
MVKCommandUse _commandUse;
bool _isClearingDepth;
bool _isClearingStencil;
};


Expand Down Expand Up @@ -326,7 +324,7 @@ class MVKCmdClearMultiAttachments : public MVKCmdClearAttachments<N> {
VkClearValue& getClearValue(uint32_t attIdx) override { return _vkClearValues[attIdx]; }
void setClearValue(uint32_t attIdx, const VkClearValue& clearValue) override { _vkClearValues[attIdx] = clearValue; }

VkClearValue _vkClearValues[kMVKCachedColorAttachmentCount];
VkClearValue _vkClearValues[kMVKMaxColorAttachmentCount];
};

typedef MVKCmdClearMultiAttachments<1> MVKCmdClearMultiAttachments1;
Expand Down
33 changes: 11 additions & 22 deletions MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1260,8 +1260,6 @@ static inline MTLSize mvkClampMTLSize(MTLSize size, MTLOrigin origin, MTLSize ma
_commandUse = cmdUse;
_mtlDepthVal = 0.0;
_mtlStencilValue = 0;
_isClearingDepth = false;
_isClearingStencil = false;
MVKPixelFormats* pixFmts = cmdBuff->getPixelFormats();

// For each attachment to be cleared, mark it so in the render pipeline state
Expand All @@ -1279,14 +1277,12 @@ static inline MTLSize mvkClampMTLSize(MTLSize size, MTLOrigin origin, MTLSize ma
}

if (mvkIsAnyFlagEnabled(clrAtt.aspectMask, VK_IMAGE_ASPECT_DEPTH_BIT)) {
_isClearingDepth = true;
_rpsKey.enableAttachment(kMVKClearAttachmentDepthStencilIndex);
_rpsKey.enableAttachment(kMVKClearAttachmentDepthIndex);
_mtlDepthVal = pixFmts->getMTLClearDepthValue(clrAtt.clearValue);
}

if (mvkIsAnyFlagEnabled(clrAtt.aspectMask, VK_IMAGE_ASPECT_STENCIL_BIT)) {
_isClearingStencil = true;
_rpsKey.enableAttachment(kMVKClearAttachmentDepthStencilIndex);
_rpsKey.enableAttachment(kMVKClearAttachmentStencilIndex);
_mtlStencilValue = pixFmts->getMTLClearStencilValue(clrAtt.clearValue);
}
}
Expand Down Expand Up @@ -1443,31 +1439,24 @@ static inline MTLSize mvkClampMTLSize(MTLSize size, MTLOrigin origin, MTLSize ma
clearColors[caIdx] = { (float)mtlCC.red, (float)mtlCC.green, (float)mtlCC.blue, (float)mtlCC.alpha};
}

// The depth value (including vertex position Z value) is held in the last index.
clearColors[kMVKClearAttachmentDepthStencilIndex] = { _mtlDepthVal, _mtlDepthVal, _mtlDepthVal, _mtlDepthVal };
// The depth value is the vertex position Z value.
clearColors[kMVKClearAttachmentDepthIndex] = { _mtlDepthVal, _mtlDepthVal, _mtlDepthVal, _mtlDepthVal };

VkFormat vkAttFmt = subpass->getDepthStencilFormat();
MTLPixelFormat mtlAttFmt = pixFmts->getMTLPixelFormat(vkAttFmt);
_rpsKey.attachmentMTLPixelFormats[kMVKClearAttachmentDepthStencilIndex] = mtlAttFmt;
_rpsKey.attachmentMTLPixelFormats[kMVKClearAttachmentDepthIndex] = pixFmts->getMTLPixelFormat(subpass->getDepthFormat());
if ( !subpass->isDepthAttachmentUsed() ) { _rpsKey.disableAttachment(kMVKClearAttachmentDepthIndex); }

bool isClearingDepth = _isClearingDepth && pixFmts->isDepthFormat(mtlAttFmt);
bool isClearingStencil = _isClearingStencil && pixFmts->isStencilFormat(mtlAttFmt);
if (!isClearingDepth && !isClearingStencil) {
// If the subpass attachment isn't actually used, don't try to clear it.
_rpsKey.disableAttachment(kMVKClearAttachmentDepthStencilIndex);
}
_rpsKey.attachmentMTLPixelFormats[kMVKClearAttachmentStencilIndex] = pixFmts->getMTLPixelFormat(subpass->getStencilFormat());
if ( !subpass->isStencilAttachmentUsed() ) { _rpsKey.disableAttachment(kMVKClearAttachmentStencilIndex); }

if (!_rpsKey.isAnyAttachmentEnabled()) {
// Nothing to do.
return;
}
if ( !_rpsKey.isAnyAttachmentEnabled() ) { return; }

// Render the clear colors to the attachments
MVKCommandEncodingPool* cmdEncPool = cmdEncoder->getCommandEncodingPool();
id<MTLRenderCommandEncoder> mtlRendEnc = cmdEncoder->_mtlRenderEncoder;
[mtlRendEnc pushDebugGroup: getMTLDebugGroupLabel()];
[mtlRendEnc setRenderPipelineState: cmdEncPool->getCmdClearMTLRenderPipelineState(_rpsKey)];
[mtlRendEnc setDepthStencilState: cmdEncPool->getMTLDepthStencilState(isClearingDepth, isClearingStencil)];
[mtlRendEnc setDepthStencilState: cmdEncPool->getMTLDepthStencilState(_rpsKey.isAttachmentUsed(kMVKClearAttachmentDepthIndex),
_rpsKey.isAttachmentUsed(kMVKClearAttachmentStencilIndex))];
[mtlRendEnc setStencilReferenceValue: _mtlStencilValue];
[mtlRendEnc setCullMode: MTLCullModeNone];
[mtlRendEnc setTriangleFillMode: MTLTriangleFillModeFill];
Expand Down
20 changes: 14 additions & 6 deletions MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm
Original file line number Diff line number Diff line change
Expand Up @@ -401,10 +401,17 @@
? VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS
: VK_SUBPASS_CONTENTS_INLINE);

uint32_t maxAttCnt = (pRenderingInfo->colorAttachmentCount + 1) * 2;
MVKImageView* attachments[maxAttCnt];
uint32_t maxAttCnt = (pRenderingInfo->colorAttachmentCount + 2) * 2;
MVKImageView* imageViews[maxAttCnt];
VkClearValue clearValues[maxAttCnt];
uint32_t attCnt = mvkGetAttachments(pRenderingInfo, attachments, clearValues);

uint32_t attCnt = 0;
MVKRenderingAttachmentIterator attIter(pRenderingInfo);
attIter.iterate([&](const VkRenderingAttachmentInfo* pAttInfo, VkImageAspectFlagBits aspect, bool isResolveAttachment)->void {
imageViews[attCnt] = (MVKImageView*)(isResolveAttachment ? pAttInfo->resolveImageView : pAttInfo->imageView);
clearValues[attCnt] = pAttInfo->clearValue;
attCnt++;
});

// If we're resuming a suspended renderpass, continue to use the existing renderpass
// (with updated rendering flags) and framebuffer. Otherwise, create new transient
Expand All @@ -419,13 +426,14 @@
mvkRP->setRenderingFlags(pRenderingInfo->flags);
mvkFB = _pEncodingContext->getFramebuffer();
} else {
mvkRP = mvkCreateRenderPass(getDevice(), pRenderingInfo);
mvkFB = mvkCreateFramebuffer(getDevice(), pRenderingInfo, mvkRP);
auto* mvkDev = getDevice();
mvkRP = mvkDev->createRenderPass(pRenderingInfo, nullptr);
mvkFB = mvkDev->createFramebuffer(pRenderingInfo, nullptr);
}
beginRenderpass(rendCmd, contents, mvkRP, mvkFB,
pRenderingInfo->renderArea,
MVKArrayRef(clearValues, attCnt),
MVKArrayRef(attachments, attCnt),
MVKArrayRef(imageViews, attCnt),
MVKArrayRef<MVKArrayRef<MTLSamplePosition>>(),
kMVKCommandUseBeginRendering);

Expand Down
4 changes: 2 additions & 2 deletions MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ class MVKViewportCommandEncoderState : public MVKCommandEncoderState {
protected:
void encodeImpl(uint32_t stage) override;

MVKSmallVector<VkViewport, kMVKCachedViewportScissorCount> _viewports, _dynamicViewports;
MVKSmallVector<VkViewport, kMVKMaxViewportScissorCount> _viewports, _dynamicViewports;
};


Expand Down Expand Up @@ -180,7 +180,7 @@ class MVKScissorCommandEncoderState : public MVKCommandEncoderState {
protected:
void encodeImpl(uint32_t stage) override;

MVKSmallVector<VkRect2D, kMVKCachedViewportScissorCount> _scissors, _dynamicScissors;
MVKSmallVector<VkRect2D, kMVKMaxViewportScissorCount> _scissors, _dynamicScissors;
};


Expand Down
7 changes: 2 additions & 5 deletions MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm
Original file line number Diff line number Diff line change
Expand Up @@ -328,15 +328,12 @@
MVKCommandEncoderState::beginMetalRenderPass();

MVKRenderSubpass* mvkSubpass = _cmdEncoder->getSubpass();
MVKPixelFormats* pixFmts = _cmdEncoder->getPixelFormats();
MTLPixelFormat mtlDSFormat = pixFmts->getMTLPixelFormat(mvkSubpass->getDepthStencilFormat());

bool prevHasDepthAttachment = _hasDepthAttachment;
_hasDepthAttachment = pixFmts->isDepthFormat(mtlDSFormat);
_hasDepthAttachment = mvkSubpass->isDepthAttachmentUsed();
if (_hasDepthAttachment != prevHasDepthAttachment) { markDirty(); }

bool prevHasStencilAttachment = _hasStencilAttachment;
_hasStencilAttachment = pixFmts->isStencilFormat(mtlDSFormat);
_hasStencilAttachment = mvkSubpass->isStencilAttachmentUsed();
if (_hasStencilAttachment != prevHasStencilAttachment) { markDirty(); }
}

Expand Down
8 changes: 5 additions & 3 deletions MoltenVK/MoltenVK/Commands/MVKCommandResourceFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,11 @@ namespace std {
#pragma mark -
#pragma mark MVKRPSKeyClearAtt

#define kMVKClearAttachmentCount (kMVKCachedColorAttachmentCount + 1)
#define kMVKClearAttachmentDepthStencilIndex (kMVKClearAttachmentCount - 1)
#define kMVKClearAttachmentLayeredRenderingBitIndex kMVKClearAttachmentCount
const static uint32_t kMVKClearColorAttachmentCount = kMVKMaxColorAttachmentCount;
const static uint32_t kMVKClearAttachmentDepthIndex = kMVKClearColorAttachmentCount;
const static uint32_t kMVKClearAttachmentStencilIndex = kMVKClearAttachmentDepthIndex + 1;
const static uint32_t kMVKClearAttachmentCount = kMVKClearAttachmentStencilIndex + 1;
const static uint32_t kMVKClearAttachmentLayeredRenderingBitIndex = kMVKClearAttachmentStencilIndex + 1;

/**
* Key to use for looking up cached MTLRenderPipelineState instances.
Expand Down
29 changes: 17 additions & 12 deletions MoltenVK/MoltenVK/Commands/MVKCommandResourceFactory.mm
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@

id<MTLRenderPipelineState> MVKCommandResourceFactory::newCmdClearMTLRenderPipelineState(MVKRPSKeyClearAtt& attKey,
MVKVulkanAPIDeviceObject* owner) {
MVKPixelFormats* pixFmts = getPixelFormats();

id<MTLFunction> vtxFunc = newClearVertFunction(attKey); // temp retain
id<MTLFunction> fragFunc = newClearFragFunction(attKey); // temp retain
MTLRenderPipelineDescriptor* plDesc = [MTLRenderPipelineDescriptor new]; // temp retain
Expand All @@ -122,15 +124,17 @@
plDesc.sampleCount = attKey.mtlSampleCount;
plDesc.inputPrimitiveTopologyMVK = MTLPrimitiveTopologyClassTriangle;

for (uint32_t caIdx = 0; caIdx < kMVKClearAttachmentDepthStencilIndex; caIdx++) {
for (uint32_t caIdx = 0; caIdx < kMVKClearColorAttachmentCount; caIdx++) {
MTLRenderPipelineColorAttachmentDescriptor* colorDesc = plDesc.colorAttachments[caIdx];
colorDesc.pixelFormat = (MTLPixelFormat)attKey.attachmentMTLPixelFormats[caIdx];
colorDesc.writeMask = attKey.isAttachmentEnabled(caIdx) ? MTLColorWriteMaskAll : MTLColorWriteMaskNone;
}
MVKPixelFormats* pixFmts = getPixelFormats();
MTLPixelFormat mtlDSFormat = (MTLPixelFormat)attKey.attachmentMTLPixelFormats[kMVKClearAttachmentDepthStencilIndex];
if (pixFmts->isDepthFormat(mtlDSFormat)) { plDesc.depthAttachmentPixelFormat = mtlDSFormat; }
if (pixFmts->isStencilFormat(mtlDSFormat)) { plDesc.stencilAttachmentPixelFormat = mtlDSFormat; }

MTLPixelFormat mtlDepthFormat = (MTLPixelFormat)attKey.attachmentMTLPixelFormats[kMVKClearAttachmentDepthIndex];
if (pixFmts->isDepthFormat(mtlDepthFormat)) { plDesc.depthAttachmentPixelFormat = mtlDepthFormat; }

MTLPixelFormat mtlStencilFormat = (MTLPixelFormat)attKey.attachmentMTLPixelFormats[kMVKClearAttachmentStencilIndex];
if (pixFmts->isStencilFormat(mtlStencilFormat)) { plDesc.stencilAttachmentPixelFormat = mtlStencilFormat; }

MTLVertexDescriptor* vtxDesc = plDesc.vertexDescriptor;

Expand Down Expand Up @@ -273,7 +277,7 @@
[msl appendLineMVK: @" return out;"];
[msl appendLineMVK: @"}"];

// MVKLogDebug("\n%s", msl.UTF8String);
// MVKLogInfo("\n%s", msl.UTF8String);

return newMTLFunction(msl, funcName);
}
Expand All @@ -300,15 +304,16 @@
[msl appendLineMVK];

NSString* funcName = @"vertClear";
[msl appendFormat: @"vertex VaryingsPos %@(AttributesPos attributes [[stage_in]], constant ClearColorsIn& ccIn [[buffer(0)]]) {", funcName];
[msl appendFormat: @"vertex VaryingsPos %@(AttributesPos attributes [[stage_in]], constant ClearColorsIn& ccIn [[buffer(0)]]) {", funcName];
[msl appendLineMVK];
[msl appendLineMVK: @" VaryingsPos varyings;"];
[msl appendLineMVK: @" varyings.v_position = float4(attributes.a_position.x, -attributes.a_position.y, ccIn.colors[8].r, 1.0);"];
[msl appendFormat: @" varyings.v_position = float4(attributes.a_position.x, -attributes.a_position.y, ccIn.colors[%d].r, 1.0);", kMVKClearAttachmentDepthIndex];
[msl appendLineMVK];
[msl appendLineMVK: @" varyings.layer = uint(attributes.a_position.w);"];
[msl appendLineMVK: @" return varyings;"];
[msl appendLineMVK: @"}"];

// MVKLogDebug("\n%s", msl.UTF8String);
// MVKLogInfo("\n%s", msl.UTF8String);

return newMTLFunction(msl, funcName);
}
Expand All @@ -329,7 +334,7 @@
[msl appendLineMVK: @"} ClearColorsIn;"];
[msl appendLineMVK];
[msl appendLineMVK: @"typedef struct {"];
for (uint32_t caIdx = 0; caIdx < kMVKClearAttachmentDepthStencilIndex; caIdx++) {
for (uint32_t caIdx = 0; caIdx < kMVKClearColorAttachmentCount; caIdx++) {
if (attKey.isAttachmentUsed(caIdx)) {
NSString* typeStr = getMTLFormatTypeString((MTLPixelFormat)attKey.attachmentMTLPixelFormats[caIdx]);
[msl appendFormat: @" %@4 color%u [[color(%u)]];", typeStr, caIdx, caIdx];
Expand All @@ -343,7 +348,7 @@
[msl appendFormat: @"fragment ClearColorsOut %@(VaryingsPos varyings [[stage_in]], constant ClearColorsIn& ccIn [[buffer(0)]]) {", funcName];
[msl appendLineMVK];
[msl appendLineMVK: @" ClearColorsOut ccOut;"];
for (uint32_t caIdx = 0; caIdx < kMVKClearAttachmentDepthStencilIndex; caIdx++) {
for (uint32_t caIdx = 0; caIdx < kMVKClearColorAttachmentCount; caIdx++) {
if (attKey.isAttachmentUsed(caIdx)) {
NSString* typeStr = getMTLFormatTypeString((MTLPixelFormat)attKey.attachmentMTLPixelFormats[caIdx]);
[msl appendFormat: @" ccOut.color%u = %@4(ccIn.colors[%u]);", caIdx, typeStr, caIdx];
Expand All @@ -353,7 +358,7 @@
[msl appendLineMVK: @" return ccOut;"];
[msl appendLineMVK: @"}"];

// MVKLogDebug("\n%s", msl.UTF8String);
// MVKLogInfo("\n%s", msl.UTF8String);

return newMTLFunction(msl, funcName);
}
Expand Down
8 changes: 6 additions & 2 deletions MoltenVK/MoltenVK/GPUObjects/MVKDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ const static uint32_t kMVKQueueFamilyCount = 4;
const static uint32_t kMVKQueueCountPerQueueFamily = 1; // Must be 1. See comments in MVKPhysicalDevice::getQueueFamilies()
const static uint32_t kMVKMinSwapchainImageCount = 2;
const static uint32_t kMVKMaxSwapchainImageCount = 3;
const static uint32_t kMVKCachedViewportScissorCount = 16;
const static uint32_t kMVKCachedColorAttachmentCount = 8;
const static uint32_t kMVKMaxColorAttachmentCount = 8;
const static uint32_t kMVKMaxViewportScissorCount = 16;
const static uint32_t kMVKMaxDescriptorSetCount = SPIRV_CROSS_NAMESPACE::kMaxArgumentBuffers;

#if !MVK_XCODE_12
Expand Down Expand Up @@ -631,13 +631,17 @@ class MVKDevice : public MVKDispatchableVulkanAPIObject {

MVKFramebuffer* createFramebuffer(const VkFramebufferCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator);
MVKFramebuffer* createFramebuffer(const VkRenderingInfo* pRenderingInfo,
const VkAllocationCallbacks* pAllocator);
void destroyFramebuffer(MVKFramebuffer* mvkFB,
const VkAllocationCallbacks* pAllocator);

MVKRenderPass* createRenderPass(const VkRenderPassCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator);
MVKRenderPass* createRenderPass(const VkRenderPassCreateInfo2* pCreateInfo,
const VkAllocationCallbacks* pAllocator);
MVKRenderPass* createRenderPass(const VkRenderingInfo* pRenderingInfo,
const VkAllocationCallbacks* pAllocator);
void destroyRenderPass(MVKRenderPass* mvkRP,
const VkAllocationCallbacks* pAllocator);

Expand Down
20 changes: 15 additions & 5 deletions MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
Original file line number Diff line number Diff line change
Expand Up @@ -2269,17 +2269,17 @@
void MVKPhysicalDevice::initLimits() {

#if MVK_TVOS
_properties.limits.maxColorAttachments = kMVKCachedColorAttachmentCount;
_properties.limits.maxColorAttachments = kMVKMaxColorAttachmentCount;
#endif
#if MVK_IOS
if (supportsMTLFeatureSet(iOS_GPUFamily2_v1)) {
_properties.limits.maxColorAttachments = kMVKCachedColorAttachmentCount;
_properties.limits.maxColorAttachments = kMVKMaxColorAttachmentCount;
} else {
_properties.limits.maxColorAttachments = 4; // < kMVKCachedColorAttachmentCount
_properties.limits.maxColorAttachments = 4; // < kMVKMaxColorAttachmentCount
}
#endif
#if MVK_MACOS
_properties.limits.maxColorAttachments = kMVKCachedColorAttachmentCount;
_properties.limits.maxColorAttachments = kMVKMaxColorAttachmentCount;
#endif

_properties.limits.maxFragmentOutputAttachments = _properties.limits.maxColorAttachments;
Expand Down Expand Up @@ -2309,7 +2309,7 @@
float maxVPDim = max(_properties.limits.maxViewportDimensions[0], _properties.limits.maxViewportDimensions[1]);
_properties.limits.viewportBoundsRange[0] = (-2.0 * maxVPDim);
_properties.limits.viewportBoundsRange[1] = (2.0 * maxVPDim) - 1;
_properties.limits.maxViewports = _features.multiViewport ? kMVKCachedViewportScissorCount : 1;
_properties.limits.maxViewports = _features.multiViewport ? kMVKMaxViewportScissorCount : 1;

_properties.limits.maxImageDimension3D = _metalFeatures.maxTextureLayers;
_properties.limits.maxImageArrayLayers = _metalFeatures.maxTextureLayers;
Expand Down Expand Up @@ -3893,6 +3893,11 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope
return new MVKFramebuffer(this, pCreateInfo);
}

MVKFramebuffer* MVKDevice::createFramebuffer(const VkRenderingInfo* pRenderingInfo,
const VkAllocationCallbacks* pAllocator) {
return new MVKFramebuffer(this, pRenderingInfo);
}

void MVKDevice::destroyFramebuffer(MVKFramebuffer* mvkFB,
const VkAllocationCallbacks* pAllocator) {
if (mvkFB) { mvkFB->destroy(); }
Expand All @@ -3908,6 +3913,11 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope
return new MVKRenderPass(this, pCreateInfo);
}

MVKRenderPass* MVKDevice::createRenderPass(const VkRenderingInfo* pRenderingInfo,
const VkAllocationCallbacks* pAllocator) {
return new MVKRenderPass(this, pRenderingInfo);
}

void MVKDevice::destroyRenderPass(MVKRenderPass* mvkRP,
const VkAllocationCallbacks* pAllocator) {
if (mvkRP) { mvkRP->destroy(); }
Expand Down
Loading

0 comments on commit e50cb32

Please sign in to comment.