aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/vk/GrVkGpu.cpp
diff options
context:
space:
mode:
authorGravatar egdaniel <egdaniel@google.com>2016-03-17 11:35:45 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-03-17 11:35:45 -0700
commit0e1853c89615d14d0d03c87c7e0c604e5285cc54 (patch)
treee0ffc4b77a62d396b548f6e45fc8b335d3e6ecc1 /src/gpu/vk/GrVkGpu.cpp
parent852f15da7ceb53cfb49b9f728baa6dbc53b27694 (diff)
Update how we send draws to gpu backend to reduce state setting.
The main change here is that we pull primitive type off of the vertices, we set the gpu state on gpu once per pipeline/prim proc draw batch, and we create the ProgramDescriptor only for the Cache/ProgramBuilder. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1806983002 Review URL: https://codereview.chromium.org/1806983002
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);