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;
MVKCmdCopyImage(MVKCommandTypePool<MVKCmdCopyImage>* pool);
MVKCmdCopyImage(MVKCommandTypePool<MVKCmdCopyImage>* pool) :
MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
protected:
void addMetalCopyRegions(const VkImageCopy* pRegion);
@ -180,7 +181,8 @@ public:
void encode(MVKCommandEncoder* cmdEncoder) override;
MVKCmdCopyBuffer(MVKCommandTypePool<MVKCmdCopyBuffer>* pool);
MVKCmdCopyBuffer(MVKCommandTypePool<MVKCmdCopyBuffer>* pool) :
MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
protected:
@ -206,7 +208,8 @@ public:
void encode(MVKCommandEncoder* cmdEncoder) override;
MVKCmdBufferImageCopy(MVKCommandTypePool<MVKCmdBufferImageCopy>* pool);
MVKCmdBufferImageCopy(MVKCommandTypePool<MVKCmdBufferImageCopy>* pool) :
MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
protected:
MVKBuffer* _buffer;
@ -231,9 +234,8 @@ public:
void encode(MVKCommandEncoder* cmdEncoder) override;
MVKCmdClearAttachments(MVKCommandTypePool<MVKCmdClearAttachments>* pool);
~MVKCmdClearAttachments() override;
MVKCmdClearAttachments(MVKCommandTypePool<MVKCmdClearAttachments>* pool) :
MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
protected:
void populateVertices(float attWidth, float attHeight);
@ -266,9 +268,8 @@ public:
void encode(MVKCommandEncoder* cmdEncoder) override;
MVKCmdClearImage(MVKCommandTypePool<MVKCmdClearImage>* pool);
~MVKCmdClearImage();
MVKCmdClearImage(MVKCommandTypePool<MVKCmdClearImage>* pool) :
MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
protected:
uint32_t populateMetalCopyRegions(const VkImageBlit* pRegion, uint32_t cpyRgnIdx);
@ -279,7 +280,6 @@ protected:
VkImageLayout _imgLayout;
std::vector<VkImageSubresourceRange> _subresourceRanges;
simd::float4 _clearColors[kMVKAttachmentFormatCount];
MTLRenderPassDescriptor* _mtlRenderPassDescriptor;
MVKRPSKeyClearAtt _rpsKey;
uint32_t _mtlStencilValue;
bool _isDepthStencilClear;
@ -297,7 +297,8 @@ public:
void encode(MVKCommandEncoder* cmdEncoder) override;
MVKCmdFillBuffer(MVKCommandTypePool<MVKCmdFillBuffer>* pool);
MVKCmdFillBuffer(MVKCommandTypePool<MVKCmdFillBuffer>* pool) :
MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
protected:
MVKBuffer* _dstBuffer;
@ -322,7 +323,8 @@ public:
void encode(MVKCommandEncoder* cmdEncoder) override;
MVKCmdUpdateBuffer(MVKCommandTypePool<MVKCmdUpdateBuffer>* pool);
MVKCmdUpdateBuffer(MVKCommandTypePool<MVKCmdUpdateBuffer>* pool) :
MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
protected:
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 MVKCmdBlitImage
@ -596,9 +593,6 @@ void MVKCmdCopyBuffer::encode(MVKCommandEncoder* cmdEncoder) {
}
}
MVKCmdCopyBuffer::MVKCmdCopyBuffer(MVKCommandTypePool<MVKCmdCopyBuffer>* pool)
: MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
#pragma mark -
#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 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 MVKCmdClearImage
@ -903,14 +886,12 @@ void MVKCmdClearImage::setContent(VkImage image,
void MVKCmdClearImage::encode(MVKCommandEncoder* cmdEncoder) {
MTLPixelFormat imgMTLPixFmt = _image->getMTLPixelFormat();
id<MTLTexture> imgMTLTex = _image->getMTLTexture();
if ( !imgMTLTex ) { return; }
cmdEncoder->endCurrentMetalEncoding();
MTLRenderPassColorAttachmentDescriptor* mtlColorAttDesc = _mtlRenderPassDescriptor.colorAttachments[0];
mtlColorAttDesc.texture = imgMTLTex;
static const simd::float2 vertices[] = {
{ -1.0, -1.0 }, // Bottom-left
{ 1.0, -1.0 }, // Bottom-right
@ -920,17 +901,38 @@ void MVKCmdClearImage::encode(MVKCommandEncoder* cmdEncoder) {
uint32_t vtxBuffIdx = getDevice()->getMetalBufferIndexForVertexAttributeBinding(kMVKVertexContentBufferIndex);
MTLRenderPassDescriptor* mtlRPDesc = [MTLRenderPassDescriptor renderPassDescriptor];
MTLRenderPassAttachmentDescriptor* mtlRPCADesc = nil;
MTLRenderPassAttachmentDescriptor* mtlRPDADesc = nil;
MTLRenderPassAttachmentDescriptor* mtlRPSADesc = nil;
NSString* mtlRendEncName;
NSString* mtlDebugGroupName;
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";
mtlRendEncName = mvkMTLRenderCommandEncoderLabel(kMVKCommandUseClearDepthStencilImage);
} else {
mtlRPCADesc = mtlRPDesc.colorAttachments[0];
mtlRPCADesc.texture = imgMTLTex;
mtlRPCADesc.loadAction = MTLLoadActionLoad;
mtlRPCADesc.storeAction = MTLStoreActionStore;
mtlDebugGroupName = @"vkCmdClearColorImage";
mtlRendEncName = mvkMTLRenderCommandEncoderLabel(kMVKCommandUseClearColorImage);
}
MVKCommandEncodingPool* cmdEncPool = cmdEncoder->getCommandEncodingPool();
id<MTLRenderPipelineState> mtlRPS = cmdEncPool->getCmdClearMTLRenderPipelineState(_rpsKey);
size_t srCnt = _subresourceRanges.size();
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 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
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
for (uint32_t mipLvl = mipLvlStart; mipLvl < mipLvlEnd; mipLvl++) {
mtlColorAttDesc.level = mipLvl;
for (uint32_t layer = layerStart; layer < layerEnd; layer++) {
mtlColorAttDesc.slice = layer;
mtlRPCADesc.level = mipLvl;
mtlRPDADesc.level = mipLvl;
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 pushDebugGroup: mtlDebugGroupName];
[mtlRendEnc setRenderPipelineState: cmdEncPool->getCmdClearMTLRenderPipelineState(_rpsKey)];
[mtlRendEnc setDepthStencilState: cmdEncPool->getMTLDepthStencilState(isClearingDepth, isClearingStencil)];
[mtlRendEnc setRenderPipelineState: mtlRPS];
[mtlRendEnc setDepthStencilState: mtlDSS];
[mtlRendEnc setStencilReferenceValue: _mtlStencilValue];
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 MVKCmdFillBuffer
@ -1024,9 +1015,6 @@ void MVKCmdFillBuffer::encode(MVKCommandEncoder* cmdEncoder) {
value: (uint8_t)_dataValue];
}
MVKCmdFillBuffer::MVKCmdFillBuffer(MVKCommandTypePool<MVKCmdFillBuffer>* pool)
: MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
#pragma mark -
#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 Command creation functions