Index: src/gpu/vk/GrVkGpu.cpp |
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp |
index fce7173effeabaa33a2f49f0ff9e687fa3ffa26f..180ba3be66b85686d0a3c2e59b32b4f1c9af3e5f 100644 |
--- a/src/gpu/vk/GrVkGpu.cpp |
+++ b/src/gpu/vk/GrVkGpu.cpp |
@@ -10,11 +10,11 @@ |
#include "GrContextOptions.h" |
#include "GrGeometryProcessor.h" |
#include "GrGpuResourceCacheAccess.h" |
+#include "GrMesh.h" |
#include "GrPipeline.h" |
#include "GrRenderTargetPriv.h" |
#include "GrSurfacePriv.h" |
#include "GrTexturePriv.h" |
-#include "GrVertices.h" |
#include "GrVkCommandBuffer.h" |
#include "GrVkImage.h" |
@@ -650,9 +650,9 @@ GrRenderTarget* GrVkGpu::onWrapBackendRenderTarget(const GrBackendRenderTargetDe |
//////////////////////////////////////////////////////////////////////////////// |
void GrVkGpu::bindGeometry(const GrPrimitiveProcessor& primProc, |
- const GrNonInstancedVertices& vertices) { |
+ const GrNonInstancedMesh& mesh) { |
GrVkVertexBuffer* vbuf; |
- vbuf = (GrVkVertexBuffer*)vertices.vertexBuffer(); |
+ vbuf = (GrVkVertexBuffer*)mesh.vertexBuffer(); |
SkASSERT(vbuf); |
SkASSERT(!vbuf->isMapped()); |
@@ -665,8 +665,8 @@ void GrVkGpu::bindGeometry(const GrPrimitiveProcessor& primProc, |
fCurrentCmdBuffer->bindVertexBuffer(this, vbuf); |
- if (vertices.isIndexed()) { |
- GrVkIndexBuffer* ibuf = (GrVkIndexBuffer*)vertices.indexBuffer(); |
+ if (mesh.isIndexed()) { |
+ GrVkIndexBuffer* ibuf = (GrVkIndexBuffer*)mesh.indexBuffer(); |
SkASSERT(ibuf); |
SkASSERT(!ibuf->isMapped()); |
@@ -681,14 +681,6 @@ void GrVkGpu::bindGeometry(const GrPrimitiveProcessor& primProc, |
} |
} |
-void GrVkGpu::buildProgramDesc(GrProgramDesc* desc, |
- const GrPrimitiveProcessor& primProc, |
- const GrPipeline& pipeline) const { |
- if (!GrVkProgramDescBuilder::Build(desc, primProc, pipeline, *this->vkCaps().glslCaps())) { |
- SkDEBUGFAIL("Failed to generate GL program descriptor"); |
- } |
-} |
- |
//////////////////////////////////////////////////////////////////////////////// |
GrStencilAttachment* GrVkGpu::createStencilAttachmentForRenderTarget(const GrRenderTarget* rt, |
@@ -1323,27 +1315,51 @@ bool GrVkGpu::onReadPixels(GrSurface* surface, |
return true; |
} |
-void GrVkGpu::onDraw(const DrawArgs& args, const GrNonInstancedVertices& vertices) { |
- GrRenderTarget* rt = args.fPipeline->getRenderTarget(); |
- GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(rt); |
- const GrVkRenderPass* renderPass = vkRT->simpleRenderPass(); |
- SkASSERT(renderPass); |
- |
- GrVkProgram* program = GrVkProgramBuilder::CreateProgram(this, args, |
- vertices.primitiveType(), |
- *renderPass); |
+bool GrVkGpu::prepareDrawState(const GrPipeline& pipeline, |
+ const GrPrimitiveProcessor& primProc, |
+ GrPrimitiveType primitiveType, |
+ const GrVkRenderPass& renderPass, |
+ GrVkProgram** program) { |
+ // Get GrVkProgramDesc |
+ GrVkProgramDesc desc; |
+ if (!GrVkProgramDescBuilder::Build(&desc, primProc, pipeline, *this->vkCaps().glslCaps())) { |
+ GrCapsDebugf(this->caps(), "Failed to vk program descriptor!\n"); |
+ return false; |
+ } |
+ *program = GrVkProgramBuilder::CreateProgram(this, |
+ pipeline, |
+ primProc, |
+ primitiveType, |
+ desc, |
+ renderPass); |
if (!program) { |
- return; |
+ return false; |
} |
- program->setData(this, *args.fPrimitiveProcessor, *args.fPipeline); |
+ (*program)->setData(this, primProc, pipeline); |
- fCurrentCmdBuffer->beginRenderPass(this, renderPass, *vkRT); |
+ (*program)->bind(this, fCurrentCmdBuffer); |
+ return true; |
+} |
- program->bind(this, fCurrentCmdBuffer); |
+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); |
- this->bindGeometry(*args.fPrimitiveProcessor, vertices); |
+ GrVkProgram* program = nullptr; |
+ GrPrimitiveType primitiveType = meshes[0].primitiveType(); |
+ if (!this->prepareDrawState(pipeline, primProc, primitiveType, *renderPass, &program)) { |
+ return; |
+ } |
// Change layout of our render target so it can be used as the color attachment |
VkImageLayout layout = vkRT->currentLayout(); |
@@ -1362,13 +1378,13 @@ void GrVkGpu::onDraw(const DrawArgs& args, const GrNonInstancedVertices& vertice |
false); |
// If we are using a stencil attachment we also need to update its layout |
- if (!args.fPipeline->getStencil().isDisabled()) { |
+ if (!pipeline.getStencil().isDisabled()) { |
GrStencilAttachment* stencil = vkRT->renderTargetPriv().getStencilAttachment(); |
GrVkStencilAttachment* vkStencil = (GrVkStencilAttachment*)stencil; |
VkImageLayout origDstLayout = vkStencil->currentLayout(); |
VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(origDstLayout); |
VkAccessFlags dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | |
- VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; |
+ VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; |
VkPipelineStageFlags srcStageMask = |
GrVkMemory::LayoutToPipelineStageFlags(origDstLayout); |
VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; |
@@ -1381,15 +1397,53 @@ void GrVkGpu::onDraw(const DrawArgs& args, const GrNonInstancedVertices& vertice |
false); |
} |
- if (vertices.isIndexed()) { |
- fCurrentCmdBuffer->drawIndexed(this, |
- vertices.indexCount(), |
- 1, |
- vertices.startIndex(), |
- vertices.startVertex(), |
- 0); |
- } else { |
- fCurrentCmdBuffer->draw(this, vertices.vertexCount(), 1, vertices.startVertex(), 0); |
+ fCurrentCmdBuffer->beginRenderPass(this, renderPass, *vkRT); |
+ |
+ for (int i = 0; i < meshCount; ++i) { |
+ if (GrXferBarrierType barrierType = pipeline.xferBarrierType(*this->caps())) { |
+ this->xferBarrier(pipeline.getRenderTarget(), barrierType); |
+ } |
+ |
+ 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 |
+ // program:setData but this will allow for quicker freeing of resources if the |
+ // program sits in a cache for a while. |
+ program->freeTempResources(this); |
+ // This free will go away once we setup a program cache, and then the cache will be |
+ // responsible for call freeGpuResources. |
+ program->freeGPUResources(this); |
+ program->unref(); |
+ SkDEBUGCODE(program = nullptr); |
+ primitiveType = nonIdxMesh->primitiveType(); |
+ if (!this->prepareDrawState(pipeline, primProc, primitiveType, *renderPass, |
+ &program)) { |
+ return; |
+ } |
+ } |
+ SkASSERT(program); |
+ 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); |