| Index: src/gpu/vk/GrVkGpu.cpp
|
| diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
|
| index 05aa1de152f160518d01fc7e3dc87115c8180e33..33437415a9146f9d373883428d1e8d4fb114043c 100644
|
| --- a/src/gpu/vk/GrVkGpu.cpp
|
| +++ b/src/gpu/vk/GrVkGpu.cpp
|
| @@ -174,13 +174,12 @@ GrVkGpu::~GrVkGpu() {
|
|
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| -GrGpuCommandBuffer* GrVkGpu::createCommandBuffer(const GrRenderTarget& target,
|
| - GrGpuCommandBuffer::LoadAndStoreOp colorOp,
|
| - GrColor colorClear,
|
| - GrGpuCommandBuffer::LoadAndStoreOp stencilOp,
|
| - GrColor stencilClear) {
|
| - const GrVkRenderTarget& vkRT = static_cast<const GrVkRenderTarget&>(target);
|
| - return new GrVkGpuCommandBuffer(this, vkRT, colorOp, colorClear, stencilOp, stencilClear);
|
| +GrGpuCommandBuffer* GrVkGpu::createCommandBuffer(
|
| + GrRenderTarget* target,
|
| + const GrGpuCommandBuffer::LoadAndStoreInfo& colorInfo,
|
| + const GrGpuCommandBuffer::LoadAndStoreInfo& stencilInfo) {
|
| + GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(target);
|
| + return new GrVkGpuCommandBuffer(this, vkRT, colorInfo, stencilInfo);
|
| }
|
|
|
| void GrVkGpu::submitCommandBuffer(SyncQueue sync) {
|
| @@ -819,31 +818,6 @@ void GrVkGpu::generateMipmap(GrVkTexture* tex) const {
|
| oldResource->unref(this);
|
| }
|
|
|
| -
|
| -////////////////////////////////////////////////////////////////////////////////
|
| -
|
| -void GrVkGpu::bindGeometry(const GrPrimitiveProcessor& primProc,
|
| - const GrNonInstancedMesh& mesh) {
|
| - // There is no need to put any memory barriers to make sure host writes have finished here.
|
| - // When a command buffer is submitted to a queue, there is an implicit memory barrier that
|
| - // occurs for all host writes. Additionally, BufferMemoryBarriers are not allowed inside of
|
| - // an active RenderPass.
|
| - GrVkVertexBuffer* vbuf;
|
| - vbuf = (GrVkVertexBuffer*)mesh.vertexBuffer();
|
| - SkASSERT(vbuf);
|
| - SkASSERT(!vbuf->isMapped());
|
| -
|
| - fCurrentCmdBuffer->bindVertexBuffer(this, vbuf);
|
| -
|
| - if (mesh.isIndexed()) {
|
| - GrVkIndexBuffer* ibuf = (GrVkIndexBuffer*)mesh.indexBuffer();
|
| - SkASSERT(ibuf);
|
| - SkASSERT(!ibuf->isMapped());
|
| -
|
| - fCurrentCmdBuffer->bindIndexBuffer(this, ibuf);
|
| - }
|
| -}
|
| -
|
| ////////////////////////////////////////////////////////////////////////////////
|
|
|
| GrStencilAttachment* GrVkGpu::createStencilAttachmentForRenderTarget(const GrRenderTarget* rt,
|
| @@ -1087,157 +1061,6 @@ void GrVkGpu::clearStencil(GrRenderTarget* target) {
|
| fCurrentCmdBuffer->clearDepthStencilImage(this, vkStencil, &vkStencilColor, 1, &subRange);
|
| }
|
|
|
| -void GrVkGpu::onClearStencilClip(GrRenderTarget* target, const SkIRect& rect, bool insideClip) {
|
| - SkASSERT(target);
|
| -
|
| - GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(target);
|
| - GrStencilAttachment* sb = target->renderTargetPriv().getStencilAttachment();
|
| - GrVkStencilAttachment* vkStencil = (GrVkStencilAttachment*)sb;
|
| -
|
| - // 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 (insideClip) {
|
| - vkStencilColor.stencil = (1 << (stencilBitCount - 1));
|
| - } else {
|
| - vkStencilColor.stencil = 0;
|
| - }
|
| -
|
| - vkStencil->setImageLayout(this,
|
| - VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
| - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
| - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
| - false);
|
| -
|
| - // Change layout of our render target so it can be used as the color attachment. This is what
|
| - // the render pass expects when it begins.
|
| - vkRT->setImageLayout(this,
|
| - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
| - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
| - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
| - false);
|
| -
|
| - VkClearRect clearRect;
|
| - // Flip rect if necessary
|
| - SkIRect vkRect = rect;
|
| -
|
| - if (kBottomLeft_GrSurfaceOrigin == vkRT->origin()) {
|
| - vkRect.fTop = vkRT->height() - rect.fBottom;
|
| - vkRect.fBottom = vkRT->height() - rect.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;
|
| -
|
| - const GrVkRenderPass* renderPass = vkRT->simpleRenderPass();
|
| - SkASSERT(renderPass);
|
| - fCurrentCmdBuffer->beginRenderPass(this, renderPass, *vkRT);
|
| -
|
| - uint32_t stencilIndex;
|
| - SkAssertResult(renderPass->stencilAttachmentIndex(&stencilIndex));
|
| -
|
| - VkClearAttachment attachment;
|
| - attachment.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
|
| - attachment.colorAttachment = 0; // this value shouldn't matter
|
| - attachment.clearValue.depthStencil = vkStencilColor;
|
| -
|
| - fCurrentCmdBuffer->clearAttachments(this, 1, &attachment, 1, &clearRect);
|
| - fCurrentCmdBuffer->endRenderPass(this);
|
| -
|
| - return;
|
| -}
|
| -
|
| -void GrVkGpu::onClear(GrRenderTarget* target, const SkIRect& rect, GrColor color) {
|
| - // parent class should never let us get here with no RT
|
| - SkASSERT(target);
|
| -
|
| - VkClearColorValue vkColor;
|
| - GrColorToRGBAFloat(color, vkColor.float32);
|
| -
|
| - GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(target);
|
| -
|
| - if (rect.width() != target->width() || rect.height() != target->height()) {
|
| - vkRT->setImageLayout(this,
|
| - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
| - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
| - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
| - false);
|
| -
|
| - // If we are using a stencil attachment we also need to change its layout to what the render
|
| - // pass is expecting.
|
| - if (GrStencilAttachment* stencil = vkRT->renderTargetPriv().getStencilAttachment()) {
|
| - GrVkStencilAttachment* vkStencil = (GrVkStencilAttachment*)stencil;
|
| - vkStencil->setImageLayout(this,
|
| - VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
| - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
|
| - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
|
| - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
| - false);
|
| - }
|
| -
|
| - VkClearRect clearRect;
|
| - // Flip rect if necessary
|
| - SkIRect vkRect = rect;
|
| - if (kBottomLeft_GrSurfaceOrigin == vkRT->origin()) {
|
| - vkRect.fTop = vkRT->height() - rect.fBottom;
|
| - vkRect.fBottom = vkRT->height() - rect.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;
|
| -
|
| - const GrVkRenderPass* renderPass = vkRT->simpleRenderPass();
|
| - SkASSERT(renderPass);
|
| - fCurrentCmdBuffer->beginRenderPass(this, renderPass, *vkRT);
|
| -
|
| - uint32_t colorIndex;
|
| - SkAssertResult(renderPass->colorAttachmentIndex(&colorIndex));
|
| -
|
| - VkClearAttachment attachment;
|
| - attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
| - attachment.colorAttachment = colorIndex;
|
| - attachment.clearValue.color = vkColor;
|
| -
|
| - fCurrentCmdBuffer->clearAttachments(this, 1, &attachment, 1, &clearRect);
|
| - fCurrentCmdBuffer->endRenderPass(this);
|
| - return;
|
| - }
|
| -
|
| - vkRT->setImageLayout(this,
|
| - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
| - VK_ACCESS_TRANSFER_WRITE_BIT,
|
| - VK_PIPELINE_STAGE_TRANSFER_BIT,
|
| - false);
|
| -
|
| - VkImageSubresourceRange subRange;
|
| - memset(&subRange, 0, sizeof(VkImageSubresourceRange));
|
| - subRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
| - subRange.baseMipLevel = 0;
|
| - subRange.levelCount = 1;
|
| - subRange.baseArrayLayer = 0;
|
| - subRange.layerCount = 1;
|
| -
|
| - // In the future we may not actually be doing this type of clear at all. If we are inside a
|
| - // render pass or doing a non full clear then we will use CmdClearColorAttachment. The more
|
| - // common use case will be clearing an attachment at the start of a render pass, in which case
|
| - // we will use the clear load ops.
|
| - fCurrentCmdBuffer->clearColorImage(this,
|
| - vkRT,
|
| - &vkColor,
|
| - 1, &subRange);
|
| -}
|
| -
|
| inline bool can_copy_image(const GrSurface* dst,
|
| const GrSurface* src,
|
| const GrVkGpu* gpu) {
|
| @@ -1587,132 +1410,16 @@ bool GrVkGpu::onReadPixels(GrSurface* surface,
|
| return true;
|
| }
|
|
|
| -void GrVkGpu::submitSecondaryCommandBuffer(const GrVkSecondaryCommandBuffer* buffer) {
|
| +void GrVkGpu::submitSecondaryCommandBuffer(const GrVkSecondaryCommandBuffer* buffer,
|
| + const GrVkRenderPass* renderPass,
|
| + const VkClearValue* colorClear,
|
| + GrVkRenderTarget* target,
|
| + const SkIRect& bounds) {
|
| + // Currently it is fine for us to always pass in 1 for the clear count even if no attachment
|
| + // uses it. In the current state, we also only use the LOAD_OP_CLEAR for the color attachment
|
| + // which is always at the first attachment.
|
| + fCurrentCmdBuffer->beginRenderPass(this, renderPass, 1, colorClear, *target, bounds, true);
|
| fCurrentCmdBuffer->executeCommands(this, buffer);
|
| -}
|
| -
|
| -sk_sp<GrVkPipelineState> GrVkGpu::prepareDrawState(const GrPipeline& pipeline,
|
| - const GrPrimitiveProcessor& primProc,
|
| - GrPrimitiveType primitiveType,
|
| - const GrVkRenderPass& renderPass) {
|
| - sk_sp<GrVkPipelineState> pipelineState =
|
| - fResourceProvider.findOrCreateCompatiblePipelineState(pipeline,
|
| - primProc,
|
| - primitiveType,
|
| - renderPass);
|
| - if (!pipelineState) {
|
| - return pipelineState;
|
| - }
|
| -
|
| - pipelineState->setData(this, primProc, pipeline);
|
| -
|
| - pipelineState->bind(this, fCurrentCmdBuffer);
|
| -
|
| - GrVkPipeline::SetDynamicState(this, fCurrentCmdBuffer, pipeline);
|
| -
|
| - return pipelineState;
|
| -}
|
| -
|
| -void GrVkGpu::onDraw(const GrPipeline& pipeline,
|
| - const GrPrimitiveProcessor& primProc,
|
| - const GrMesh* meshes,
|
| - int meshCount) {
|
| - if (!meshCount) {
|
| - return;
|
| - }
|
| - GrRenderTarget* rt = pipeline.getRenderTarget();
|
| - GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(rt);
|
| - const GrVkRenderPass* renderPass = vkRT->simpleRenderPass();
|
| - SkASSERT(renderPass);
|
| -
|
| - GrPrimitiveType primitiveType = meshes[0].primitiveType();
|
| - sk_sp<GrVkPipelineState> pipelineState = this->prepareDrawState(pipeline,
|
| - primProc,
|
| - primitiveType,
|
| - *renderPass);
|
| - if (!pipelineState) {
|
| - return;
|
| - }
|
| -
|
| - // Change layout of our render target so it can be used as the color attachment
|
| - vkRT->setImageLayout(this,
|
| - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
| - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
| - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
| - false);
|
| -
|
| - // If we are using a stencil attachment we also need to update its layout
|
| - if (GrStencilAttachment* stencil = vkRT->renderTargetPriv().getStencilAttachment()) {
|
| - GrVkStencilAttachment* vkStencil = (GrVkStencilAttachment*)stencil;
|
| - vkStencil->setImageLayout(this,
|
| - VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
| - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
|
| - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
|
| - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
| - false);
|
| - }
|
| -
|
| - fCurrentCmdBuffer->beginRenderPass(this, renderPass, *vkRT);
|
| -
|
| - for (int i = 0; i < meshCount; ++i) {
|
| - const GrMesh& mesh = meshes[i];
|
| - GrMesh::Iterator iter;
|
| - const GrNonInstancedMesh* nonIdxMesh = iter.init(mesh);
|
| - do {
|
| - if (nonIdxMesh->primitiveType() != primitiveType) {
|
| - // Technically we don't have to call this here (since there is a safety check in
|
| - // pipelineState:setData but this will allow for quicker freeing of resources if the
|
| - // pipelineState sits in a cache for a while.
|
| - pipelineState->freeTempResources(this);
|
| - SkDEBUGCODE(pipelineState = nullptr);
|
| - primitiveType = nonIdxMesh->primitiveType();
|
| - pipelineState = this->prepareDrawState(pipeline,
|
| - primProc,
|
| - primitiveType,
|
| - *renderPass);
|
| - if (!pipelineState) {
|
| - return;
|
| - }
|
| - }
|
| - SkASSERT(pipelineState);
|
| - this->bindGeometry(primProc, *nonIdxMesh);
|
| -
|
| - if (nonIdxMesh->isIndexed()) {
|
| - fCurrentCmdBuffer->drawIndexed(this,
|
| - nonIdxMesh->indexCount(),
|
| - 1,
|
| - nonIdxMesh->startIndex(),
|
| - nonIdxMesh->startVertex(),
|
| - 0);
|
| - } else {
|
| - fCurrentCmdBuffer->draw(this,
|
| - nonIdxMesh->vertexCount(),
|
| - 1,
|
| - nonIdxMesh->startVertex(),
|
| - 0);
|
| - }
|
| -
|
| - fStats.incNumDraws();
|
| - } while ((nonIdxMesh = iter.next()));
|
| - }
|
| -
|
| fCurrentCmdBuffer->endRenderPass(this);
|
| -
|
| - // Technically we don't have to call this here (since there is a safety check in
|
| - // pipelineState:setData but this will allow for quicker freeing of resources if the
|
| - // pipelineState sits in a cache for a while.
|
| - pipelineState->freeTempResources(this);
|
| -
|
| -#if SWAP_PER_DRAW
|
| - glFlush();
|
| -#if defined(SK_BUILD_FOR_MAC)
|
| - aglSwapBuffers(aglGetCurrentContext());
|
| - int set_a_break_pt_here = 9;
|
| - aglSwapBuffers(aglGetCurrentContext());
|
| -#elif defined(SK_BUILD_FOR_WIN32)
|
| - SwapBuf();
|
| - int set_a_break_pt_here = 9;
|
| - SwapBuf();
|
| -#endif
|
| -#endif
|
| }
|
| +
|
|
|