Merge pull request #569 from mbarriault/master

Fix tessellation pipeline re-clearing attachments.
This commit is contained in:
Bill Hollings 2019-04-11 18:31:15 -04:00 committed by GitHub
commit c425602ee7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 25 additions and 16 deletions

View File

@ -194,7 +194,7 @@ void MVKCmdDraw::encode(MVKCommandEncoder* cmdEncoder) {
threadsPerThreadgroup: MTLSizeMake(std::max(inControlPointCount, outControlPointCount), 1, 1)];
// Running this stage prematurely ended the render pass, so we have to start it up again.
// TODO: On iOS, maybe we could use a tile shader to avoid this.
cmdEncoder->beginMetalRenderPass();
cmdEncoder->beginMetalRenderPass(true);
break;
case kMVKGraphicsStageRasterization:
if (pipeline->isTessellationPipeline()) {
@ -413,7 +413,7 @@ void MVKCmdDrawIndexed::encode(MVKCommandEncoder* cmdEncoder) {
threadsPerThreadgroup: MTLSizeMake(std::max(inControlPointCount, outControlPointCount), 1, 1)];
// Running this stage prematurely ended the render pass, so we have to start it up again.
// TODO: On iOS, maybe we could use a tile shader to avoid this.
cmdEncoder->beginMetalRenderPass();
cmdEncoder->beginMetalRenderPass(true);
break;
case kMVKGraphicsStageRasterization:
if (pipeline->isTessellationPipeline()) {
@ -663,7 +663,7 @@ void MVKCmdDrawIndirect::encode(MVKCommandEncoder* cmdEncoder) {
mtlTCIndBuffOfst += sizeof(MTLDispatchThreadgroupsIndirectArguments);
// Running this stage prematurely ended the render pass, so we have to start it up again.
// TODO: On iOS, maybe we could use a tile shader to avoid this.
cmdEncoder->beginMetalRenderPass();
cmdEncoder->beginMetalRenderPass(true);
break;
case kMVKGraphicsStageRasterization:
if (pipeline->isTessellationPipeline()) {
@ -909,7 +909,7 @@ void MVKCmdDrawIndexedIndirect::encode(MVKCommandEncoder* cmdEncoder) {
mtlTCIndBuffOfst += sizeof(MTLDispatchThreadgroupsIndirectArguments);
// Running this stage prematurely ended the render pass, so we have to start it up again.
// TODO: On iOS, maybe we could use a tile shader to avoid this.
cmdEncoder->beginMetalRenderPass();
cmdEncoder->beginMetalRenderPass(true);
break;
case kMVKGraphicsStageRasterization:
if (pipeline->isTessellationPipeline()) {

View File

@ -246,7 +246,7 @@ public:
void beginNextSubpass(VkSubpassContents renderpassContents);
/** Begins a Metal render pass for the current render subpass. */
void beginMetalRenderPass();
void beginMetalRenderPass(bool loadOverride = false);
/** Returns the render subpass that is currently active. */
MVKRenderSubpass* getSubpass();

View File

@ -242,12 +242,12 @@ void MVKCommandEncoder::setSubpass(VkSubpassContents subpassContents, uint32_t s
}
// Creates _mtlRenderEncoder and marks cached render state as dirty so it will be set into the _mtlRenderEncoder.
void MVKCommandEncoder::beginMetalRenderPass() {
void MVKCommandEncoder::beginMetalRenderPass(bool loadOverride) {
endCurrentMetalEncoding();
MTLRenderPassDescriptor* mtlRPDesc = [MTLRenderPassDescriptor renderPassDescriptor];
getSubpass()->populateMTLRenderPassDescriptor(mtlRPDesc, _framebuffer, _clearValues, _isRenderingEntireAttachment);
getSubpass()->populateMTLRenderPassDescriptor(mtlRPDesc, _framebuffer, _clearValues, _isRenderingEntireAttachment, loadOverride);
mtlRPDesc.visibilityResultBuffer = _occlusionQueryState.getVisibilityResultMTLBuffer();
if (_device->_pMetalFeatures->layeredRendering) {

View File

@ -58,7 +58,8 @@ public:
void populateMTLRenderPassDescriptor(MTLRenderPassDescriptor* mtlRPDesc,
MVKFramebuffer* framebuffer,
MVKVector<VkClearValue>& clearValues,
bool isRenderingEntireAttachment);
bool isRenderingEntireAttachment,
bool loadOverride = false);
/**
* Populates the specified vector with the attachments that need to be cleared
@ -111,7 +112,8 @@ public:
MVKRenderSubpass* subpass,
bool isRenderingEntireAttachment,
bool hasResolveAttachment,
bool isStencil);
bool isStencil,
bool loadOverride = false);
/** Returns whether this attachment should be cleared in the subpass. */
bool shouldUseClearAttachment(MVKRenderSubpass* subpass);

View File

@ -68,7 +68,8 @@ VkSampleCountFlagBits MVKRenderSubpass::getSampleCount() {
void MVKRenderSubpass::populateMTLRenderPassDescriptor(MTLRenderPassDescriptor* mtlRPDesc,
MVKFramebuffer* framebuffer,
MVKVector<VkClearValue>& clearValues,
bool isRenderingEntireAttachment) {
bool isRenderingEntireAttachment,
bool loadOverride) {
// Populate the Metal color attachments
uint32_t caCnt = getColorAttachmentCount();
for (uint32_t caIdx = 0; caIdx < caCnt; caIdx++) {
@ -89,7 +90,8 @@ void MVKRenderSubpass::populateMTLRenderPassDescriptor(MTLRenderPassDescriptor*
framebuffer->getAttachment(clrRPAttIdx)->populateMTLRenderPassAttachmentDescriptor(mtlColorAttDesc);
if (clrMVKRPAtt->populateMTLRenderPassAttachmentDescriptor(mtlColorAttDesc, this,
isRenderingEntireAttachment,
hasResolveAttachment, false)) {
hasResolveAttachment, false,
loadOverride)) {
mtlColorAttDesc.clearColor = mvkMTLClearColorFromVkClearValue(clearValues[clrRPAttIdx], clrMVKRPAtt->getFormat());
}
@ -110,8 +112,9 @@ void MVKRenderSubpass::populateMTLRenderPassDescriptor(MTLRenderPassDescriptor*
dsImage->populateMTLRenderPassAttachmentDescriptor(mtlDepthAttDesc);
if (dsMVKRPAtt->populateMTLRenderPassAttachmentDescriptor(mtlDepthAttDesc, this,
isRenderingEntireAttachment,
false, false)) {
mtlDepthAttDesc.clearDepth = mvkMTLClearDepthFromVkClearValue(clearValues[dsRPAttIdx]);
false, false,
loadOverride)) {
mtlDepthAttDesc.clearDepth = mvkMTLClearDepthFromVkClearValue(clearValues[dsRPAttIdx]);
}
}
if (mvkMTLPixelFormatIsStencilFormat(mtlDSFormat)) {
@ -119,7 +122,8 @@ void MVKRenderSubpass::populateMTLRenderPassDescriptor(MTLRenderPassDescriptor*
dsImage->populateMTLRenderPassAttachmentDescriptor(mtlStencilAttDesc);
if (dsMVKRPAtt->populateMTLRenderPassAttachmentDescriptor(mtlStencilAttDesc, this,
isRenderingEntireAttachment,
false, true)) {
false, true,
loadOverride)) {
mtlStencilAttDesc.clearStencil = mvkMTLClearStencilFromVkClearValue(clearValues[dsRPAttIdx]);
}
}
@ -252,13 +256,16 @@ bool MVKRenderPassAttachment::populateMTLRenderPassAttachmentDescriptor(MTLRende
MVKRenderSubpass* subpass,
bool isRenderingEntireAttachment,
bool hasResolveAttachment,
bool isStencil) {
bool isStencil,
bool loadOverride) {
bool willClear = false; // Assume the attachment won't be cleared
// Only allow clearing of entire attachment if we're actually rendering to the entire
// attachment AND we're in the first subpass.
if ( isRenderingEntireAttachment && (subpass->_subpassIndex == _firstUseSubpassIdx) ) {
if ( loadOverride ) {
mtlAttDesc.loadAction = MTLLoadActionLoad;
} else if ( isRenderingEntireAttachment && (subpass->_subpassIndex == _firstUseSubpassIdx) ) {
VkAttachmentLoadOp loadOp = isStencil ? _info.stencilLoadOp : _info.loadOp;
mtlAttDesc.loadAction = mvkMTLLoadActionFromVkAttachmentLoadOp(loadOp);
willClear = (_info.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR);