Merge pull request #569 from mbarriault/master
Fix tessellation pipeline re-clearing attachments.
This commit is contained in:
commit
c425602ee7
@ -194,7 +194,7 @@ void MVKCmdDraw::encode(MVKCommandEncoder* cmdEncoder) {
|
|||||||
threadsPerThreadgroup: MTLSizeMake(std::max(inControlPointCount, outControlPointCount), 1, 1)];
|
threadsPerThreadgroup: MTLSizeMake(std::max(inControlPointCount, outControlPointCount), 1, 1)];
|
||||||
// Running this stage prematurely ended the render pass, so we have to start it up again.
|
// 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.
|
// TODO: On iOS, maybe we could use a tile shader to avoid this.
|
||||||
cmdEncoder->beginMetalRenderPass();
|
cmdEncoder->beginMetalRenderPass(true);
|
||||||
break;
|
break;
|
||||||
case kMVKGraphicsStageRasterization:
|
case kMVKGraphicsStageRasterization:
|
||||||
if (pipeline->isTessellationPipeline()) {
|
if (pipeline->isTessellationPipeline()) {
|
||||||
@ -413,7 +413,7 @@ void MVKCmdDrawIndexed::encode(MVKCommandEncoder* cmdEncoder) {
|
|||||||
threadsPerThreadgroup: MTLSizeMake(std::max(inControlPointCount, outControlPointCount), 1, 1)];
|
threadsPerThreadgroup: MTLSizeMake(std::max(inControlPointCount, outControlPointCount), 1, 1)];
|
||||||
// Running this stage prematurely ended the render pass, so we have to start it up again.
|
// 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.
|
// TODO: On iOS, maybe we could use a tile shader to avoid this.
|
||||||
cmdEncoder->beginMetalRenderPass();
|
cmdEncoder->beginMetalRenderPass(true);
|
||||||
break;
|
break;
|
||||||
case kMVKGraphicsStageRasterization:
|
case kMVKGraphicsStageRasterization:
|
||||||
if (pipeline->isTessellationPipeline()) {
|
if (pipeline->isTessellationPipeline()) {
|
||||||
@ -663,7 +663,7 @@ void MVKCmdDrawIndirect::encode(MVKCommandEncoder* cmdEncoder) {
|
|||||||
mtlTCIndBuffOfst += sizeof(MTLDispatchThreadgroupsIndirectArguments);
|
mtlTCIndBuffOfst += sizeof(MTLDispatchThreadgroupsIndirectArguments);
|
||||||
// Running this stage prematurely ended the render pass, so we have to start it up again.
|
// 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.
|
// TODO: On iOS, maybe we could use a tile shader to avoid this.
|
||||||
cmdEncoder->beginMetalRenderPass();
|
cmdEncoder->beginMetalRenderPass(true);
|
||||||
break;
|
break;
|
||||||
case kMVKGraphicsStageRasterization:
|
case kMVKGraphicsStageRasterization:
|
||||||
if (pipeline->isTessellationPipeline()) {
|
if (pipeline->isTessellationPipeline()) {
|
||||||
@ -909,7 +909,7 @@ void MVKCmdDrawIndexedIndirect::encode(MVKCommandEncoder* cmdEncoder) {
|
|||||||
mtlTCIndBuffOfst += sizeof(MTLDispatchThreadgroupsIndirectArguments);
|
mtlTCIndBuffOfst += sizeof(MTLDispatchThreadgroupsIndirectArguments);
|
||||||
// Running this stage prematurely ended the render pass, so we have to start it up again.
|
// 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.
|
// TODO: On iOS, maybe we could use a tile shader to avoid this.
|
||||||
cmdEncoder->beginMetalRenderPass();
|
cmdEncoder->beginMetalRenderPass(true);
|
||||||
break;
|
break;
|
||||||
case kMVKGraphicsStageRasterization:
|
case kMVKGraphicsStageRasterization:
|
||||||
if (pipeline->isTessellationPipeline()) {
|
if (pipeline->isTessellationPipeline()) {
|
||||||
|
@ -246,7 +246,7 @@ public:
|
|||||||
void beginNextSubpass(VkSubpassContents renderpassContents);
|
void beginNextSubpass(VkSubpassContents renderpassContents);
|
||||||
|
|
||||||
/** Begins a Metal render pass for the current render subpass. */
|
/** 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. */
|
/** Returns the render subpass that is currently active. */
|
||||||
MVKRenderSubpass* getSubpass();
|
MVKRenderSubpass* getSubpass();
|
||||||
|
@ -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.
|
// 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();
|
endCurrentMetalEncoding();
|
||||||
|
|
||||||
MTLRenderPassDescriptor* mtlRPDesc = [MTLRenderPassDescriptor renderPassDescriptor];
|
MTLRenderPassDescriptor* mtlRPDesc = [MTLRenderPassDescriptor renderPassDescriptor];
|
||||||
getSubpass()->populateMTLRenderPassDescriptor(mtlRPDesc, _framebuffer, _clearValues, _isRenderingEntireAttachment);
|
getSubpass()->populateMTLRenderPassDescriptor(mtlRPDesc, _framebuffer, _clearValues, _isRenderingEntireAttachment, loadOverride);
|
||||||
mtlRPDesc.visibilityResultBuffer = _occlusionQueryState.getVisibilityResultMTLBuffer();
|
mtlRPDesc.visibilityResultBuffer = _occlusionQueryState.getVisibilityResultMTLBuffer();
|
||||||
|
|
||||||
if (_device->_pMetalFeatures->layeredRendering) {
|
if (_device->_pMetalFeatures->layeredRendering) {
|
||||||
|
@ -58,7 +58,8 @@ public:
|
|||||||
void populateMTLRenderPassDescriptor(MTLRenderPassDescriptor* mtlRPDesc,
|
void populateMTLRenderPassDescriptor(MTLRenderPassDescriptor* mtlRPDesc,
|
||||||
MVKFramebuffer* framebuffer,
|
MVKFramebuffer* framebuffer,
|
||||||
MVKVector<VkClearValue>& clearValues,
|
MVKVector<VkClearValue>& clearValues,
|
||||||
bool isRenderingEntireAttachment);
|
bool isRenderingEntireAttachment,
|
||||||
|
bool loadOverride = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Populates the specified vector with the attachments that need to be cleared
|
* Populates the specified vector with the attachments that need to be cleared
|
||||||
@ -111,7 +112,8 @@ public:
|
|||||||
MVKRenderSubpass* subpass,
|
MVKRenderSubpass* subpass,
|
||||||
bool isRenderingEntireAttachment,
|
bool isRenderingEntireAttachment,
|
||||||
bool hasResolveAttachment,
|
bool hasResolveAttachment,
|
||||||
bool isStencil);
|
bool isStencil,
|
||||||
|
bool loadOverride = false);
|
||||||
|
|
||||||
/** Returns whether this attachment should be cleared in the subpass. */
|
/** Returns whether this attachment should be cleared in the subpass. */
|
||||||
bool shouldUseClearAttachment(MVKRenderSubpass* subpass);
|
bool shouldUseClearAttachment(MVKRenderSubpass* subpass);
|
||||||
|
@ -68,7 +68,8 @@ VkSampleCountFlagBits MVKRenderSubpass::getSampleCount() {
|
|||||||
void MVKRenderSubpass::populateMTLRenderPassDescriptor(MTLRenderPassDescriptor* mtlRPDesc,
|
void MVKRenderSubpass::populateMTLRenderPassDescriptor(MTLRenderPassDescriptor* mtlRPDesc,
|
||||||
MVKFramebuffer* framebuffer,
|
MVKFramebuffer* framebuffer,
|
||||||
MVKVector<VkClearValue>& clearValues,
|
MVKVector<VkClearValue>& clearValues,
|
||||||
bool isRenderingEntireAttachment) {
|
bool isRenderingEntireAttachment,
|
||||||
|
bool loadOverride) {
|
||||||
// Populate the Metal color attachments
|
// Populate the Metal color attachments
|
||||||
uint32_t caCnt = getColorAttachmentCount();
|
uint32_t caCnt = getColorAttachmentCount();
|
||||||
for (uint32_t caIdx = 0; caIdx < caCnt; caIdx++) {
|
for (uint32_t caIdx = 0; caIdx < caCnt; caIdx++) {
|
||||||
@ -89,7 +90,8 @@ void MVKRenderSubpass::populateMTLRenderPassDescriptor(MTLRenderPassDescriptor*
|
|||||||
framebuffer->getAttachment(clrRPAttIdx)->populateMTLRenderPassAttachmentDescriptor(mtlColorAttDesc);
|
framebuffer->getAttachment(clrRPAttIdx)->populateMTLRenderPassAttachmentDescriptor(mtlColorAttDesc);
|
||||||
if (clrMVKRPAtt->populateMTLRenderPassAttachmentDescriptor(mtlColorAttDesc, this,
|
if (clrMVKRPAtt->populateMTLRenderPassAttachmentDescriptor(mtlColorAttDesc, this,
|
||||||
isRenderingEntireAttachment,
|
isRenderingEntireAttachment,
|
||||||
hasResolveAttachment, false)) {
|
hasResolveAttachment, false,
|
||||||
|
loadOverride)) {
|
||||||
mtlColorAttDesc.clearColor = mvkMTLClearColorFromVkClearValue(clearValues[clrRPAttIdx], clrMVKRPAtt->getFormat());
|
mtlColorAttDesc.clearColor = mvkMTLClearColorFromVkClearValue(clearValues[clrRPAttIdx], clrMVKRPAtt->getFormat());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +112,8 @@ void MVKRenderSubpass::populateMTLRenderPassDescriptor(MTLRenderPassDescriptor*
|
|||||||
dsImage->populateMTLRenderPassAttachmentDescriptor(mtlDepthAttDesc);
|
dsImage->populateMTLRenderPassAttachmentDescriptor(mtlDepthAttDesc);
|
||||||
if (dsMVKRPAtt->populateMTLRenderPassAttachmentDescriptor(mtlDepthAttDesc, this,
|
if (dsMVKRPAtt->populateMTLRenderPassAttachmentDescriptor(mtlDepthAttDesc, this,
|
||||||
isRenderingEntireAttachment,
|
isRenderingEntireAttachment,
|
||||||
false, false)) {
|
false, false,
|
||||||
|
loadOverride)) {
|
||||||
mtlDepthAttDesc.clearDepth = mvkMTLClearDepthFromVkClearValue(clearValues[dsRPAttIdx]);
|
mtlDepthAttDesc.clearDepth = mvkMTLClearDepthFromVkClearValue(clearValues[dsRPAttIdx]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -119,7 +122,8 @@ void MVKRenderSubpass::populateMTLRenderPassDescriptor(MTLRenderPassDescriptor*
|
|||||||
dsImage->populateMTLRenderPassAttachmentDescriptor(mtlStencilAttDesc);
|
dsImage->populateMTLRenderPassAttachmentDescriptor(mtlStencilAttDesc);
|
||||||
if (dsMVKRPAtt->populateMTLRenderPassAttachmentDescriptor(mtlStencilAttDesc, this,
|
if (dsMVKRPAtt->populateMTLRenderPassAttachmentDescriptor(mtlStencilAttDesc, this,
|
||||||
isRenderingEntireAttachment,
|
isRenderingEntireAttachment,
|
||||||
false, true)) {
|
false, true,
|
||||||
|
loadOverride)) {
|
||||||
mtlStencilAttDesc.clearStencil = mvkMTLClearStencilFromVkClearValue(clearValues[dsRPAttIdx]);
|
mtlStencilAttDesc.clearStencil = mvkMTLClearStencilFromVkClearValue(clearValues[dsRPAttIdx]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -252,13 +256,16 @@ bool MVKRenderPassAttachment::populateMTLRenderPassAttachmentDescriptor(MTLRende
|
|||||||
MVKRenderSubpass* subpass,
|
MVKRenderSubpass* subpass,
|
||||||
bool isRenderingEntireAttachment,
|
bool isRenderingEntireAttachment,
|
||||||
bool hasResolveAttachment,
|
bool hasResolveAttachment,
|
||||||
bool isStencil) {
|
bool isStencil,
|
||||||
|
bool loadOverride) {
|
||||||
|
|
||||||
bool willClear = false; // Assume the attachment won't be cleared
|
bool willClear = false; // Assume the attachment won't be cleared
|
||||||
|
|
||||||
// Only allow clearing of entire attachment if we're actually rendering to the entire
|
// Only allow clearing of entire attachment if we're actually rendering to the entire
|
||||||
// attachment AND we're in the first subpass.
|
// 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;
|
VkAttachmentLoadOp loadOp = isStencil ? _info.stencilLoadOp : _info.loadOp;
|
||||||
mtlAttDesc.loadAction = mvkMTLLoadActionFromVkAttachmentLoadOp(loadOp);
|
mtlAttDesc.loadAction = mvkMTLLoadActionFromVkAttachmentLoadOp(loadOp);
|
||||||
willClear = (_info.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR);
|
willClear = (_info.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user