aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/vk/GrVkGpu.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu/vk/GrVkGpu.cpp')
-rw-r--r--src/gpu/vk/GrVkGpu.cpp130
1 files changed, 92 insertions, 38 deletions
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index fce7173eff..180ba3be66 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);