void GrVkGpuCommandBuffer::onClearStencilClip(GrRenderTarget* target, const GrFixedClip& clip, bool insideStencilMask) { SkASSERT(target); SkASSERT(!clip.hasWindowRectangles()); GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(target); GrStencilAttachment* sb = target->renderTargetPriv().getStencilAttachment(); // this should only be called internally when we know we have a // stencil buffer. SkASSERT(sb); int stencilBitCount = sb->bits(); // The contract with the callers does not guarantee that we preserve all bits in the stencil // during this clear. Thus we will clear the entire stencil to the desired value. VkClearDepthStencilValue vkStencilColor; memset(&vkStencilColor, 0, sizeof(VkClearDepthStencilValue)); if (insideStencilMask) { vkStencilColor.stencil = (1 << (stencilBitCount - 1)); } else { vkStencilColor.stencil = 0; } VkClearRect clearRect; // Flip rect if necessary SkIRect vkRect; if (!clip.scissorEnabled()) { vkRect.setXYWH(0, 0, vkRT->width(), vkRT->height()); } else if (kBottomLeft_GrSurfaceOrigin != vkRT->origin()) { vkRect = clip.scissorRect(); } else { const SkIRect& scissor = clip.scissorRect(); vkRect.setLTRB(scissor.fLeft, vkRT->height() - scissor.fBottom, scissor.fRight, vkRT->height() - scissor.fTop); } clearRect.rect.offset = { vkRect.fLeft, vkRect.fTop }; clearRect.rect.extent = { (uint32_t)vkRect.width(), (uint32_t)vkRect.height() }; clearRect.baseArrayLayer = 0; clearRect.layerCount = 1; uint32_t stencilIndex; SkAssertResult(fRenderPass->stencilAttachmentIndex(&stencilIndex)); VkClearAttachment attachment; attachment.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT; attachment.colorAttachment = 0; // this value shouldn't matter attachment.clearValue.depthStencil = vkStencilColor; fCommandBuffer->clearAttachments(fGpu, 1, &attachment, 1, &clearRect); fIsEmpty = false; }
void GrVkGpuCommandBuffer::onClear(GrRenderTarget* target, const GrFixedClip& clip, GrColor color) { // parent class should never let us get here with no RT SkASSERT(target); SkASSERT(!clip.hasWindowRectangles()); VkClearColorValue vkColor; GrColorToRGBAFloat(color, vkColor.float32); GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(target); if (fIsEmpty && !clip.scissorEnabled()) { // We will change the render pass to do a clear load instead GrVkRenderPass::LoadStoreOps vkColorOps(VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE); GrVkRenderPass::LoadStoreOps vkStencilOps(VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE); const GrVkRenderPass* oldRP = fRenderPass; const GrVkResourceProvider::CompatibleRPHandle& rpHandle = vkRT->compatibleRenderPassHandle(); if (rpHandle.isValid()) { fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle, vkColorOps, vkStencilOps); } else { fRenderPass = fGpu->resourceProvider().findRenderPass(*vkRT, vkColorOps, vkStencilOps); } SkASSERT(fRenderPass->isCompatible(*oldRP)); oldRP->unref(fGpu); GrColorToRGBAFloat(color, fColorClearValue.color.float32); fStartsWithClear = true; return; } // We always do a sub rect clear with clearAttachments since we are inside a render pass VkClearRect clearRect; // Flip rect if necessary SkIRect vkRect; if (!clip.scissorEnabled()) { vkRect.setXYWH(0, 0, vkRT->width(), vkRT->height()); } else if (kBottomLeft_GrSurfaceOrigin != vkRT->origin()) { vkRect = clip.scissorRect(); } else { const SkIRect& scissor = clip.scissorRect(); vkRect.setLTRB(scissor.fLeft, vkRT->height() - scissor.fBottom, scissor.fRight, vkRT->height() - scissor.fTop); } clearRect.rect.offset = { vkRect.fLeft, vkRect.fTop }; clearRect.rect.extent = { (uint32_t)vkRect.width(), (uint32_t)vkRect.height() }; clearRect.baseArrayLayer = 0; clearRect.layerCount = 1; uint32_t colorIndex; SkAssertResult(fRenderPass->colorAttachmentIndex(&colorIndex)); VkClearAttachment attachment; attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; attachment.colorAttachment = colorIndex; attachment.clearValue.color = vkColor; fCommandBuffer->clearAttachments(fGpu, 1, &attachment, 1, &clearRect); fIsEmpty = false; return; }