vkCmdClearImage() fixes to clearing depth and stencil formats and avoid Metal validation errors.

This commit is contained in:
Bill Hollings 2018-06-15 14:25:52 -04:00
parent 9ae35d73c4
commit e90480ea99
2 changed files with 48 additions and 61 deletions

View File

@ -59,7 +59,8 @@ public:
void encode(MVKCommandEncoder* cmdEncoder) override; void encode(MVKCommandEncoder* cmdEncoder) override;
MVKCmdCopyImage(MVKCommandTypePool<MVKCmdCopyImage>* pool); MVKCmdCopyImage(MVKCommandTypePool<MVKCmdCopyImage>* pool) :
MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
protected: protected:
void addMetalCopyRegions(const VkImageCopy* pRegion); void addMetalCopyRegions(const VkImageCopy* pRegion);
@ -180,7 +181,8 @@ public:
void encode(MVKCommandEncoder* cmdEncoder) override; void encode(MVKCommandEncoder* cmdEncoder) override;
MVKCmdCopyBuffer(MVKCommandTypePool<MVKCmdCopyBuffer>* pool); MVKCmdCopyBuffer(MVKCommandTypePool<MVKCmdCopyBuffer>* pool) :
MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
protected: protected:
@ -206,7 +208,8 @@ public:
void encode(MVKCommandEncoder* cmdEncoder) override; void encode(MVKCommandEncoder* cmdEncoder) override;
MVKCmdBufferImageCopy(MVKCommandTypePool<MVKCmdBufferImageCopy>* pool); MVKCmdBufferImageCopy(MVKCommandTypePool<MVKCmdBufferImageCopy>* pool) :
MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
protected: protected:
MVKBuffer* _buffer; MVKBuffer* _buffer;
@ -231,9 +234,8 @@ public:
void encode(MVKCommandEncoder* cmdEncoder) override; void encode(MVKCommandEncoder* cmdEncoder) override;
MVKCmdClearAttachments(MVKCommandTypePool<MVKCmdClearAttachments>* pool); MVKCmdClearAttachments(MVKCommandTypePool<MVKCmdClearAttachments>* pool) :
MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
~MVKCmdClearAttachments() override;
protected: protected:
void populateVertices(float attWidth, float attHeight); void populateVertices(float attWidth, float attHeight);
@ -266,9 +268,8 @@ public:
void encode(MVKCommandEncoder* cmdEncoder) override; void encode(MVKCommandEncoder* cmdEncoder) override;
MVKCmdClearImage(MVKCommandTypePool<MVKCmdClearImage>* pool); MVKCmdClearImage(MVKCommandTypePool<MVKCmdClearImage>* pool) :
MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
~MVKCmdClearImage();
protected: protected:
uint32_t populateMetalCopyRegions(const VkImageBlit* pRegion, uint32_t cpyRgnIdx); uint32_t populateMetalCopyRegions(const VkImageBlit* pRegion, uint32_t cpyRgnIdx);
@ -279,7 +280,6 @@ protected:
VkImageLayout _imgLayout; VkImageLayout _imgLayout;
std::vector<VkImageSubresourceRange> _subresourceRanges; std::vector<VkImageSubresourceRange> _subresourceRanges;
simd::float4 _clearColors[kMVKAttachmentFormatCount]; simd::float4 _clearColors[kMVKAttachmentFormatCount];
MTLRenderPassDescriptor* _mtlRenderPassDescriptor;
MVKRPSKeyClearAtt _rpsKey; MVKRPSKeyClearAtt _rpsKey;
uint32_t _mtlStencilValue; uint32_t _mtlStencilValue;
bool _isDepthStencilClear; bool _isDepthStencilClear;
@ -297,7 +297,8 @@ public:
void encode(MVKCommandEncoder* cmdEncoder) override; void encode(MVKCommandEncoder* cmdEncoder) override;
MVKCmdFillBuffer(MVKCommandTypePool<MVKCmdFillBuffer>* pool); MVKCmdFillBuffer(MVKCommandTypePool<MVKCmdFillBuffer>* pool) :
MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
protected: protected:
MVKBuffer* _dstBuffer; MVKBuffer* _dstBuffer;
@ -322,7 +323,8 @@ public:
void encode(MVKCommandEncoder* cmdEncoder) override; void encode(MVKCommandEncoder* cmdEncoder) override;
MVKCmdUpdateBuffer(MVKCommandTypePool<MVKCmdUpdateBuffer>* pool); MVKCmdUpdateBuffer(MVKCommandTypePool<MVKCmdUpdateBuffer>* pool) :
MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
protected: protected:
MVKBuffer* _dstBuffer; MVKBuffer* _dstBuffer;

View File

@ -104,9 +104,6 @@ void MVKCmdCopyImage::encode(MVKCommandEncoder* cmdEncoder) {
} }
} }
MVKCmdCopyImage::MVKCmdCopyImage(MVKCommandTypePool<MVKCmdCopyImage>* pool)
: MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
#pragma mark - #pragma mark -
#pragma mark MVKCmdBlitImage #pragma mark MVKCmdBlitImage
@ -596,9 +593,6 @@ void MVKCmdCopyBuffer::encode(MVKCommandEncoder* cmdEncoder) {
} }
} }
MVKCmdCopyBuffer::MVKCmdCopyBuffer(MVKCommandTypePool<MVKCmdCopyBuffer>* pool)
: MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
#pragma mark - #pragma mark -
#pragma mark MVKCmdBufferImageCopy #pragma mark MVKCmdBufferImageCopy
@ -704,9 +698,6 @@ void MVKCmdBufferImageCopy::encode(MVKCommandEncoder* cmdEncoder) {
} }
} }
MVKCmdBufferImageCopy::MVKCmdBufferImageCopy(MVKCommandTypePool<MVKCmdBufferImageCopy>* pool)
: MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
#pragma mark - #pragma mark -
#pragma mark MVKCmdClearAttachments #pragma mark MVKCmdClearAttachments
@ -855,14 +846,6 @@ void MVKCmdClearAttachments::encode(MVKCommandEncoder* cmdEncoder) {
} }
#pragma mark Construction
MVKCmdClearAttachments::MVKCmdClearAttachments(MVKCommandTypePool<MVKCmdClearAttachments>* pool)
: MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
MVKCmdClearAttachments::~MVKCmdClearAttachments() {}
#pragma mark - #pragma mark -
#pragma mark MVKCmdClearImage #pragma mark MVKCmdClearImage
@ -903,14 +886,12 @@ void MVKCmdClearImage::setContent(VkImage image,
void MVKCmdClearImage::encode(MVKCommandEncoder* cmdEncoder) { void MVKCmdClearImage::encode(MVKCommandEncoder* cmdEncoder) {
MTLPixelFormat imgMTLPixFmt = _image->getMTLPixelFormat();
id<MTLTexture> imgMTLTex = _image->getMTLTexture(); id<MTLTexture> imgMTLTex = _image->getMTLTexture();
if ( !imgMTLTex ) { return; } if ( !imgMTLTex ) { return; }
cmdEncoder->endCurrentMetalEncoding(); cmdEncoder->endCurrentMetalEncoding();
MTLRenderPassColorAttachmentDescriptor* mtlColorAttDesc = _mtlRenderPassDescriptor.colorAttachments[0];
mtlColorAttDesc.texture = imgMTLTex;
static const simd::float2 vertices[] = { static const simd::float2 vertices[] = {
{ -1.0, -1.0 }, // Bottom-left { -1.0, -1.0 }, // Bottom-left
{ 1.0, -1.0 }, // Bottom-right { 1.0, -1.0 }, // Bottom-right
@ -920,17 +901,38 @@ void MVKCmdClearImage::encode(MVKCommandEncoder* cmdEncoder) {
uint32_t vtxBuffIdx = getDevice()->getMetalBufferIndexForVertexAttributeBinding(kMVKVertexContentBufferIndex); uint32_t vtxBuffIdx = getDevice()->getMetalBufferIndexForVertexAttributeBinding(kMVKVertexContentBufferIndex);
MTLRenderPassDescriptor* mtlRPDesc = [MTLRenderPassDescriptor renderPassDescriptor];
MTLRenderPassAttachmentDescriptor* mtlRPCADesc = nil;
MTLRenderPassAttachmentDescriptor* mtlRPDADesc = nil;
MTLRenderPassAttachmentDescriptor* mtlRPSADesc = nil;
NSString* mtlRendEncName; NSString* mtlRendEncName;
NSString* mtlDebugGroupName; NSString* mtlDebugGroupName;
if (_isDepthStencilClear) { if (_isDepthStencilClear) {
if (mvkMTLPixelFormatIsDepthFormat(imgMTLPixFmt)) {
mtlRPDADesc = mtlRPDesc.depthAttachment;
mtlRPDADesc.texture = imgMTLTex;
mtlRPDADesc.loadAction = MTLLoadActionLoad;
mtlRPDADesc.storeAction = MTLStoreActionStore;
}
if (mvkMTLPixelFormatIsStencilFormat(imgMTLPixFmt)) {
mtlRPSADesc = mtlRPDesc.stencilAttachment;
mtlRPSADesc.texture = imgMTLTex;
mtlRPSADesc.loadAction = MTLLoadActionLoad;
mtlRPSADesc.storeAction = MTLStoreActionStore;
}
mtlDebugGroupName = @"vkCmdClearDepthStencilImage"; mtlDebugGroupName = @"vkCmdClearDepthStencilImage";
mtlRendEncName = mvkMTLRenderCommandEncoderLabel(kMVKCommandUseClearDepthStencilImage); mtlRendEncName = mvkMTLRenderCommandEncoderLabel(kMVKCommandUseClearDepthStencilImage);
} else { } else {
mtlRPCADesc = mtlRPDesc.colorAttachments[0];
mtlRPCADesc.texture = imgMTLTex;
mtlRPCADesc.loadAction = MTLLoadActionLoad;
mtlRPCADesc.storeAction = MTLStoreActionStore;
mtlDebugGroupName = @"vkCmdClearColorImage"; mtlDebugGroupName = @"vkCmdClearColorImage";
mtlRendEncName = mvkMTLRenderCommandEncoderLabel(kMVKCommandUseClearColorImage); mtlRendEncName = mvkMTLRenderCommandEncoderLabel(kMVKCommandUseClearColorImage);
} }
MVKCommandEncodingPool* cmdEncPool = cmdEncoder->getCommandEncodingPool(); MVKCommandEncodingPool* cmdEncPool = cmdEncoder->getCommandEncodingPool();
id<MTLRenderPipelineState> mtlRPS = cmdEncPool->getCmdClearMTLRenderPipelineState(_rpsKey);
size_t srCnt = _subresourceRanges.size(); size_t srCnt = _subresourceRanges.size();
for (uint32_t srIdx = 0; srIdx < srCnt; srIdx++) { for (uint32_t srIdx = 0; srIdx < srCnt; srIdx++) {
@ -938,6 +940,7 @@ void MVKCmdClearImage::encode(MVKCommandEncoder* cmdEncoder) {
bool isClearingDepth = _isDepthStencilClear && mvkIsAnyFlagEnabled(srRange.aspectMask, VK_IMAGE_ASPECT_DEPTH_BIT); bool isClearingDepth = _isDepthStencilClear && mvkIsAnyFlagEnabled(srRange.aspectMask, VK_IMAGE_ASPECT_DEPTH_BIT);
bool isClearingStencil = _isDepthStencilClear && mvkIsAnyFlagEnabled(srRange.aspectMask, VK_IMAGE_ASPECT_STENCIL_BIT); bool isClearingStencil = _isDepthStencilClear && mvkIsAnyFlagEnabled(srRange.aspectMask, VK_IMAGE_ASPECT_STENCIL_BIT);
id<MTLDepthStencilState> mtlDSS = cmdEncPool->getMTLDepthStencilState(isClearingDepth, isClearingStencil);
// Extract the mipmap levels that are to be updated // Extract the mipmap levels that are to be updated
uint32_t mipLvlStart = srRange.baseMipLevel; uint32_t mipLvlStart = srRange.baseMipLevel;
@ -955,16 +958,21 @@ void MVKCmdClearImage::encode(MVKCommandEncoder* cmdEncoder) {
// Iterate across mipmap levels and layers, and render to clear each // Iterate across mipmap levels and layers, and render to clear each
for (uint32_t mipLvl = mipLvlStart; mipLvl < mipLvlEnd; mipLvl++) { for (uint32_t mipLvl = mipLvlStart; mipLvl < mipLvlEnd; mipLvl++) {
mtlColorAttDesc.level = mipLvl; mtlRPCADesc.level = mipLvl;
for (uint32_t layer = layerStart; layer < layerEnd; layer++) { mtlRPDADesc.level = mipLvl;
mtlColorAttDesc.slice = layer; mtlRPSADesc.level = mipLvl;
id<MTLRenderCommandEncoder> mtlRendEnc = [cmdEncoder->_mtlCmdBuffer renderCommandEncoderWithDescriptor: _mtlRenderPassDescriptor]; for (uint32_t layer = layerStart; layer < layerEnd; layer++) {
mtlRPCADesc.slice = layer;
mtlRPDADesc.slice = layer;
mtlRPSADesc.slice = layer;
id<MTLRenderCommandEncoder> mtlRendEnc = [cmdEncoder->_mtlCmdBuffer renderCommandEncoderWithDescriptor: mtlRPDesc];
mtlRendEnc.label = mtlRendEncName; mtlRendEnc.label = mtlRendEncName;
[mtlRendEnc pushDebugGroup: mtlDebugGroupName]; [mtlRendEnc pushDebugGroup: mtlDebugGroupName];
[mtlRendEnc setRenderPipelineState: cmdEncPool->getCmdClearMTLRenderPipelineState(_rpsKey)]; [mtlRendEnc setRenderPipelineState: mtlRPS];
[mtlRendEnc setDepthStencilState: cmdEncPool->getMTLDepthStencilState(isClearingDepth, isClearingStencil)]; [mtlRendEnc setDepthStencilState: mtlDSS];
[mtlRendEnc setStencilReferenceValue: _mtlStencilValue]; [mtlRendEnc setStencilReferenceValue: _mtlStencilValue];
cmdEncoder->setVertexBytes(mtlRendEnc, _clearColors, sizeof(_clearColors), 0); cmdEncoder->setVertexBytes(mtlRendEnc, _clearColors, sizeof(_clearColors), 0);
@ -979,23 +987,6 @@ void MVKCmdClearImage::encode(MVKCommandEncoder* cmdEncoder) {
} }
#pragma mark Construction
MVKCmdClearImage::MVKCmdClearImage(MVKCommandTypePool<MVKCmdClearImage>* pool)
: MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {
// Create and configure the render pass descriptor
_mtlRenderPassDescriptor = [[MTLRenderPassDescriptor renderPassDescriptor] retain]; // retained
MTLRenderPassColorAttachmentDescriptor* mtlColorAttDesc = _mtlRenderPassDescriptor.colorAttachments[0];
mtlColorAttDesc.loadAction = MTLLoadActionLoad;
mtlColorAttDesc.storeAction = MTLStoreActionStore;
}
MVKCmdClearImage::~MVKCmdClearImage() {
[_mtlRenderPassDescriptor release];
}
#pragma mark - #pragma mark -
#pragma mark MVKCmdFillBuffer #pragma mark MVKCmdFillBuffer
@ -1024,9 +1015,6 @@ void MVKCmdFillBuffer::encode(MVKCommandEncoder* cmdEncoder) {
value: (uint8_t)_dataValue]; value: (uint8_t)_dataValue];
} }
MVKCmdFillBuffer::MVKCmdFillBuffer(MVKCommandTypePool<MVKCmdFillBuffer>* pool)
: MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
#pragma mark - #pragma mark -
#pragma mark MVKCmdUpdateBuffer #pragma mark MVKCmdUpdateBuffer
@ -1067,9 +1055,6 @@ void MVKCmdUpdateBuffer::encode(MVKCommandEncoder* cmdEncoder) {
}]; }];
} }
MVKCmdUpdateBuffer::MVKCmdUpdateBuffer(MVKCommandTypePool<MVKCmdUpdateBuffer>* pool)
: MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
#pragma mark - #pragma mark -
#pragma mark Command creation functions #pragma mark Command creation functions