diff options
author | 2016-06-23 08:37:05 -0700 | |
---|---|---|
committer | 2016-06-23 08:37:06 -0700 | |
commit | 9cb6340a62a5d748e4189d50e51fa527c8c80c03 (patch) | |
tree | 340b581c1463f7983d3aaccea22c2dbf73e49db0 /src/gpu/vk | |
parent | de8ae904789ed2fb617134564630d0a97edc69d1 (diff) |
Start using GrGpuCommandBuffer in GrDrawTarget.
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2052263003
Review-Url: https://codereview.chromium.org/2078483002
Diffstat (limited to 'src/gpu/vk')
-rw-r--r-- | src/gpu/vk/GrVkCaps.cpp | 2 | ||||
-rw-r--r-- | src/gpu/vk/GrVkCommandBuffer.cpp | 56 | ||||
-rw-r--r-- | src/gpu/vk/GrVkCommandBuffer.h | 23 | ||||
-rw-r--r-- | src/gpu/vk/GrVkGpu.cpp | 325 | ||||
-rw-r--r-- | src/gpu/vk/GrVkGpu.h | 34 | ||||
-rw-r--r-- | src/gpu/vk/GrVkGpuCommandBuffer.cpp | 364 | ||||
-rw-r--r-- | src/gpu/vk/GrVkGpuCommandBuffer.h | 39 | ||||
-rw-r--r-- | src/gpu/vk/GrVkPipelineState.cpp | 13 | ||||
-rw-r--r-- | src/gpu/vk/GrVkResourceProvider.cpp | 2 |
9 files changed, 451 insertions, 407 deletions
diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp index 60934de2a7..833dc246c0 100644 --- a/src/gpu/vk/GrVkCaps.cpp +++ b/src/gpu/vk/GrVkCaps.cpp @@ -31,7 +31,7 @@ GrVkCaps::GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface* fCompressedTexSubImageSupport = false; //TODO: figure this out fOversizedStencilSupport = false; //TODO: figure this out - fUseDrawInsteadOfClear = false; //TODO: figure this out + fUseDrawInsteadOfClear = false; fMapBufferFlags = kNone_MapFlags; //TODO: figure this out fBufferMapThreshold = SK_MaxS32; //TODO: figure this out diff --git a/src/gpu/vk/GrVkCommandBuffer.cpp b/src/gpu/vk/GrVkCommandBuffer.cpp index 2b636edf20..4a469fe42e 100644 --- a/src/gpu/vk/GrVkCommandBuffer.cpp +++ b/src/gpu/vk/GrVkCommandBuffer.cpp @@ -15,12 +15,7 @@ #include "GrVkPipelineState.h" #include "GrVkTransferBuffer.h" #include "GrVkUtil.h" - - -GrVkCommandBuffer::~GrVkCommandBuffer() { - // Should have ended any render pass we're in the middle of - SkASSERT(!fActiveRenderPass); -} +#include "SkRect.h" void GrVkCommandBuffer::invalidateState() { fBoundVertexBuffer = VK_NULL_HANDLE; @@ -41,18 +36,14 @@ void GrVkCommandBuffer::invalidateState() { void GrVkCommandBuffer::freeGPUData(const GrVkGpu* gpu) const { SkASSERT(!fIsActive); - SkASSERT(!fActiveRenderPass); for (int i = 0; i < fTrackedResources.count(); ++i) { fTrackedResources[i]->unref(gpu); } - // Destroy the fence, if any - if (VK_NULL_HANDLE != fSubmitFence) { - GR_VK_CALL(gpu->vkInterface(), DestroyFence(gpu->device(), fSubmitFence, nullptr)); - } - GR_VK_CALL(gpu->vkInterface(), FreeCommandBuffers(gpu->device(), gpu->cmdPool(), 1, &fCmdBuffer)); + + this->onFreeGPUData(gpu); } void GrVkCommandBuffer::abandonSubResources() const { @@ -240,6 +231,11 @@ void GrVkCommandBuffer::setBlendConstants(const GrVkGpu* gpu, /////////////////////////////////////////////////////////////////////////////// // PrimaryCommandBuffer //////////////////////////////////////////////////////////////////////////////// +GrVkPrimaryCommandBuffer::~GrVkPrimaryCommandBuffer() { + // Should have ended any render pass we're in the middle of + SkASSERT(!fActiveRenderPass); +} + GrVkPrimaryCommandBuffer* GrVkPrimaryCommandBuffer::Create(const GrVkGpu* gpu, VkCommandPool cmdPool) { const VkCommandBufferAllocateInfo cmdInfo = { @@ -283,13 +279,33 @@ void GrVkPrimaryCommandBuffer::end(const GrVkGpu* gpu) { } void GrVkPrimaryCommandBuffer::beginRenderPass(const GrVkGpu* gpu, - const GrVkRenderPass* renderPass, - const GrVkRenderTarget& target) { + const GrVkRenderPass* renderPass, + uint32_t clearCount, + const VkClearValue* clearValues, + const GrVkRenderTarget& target, + const SkIRect& bounds, + bool forSecondaryCB) { SkASSERT(fIsActive); SkASSERT(!fActiveRenderPass); + SkASSERT(renderPass->isCompatible(target)); + VkRenderPassBeginInfo beginInfo; - VkSubpassContents contents; - renderPass->getBeginInfo(target, &beginInfo, &contents); + VkRect2D renderArea; + renderArea.offset = { bounds.fLeft , bounds.fTop }; + renderArea.extent = { (uint32_t)bounds.width(), (uint32_t)bounds.height() }; + + memset(&beginInfo, 0, sizeof(VkRenderPassBeginInfo)); + beginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + beginInfo.pNext = nullptr; + beginInfo.renderPass = renderPass->vkRenderPass(); + beginInfo.framebuffer = target.framebuffer()->framebuffer(); + beginInfo.renderArea = renderArea; + beginInfo.clearValueCount = clearCount; + beginInfo.pClearValues = clearValues; + + VkSubpassContents contents = forSecondaryCB ? VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS + : VK_SUBPASS_CONTENTS_INLINE; + GR_VK_CALL(gpu->vkInterface(), CmdBeginRenderPass(fCmdBuffer, &beginInfo, contents)); fActiveRenderPass = renderPass; this->addResource(renderPass); @@ -491,6 +507,14 @@ void GrVkPrimaryCommandBuffer::clearDepthStencilImage(const GrVkGpu* gpu, subRanges)); } +void GrVkPrimaryCommandBuffer::onFreeGPUData(const GrVkGpu* gpu) const { + SkASSERT(!fActiveRenderPass); + // Destroy the fence, if any + if (VK_NULL_HANDLE != fSubmitFence) { + GR_VK_CALL(gpu->vkInterface(), DestroyFence(gpu->device(), fSubmitFence, nullptr)); + } +} + /////////////////////////////////////////////////////////////////////////////// // SecondaryCommandBuffer //////////////////////////////////////////////////////////////////////////////// diff --git a/src/gpu/vk/GrVkCommandBuffer.h b/src/gpu/vk/GrVkCommandBuffer.h index 709e4c6044..87c33c057a 100644 --- a/src/gpu/vk/GrVkCommandBuffer.h +++ b/src/gpu/vk/GrVkCommandBuffer.h @@ -21,8 +21,6 @@ class GrVkTransferBuffer; class GrVkCommandBuffer : public GrVkResource { public: - ~GrVkCommandBuffer() override; - void invalidateState(); //////////////////////////////////////////////////////////////////////////// @@ -125,7 +123,6 @@ protected: , fIsActive(false) , fActiveRenderPass(rp) , fCmdBuffer(cmdBuffer) - , fSubmitFence(VK_NULL_HANDLE) , fBoundVertexBufferIsValid(false) , fBoundIndexBufferIsValid(false) { this->invalidateState(); @@ -142,12 +139,12 @@ protected: const GrVkRenderPass* fActiveRenderPass; VkCommandBuffer fCmdBuffer; - VkFence fSubmitFence; private: static const int kInitialTrackedResourcesCount = 32; void freeGPUData(const GrVkGpu* gpu) const override; + virtual void onFreeGPUData(const GrVkGpu* gpu) const = 0; void abandonSubResources() const override; VkBuffer fBoundVertexBuffer; @@ -166,6 +163,8 @@ class GrVkSecondaryCommandBuffer; class GrVkPrimaryCommandBuffer : public GrVkCommandBuffer { public: + ~GrVkPrimaryCommandBuffer() override; + static GrVkPrimaryCommandBuffer* Create(const GrVkGpu* gpu, VkCommandPool cmdPool); void begin(const GrVkGpu* gpu); @@ -175,7 +174,11 @@ public: // in the render pass. void beginRenderPass(const GrVkGpu* gpu, const GrVkRenderPass* renderPass, - const GrVkRenderTarget& target); + uint32_t clearCount, + const VkClearValue* clearValues, + const GrVkRenderTarget& target, + const SkIRect& bounds, + bool forSecondaryCB); void endRenderPass(const GrVkGpu* gpu); // Submits the SecondaryCommandBuffer into this command buffer. It is required that we are @@ -252,7 +255,13 @@ public: bool finished(const GrVkGpu* gpu) const; private: - explicit GrVkPrimaryCommandBuffer(VkCommandBuffer cmdBuffer) : INHERITED(cmdBuffer) {} + explicit GrVkPrimaryCommandBuffer(VkCommandBuffer cmdBuffer) + : INHERITED(cmdBuffer) + , fSubmitFence(VK_NULL_HANDLE) {} + + void onFreeGPUData(const GrVkGpu* gpu) const override; + + VkFence fSubmitFence; typedef GrVkCommandBuffer INHERITED; }; @@ -271,6 +280,8 @@ private: : INHERITED(cmdBuffer, compatibleRenderPass) { } + void onFreeGPUData(const GrVkGpu* gpu) const override {} + friend class GrVkPrimaryCommandBuffer; typedef GrVkCommandBuffer INHERITED; diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp index 05aa1de152..33437415a9 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 } + diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h index b076de29ff..a9470aee14 100644 --- a/src/gpu/vk/GrVkGpu.h +++ b/src/gpu/vk/GrVkGpu.h @@ -65,8 +65,6 @@ public: GrPixelConfig srcConfig, DrawPreference*, WritePixelTempDrawInfo*) override; - void discard(GrRenderTarget*) override {} - bool onCopySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect, @@ -92,11 +90,10 @@ public: void clearStencil(GrRenderTarget* target) override; - GrGpuCommandBuffer* createCommandBuffer(const GrRenderTarget& target, - GrGpuCommandBuffer::LoadAndStoreOp colorOp, - GrColor colorClear, - GrGpuCommandBuffer::LoadAndStoreOp stencilOp, - GrColor stencilClear) override; + GrGpuCommandBuffer* createCommandBuffer( + GrRenderTarget* target, + const GrGpuCommandBuffer::LoadAndStoreInfo& colorInfo, + const GrGpuCommandBuffer::LoadAndStoreInfo& stencilInfo) override; void drawDebugWireRect(GrRenderTarget*, const SkIRect&, GrColor) override {} @@ -117,7 +114,11 @@ public: return fCompiler; } - void submitSecondaryCommandBuffer(const GrVkSecondaryCommandBuffer*); + void submitSecondaryCommandBuffer(const GrVkSecondaryCommandBuffer*, + const GrVkRenderPass*, + const VkClearValue*, + GrVkRenderTarget*, + const SkIRect& bounds); void finishDrawTarget() override; @@ -165,15 +166,6 @@ private: GrBuffer* onCreateBuffer(size_t size, GrBufferType type, GrAccessPattern, const void* data) override; - void onClear(GrRenderTarget*, const SkIRect& rect, GrColor color) override; - - void onClearStencilClip(GrRenderTarget*, const SkIRect& rect, bool insideClip) override; - - void onDraw(const GrPipeline&, - const GrPrimitiveProcessor&, - const GrMesh*, - int meshCount) override; - bool onReadPixels(GrSurface* surface, int left, int top, int width, int height, GrPixelConfig, @@ -191,14 +183,6 @@ private: void onResolveRenderTarget(GrRenderTarget* target) override {} - sk_sp<GrVkPipelineState> prepareDrawState(const GrPipeline&, - const GrPrimitiveProcessor&, - GrPrimitiveType, - const GrVkRenderPass&); - - // Bind vertex and index buffers - void bindGeometry(const GrPrimitiveProcessor&, const GrNonInstancedMesh&); - // Ends and submits the current command buffer to the queue and then creates a new command // buffer and begins it. If sync is set to kForce_SyncQueue, the function will wait for all // work in the queue to finish before returning. diff --git a/src/gpu/vk/GrVkGpuCommandBuffer.cpp b/src/gpu/vk/GrVkGpuCommandBuffer.cpp index f6104a3308..f987231940 100644 --- a/src/gpu/vk/GrVkGpuCommandBuffer.cpp +++ b/src/gpu/vk/GrVkGpuCommandBuffer.cpp @@ -7,79 +7,85 @@ #include "GrVkGpuCommandBuffer.h" +#include "GrMesh.h" +#include "GrPipeline.h" +#include "GrRenderTargetPriv.h" +#include "GrTextureAccess.h" +#include "GrTexturePriv.h" #include "GrVkCommandBuffer.h" #include "GrVkGpu.h" +#include "GrVkPipeline.h" #include "GrVkRenderPass.h" #include "GrVkRenderTarget.h" #include "GrVkResourceProvider.h" +#include "GrVkTexture.h" -void get_vk_load_store_ops(GrGpuCommandBuffer::LoadAndStoreOp op, +void get_vk_load_store_ops(const GrGpuCommandBuffer::LoadAndStoreInfo& info, VkAttachmentLoadOp* loadOp, VkAttachmentStoreOp* storeOp) { - switch (op) { - case GrGpuCommandBuffer::kLoadAndStore_LoadAndStoreOp: + switch (info.fLoadOp) { + case GrGpuCommandBuffer::LoadOp::kLoad: *loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - *storeOp = VK_ATTACHMENT_STORE_OP_STORE; - break; - case GrGpuCommandBuffer::kLoadAndDiscard_LoadAndStoreOp: - *loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - *storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; break; - case GrGpuCommandBuffer::kClearAndStore_LoadAndStoreOp: + case GrGpuCommandBuffer::LoadOp::kClear: *loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - *storeOp = VK_ATTACHMENT_STORE_OP_STORE; break; - case GrGpuCommandBuffer::kClearAndDiscard_LoadAndStoreOp: - *loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - *storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - break; - case GrGpuCommandBuffer::kDiscardAndStore_LoadAndStoreOp: + case GrGpuCommandBuffer::LoadOp::kDiscard: *loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + break; + default: + SK_ABORT("Invalid LoadOp"); + *loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + } + + switch (info.fStoreOp) { + case GrGpuCommandBuffer::StoreOp::kStore: *storeOp = VK_ATTACHMENT_STORE_OP_STORE; break; - case GrGpuCommandBuffer::kDiscardAndDiscard_LoadAndStoreOp: - *loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + case GrGpuCommandBuffer::StoreOp::kDiscard: *storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; break; default: - SK_ABORT("Invalid LoadAndStoreOp"); - *loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + SK_ABORT("Invalid StoreOp"); *storeOp = VK_ATTACHMENT_STORE_OP_STORE; - break; } } GrVkGpuCommandBuffer::GrVkGpuCommandBuffer(GrVkGpu* gpu, - const GrVkRenderTarget& target, - LoadAndStoreOp colorOp, GrColor colorClear, - LoadAndStoreOp stencilOp, GrColor stencilClear) - : fGpu(gpu) { + GrVkRenderTarget* target, + const LoadAndStoreInfo& colorInfo, + const LoadAndStoreInfo& stencilInfo) + : fGpu(gpu) + , fRenderTarget(target) + , fIsEmpty(true) { VkAttachmentLoadOp vkLoadOp; VkAttachmentStoreOp vkStoreOp; - get_vk_load_store_ops(colorOp, &vkLoadOp, &vkStoreOp); + get_vk_load_store_ops(colorInfo, &vkLoadOp, &vkStoreOp); GrVkRenderPass::LoadStoreOps vkColorOps(vkLoadOp, vkStoreOp); - get_vk_load_store_ops(stencilOp, &vkLoadOp, &vkStoreOp); + get_vk_load_store_ops(stencilInfo, &vkLoadOp, &vkStoreOp); GrVkRenderPass::LoadStoreOps vkStencilOps(vkLoadOp, vkStoreOp); - + GrVkRenderPass::LoadStoreOps vkResolveOps(VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE); - const GrVkResourceProvider::CompatibleRPHandle& rpHandle = target.compatibleRenderPassHandle(); + const GrVkResourceProvider::CompatibleRPHandle& rpHandle = target->compatibleRenderPassHandle(); if (rpHandle.isValid()) { fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle, vkColorOps, vkResolveOps, vkStencilOps); } else { - fRenderPass = fGpu->resourceProvider().findRenderPass(target, + fRenderPass = fGpu->resourceProvider().findRenderPass(*target, vkColorOps, vkResolveOps, vkStencilOps); } + GrColorToRGBAFloat(colorInfo.fClearColor, fColorClearValue.color.float32); + fCommandBuffer = GrVkSecondaryCommandBuffer::Create(gpu, gpu->cmdPool(), fRenderPass); - fCommandBuffer->begin(gpu, target.framebuffer()); + fCommandBuffer->begin(gpu, target->framebuffer()); } GrVkGpuCommandBuffer::~GrVkGpuCommandBuffer() { @@ -87,11 +93,305 @@ GrVkGpuCommandBuffer::~GrVkGpuCommandBuffer() { fRenderPass->unref(fGpu); } +GrGpu* GrVkGpuCommandBuffer::gpu() { return fGpu; } + void GrVkGpuCommandBuffer::end() { fCommandBuffer->end(fGpu); } -void GrVkGpuCommandBuffer::submit() { - fGpu->submitSecondaryCommandBuffer(fCommandBuffer); +void GrVkGpuCommandBuffer::onSubmit(const SkIRect& bounds) { + // Change layout of our render target so it can be used as the color attachment + fRenderTarget->setImageLayout(fGpu, + 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 = fRenderTarget->renderTargetPriv().getStencilAttachment()) { + GrVkStencilAttachment* vkStencil = (GrVkStencilAttachment*)stencil; + vkStencil->setImageLayout(fGpu, + 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); + } + + for (int i = 0; i < fSampledImages.count(); ++i) { + fSampledImages[i]->setImageLayout(fGpu, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + VK_ACCESS_SHADER_READ_BIT, + VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, + false); + } + + fGpu->submitSecondaryCommandBuffer(fCommandBuffer, fRenderPass, &fColorClearValue, + fRenderTarget, bounds); +} + +void GrVkGpuCommandBuffer::onClearStencilClip(GrRenderTarget* target, + const SkIRect& rect, + bool insideClip) { + SkASSERT(target); + + 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 (insideClip) { + vkStencilColor.stencil = (1 << (stencilBitCount - 1)); + } else { + vkStencilColor.stencil = 0; + } + + 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; + + 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 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 (fIsEmpty) { + // 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); + GrVkRenderPass::LoadStoreOps vkResolveOps(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, + vkResolveOps, + vkStencilOps); + } else { + fRenderPass = fGpu->resourceProvider().findRenderPass(*vkRT, + vkColorOps, + vkResolveOps, + vkStencilOps); + } + + SkASSERT(fRenderPass->isCompatible(*oldRP)); + oldRP->unref(fGpu); + + GrColorToRGBAFloat(color, fColorClearValue.color.float32); + 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 = 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; + + 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; +} + +//////////////////////////////////////////////////////////////////////////////// + +void GrVkGpuCommandBuffer::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()); + + fCommandBuffer->bindVertexBuffer(fGpu, vbuf); + + if (mesh.isIndexed()) { + GrVkIndexBuffer* ibuf = (GrVkIndexBuffer*)mesh.indexBuffer(); + SkASSERT(ibuf); + SkASSERT(!ibuf->isMapped()); + + fCommandBuffer->bindIndexBuffer(fGpu, ibuf); + } +} + +sk_sp<GrVkPipelineState> GrVkGpuCommandBuffer::prepareDrawState( + const GrPipeline& pipeline, + const GrPrimitiveProcessor& primProc, + GrPrimitiveType primitiveType, + const GrVkRenderPass& renderPass) { + sk_sp<GrVkPipelineState> pipelineState = + fGpu->resourceProvider().findOrCreateCompatiblePipelineState(pipeline, + primProc, + primitiveType, + renderPass); + if (!pipelineState) { + return pipelineState; + } + + pipelineState->setData(fGpu, primProc, pipeline); + + pipelineState->bind(fGpu, fCommandBuffer); + + GrVkPipeline::SetDynamicState(fGpu, fCommandBuffer, pipeline); + + return pipelineState; +} + +static void append_sampled_images(const GrProcessor& processor, + const GrVkGpu* gpu, + SkTArray<GrVkImage*>* sampledImages) { + if (int numTextures = processor.numTextures()) { + GrVkImage** images = sampledImages->push_back_n(numTextures); + int i = 0; + do { + const GrTextureAccess& texAccess = processor.textureAccess(i); + GrVkTexture* vkTexture = static_cast<GrVkTexture*>(processor.texture(i)); + SkASSERT(vkTexture); + const GrTextureParams& params = texAccess.getParams(); + // Check if we need to regenerate any mip maps + if (GrTextureParams::kMipMap_FilterMode == params.filterMode()) { + if (vkTexture->texturePriv().mipMapsAreDirty()) { + gpu->generateMipmap(vkTexture); + vkTexture->texturePriv().dirtyMipMaps(false); + } + } + + images[i] = vkTexture; + } while (++i < numTextures); + + } +} + +void GrVkGpuCommandBuffer::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; + } + + append_sampled_images(primProc, fGpu, &fSampledImages); + for (int i = 0; i < pipeline.numFragmentProcessors(); ++i) { + append_sampled_images(pipeline.getFragmentProcessor(i), fGpu, &fSampledImages); + } + append_sampled_images(pipeline.getXferProcessor(), fGpu, &fSampledImages); + + 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(fGpu); + 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()) { + fCommandBuffer->drawIndexed(fGpu, + nonIdxMesh->indexCount(), + 1, + nonIdxMesh->startIndex(), + nonIdxMesh->startVertex(), + 0); + } else { + fCommandBuffer->draw(fGpu, + nonIdxMesh->vertexCount(), + 1, + nonIdxMesh->startVertex(), + 0); + } + fIsEmpty = false; + + fGpu->stats()->incNumDraws(); + } while ((nonIdxMesh = iter.next())); + } + + // 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(fGpu); } diff --git a/src/gpu/vk/GrVkGpuCommandBuffer.h b/src/gpu/vk/GrVkGpuCommandBuffer.h index b68aa0334c..2daa98ce10 100644 --- a/src/gpu/vk/GrVkGpuCommandBuffer.h +++ b/src/gpu/vk/GrVkGpuCommandBuffer.h @@ -11,8 +11,12 @@ #include "GrGpuCommandBuffer.h" #include "GrColor.h" +#include "GrTypes.h" +#include "GrVkPipelineState.h" +class GrNonInstancedMesh; class GrVkGpu; +class GrVkImage; class GrVkRenderPass; class GrVkRenderTarget; class GrVkSecondaryCommandBuffer; @@ -20,20 +24,47 @@ class GrVkSecondaryCommandBuffer; class GrVkGpuCommandBuffer : public GrGpuCommandBuffer { public: GrVkGpuCommandBuffer(GrVkGpu* gpu, - const GrVkRenderTarget&, - LoadAndStoreOp colorOp, GrColor colorClear, - LoadAndStoreOp stencilOp, GrColor stencilClear); + GrVkRenderTarget*, + const LoadAndStoreInfo& colorInfo, + const LoadAndStoreInfo& stencilInfo); virtual ~GrVkGpuCommandBuffer(); void end() override; - void submit() override; + void discard(GrRenderTarget* rt) override {} private: + GrGpu* gpu() override; + + void onSubmit(const SkIRect& bounds) override; + + // Bind vertex and index buffers + void bindGeometry(const GrPrimitiveProcessor&, const GrNonInstancedMesh&); + + sk_sp<GrVkPipelineState> prepareDrawState(const GrPipeline&, + const GrPrimitiveProcessor&, + GrPrimitiveType, + const GrVkRenderPass&); + + void onDraw(const GrPipeline& pipeline, + const GrPrimitiveProcessor& primProc, + const GrMesh* mesh, + int meshCount) override; + + void onClear(GrRenderTarget* rt, const SkIRect& rect, GrColor color) override; + + void onClearStencilClip(GrRenderTarget*, const SkIRect& rect, bool insideClip) override; + const GrVkRenderPass* fRenderPass; GrVkSecondaryCommandBuffer* fCommandBuffer; GrVkGpu* fGpu; + GrVkRenderTarget* fRenderTarget; + VkClearValue fColorClearValue; + + SkTArray<GrVkImage*> fSampledImages; + + bool fIsEmpty; typedef GrGpuCommandBuffer INHERITED; }; diff --git a/src/gpu/vk/GrVkPipelineState.cpp b/src/gpu/vk/GrVkPipelineState.cpp index f27916f714..8280e62c2a 100644 --- a/src/gpu/vk/GrVkPipelineState.cpp +++ b/src/gpu/vk/GrVkPipelineState.cpp @@ -294,12 +294,6 @@ void GrVkPipelineState::writeSamplers(GrVkGpu* gpu, const GrTextureParams& params = textureBindings[i]->getParams(); GrVkTexture* texture = static_cast<GrVkTexture*>(textureBindings[i]->getTexture()); - if (GrTextureParams::kMipMap_FilterMode == params.filterMode()) { - if (texture->texturePriv().mipMapsAreDirty()) { - gpu->generateMipmap(texture); - texture->texturePriv().dirtyMipMaps(false); - } - } fSamplers.push(gpu->resourceProvider().findOrCreateCompatibleSampler(params, texture->texturePriv().maxMipMapLevel())); @@ -312,13 +306,6 @@ void GrVkPipelineState::writeSamplers(GrVkGpu* gpu, textureView->ref(); fTextureViews.push(textureView); - // Change texture layout so it can be read in shader - texture->setImageLayout(gpu, - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - VK_ACCESS_SHADER_READ_BIT, - VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, - false); - VkDescriptorImageInfo imageInfo; memset(&imageInfo, 0, sizeof(VkDescriptorImageInfo)); imageInfo.sampler = fSamplers[i]->sampler(); diff --git a/src/gpu/vk/GrVkResourceProvider.cpp b/src/gpu/vk/GrVkResourceProvider.cpp index a632be44e2..31d5568b60 100644 --- a/src/gpu/vk/GrVkResourceProvider.cpp +++ b/src/gpu/vk/GrVkResourceProvider.cpp @@ -339,7 +339,7 @@ GrVkRenderPass* GrVkResourceProvider::CompatibleRenderPassSet::getRenderPass( return fRenderPasses[idx]; } } - GrVkRenderPass* renderPass = fRenderPasses.push_back(); + GrVkRenderPass* renderPass = fRenderPasses.emplace_back(new GrVkRenderPass()); renderPass->init(gpu, *this->getCompatibleRenderPass(), colorOps, resolveOps, stencilOps); fLastReturnedIndex = fRenderPasses.count() - 1; return renderPass; |