Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: src/gpu/vk/GrVkGpu.cpp

Issue 1806983002: Update how we send draws to gpu backend to reduce state setting. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: nit Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/vk/GrVkGpu.h ('k') | src/gpu/vk/GrVkProgramBuilder.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2015 Google Inc. 2 * Copyright 2015 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "GrVkGpu.h" 8 #include "GrVkGpu.h"
9 9
10 #include "GrContextOptions.h" 10 #include "GrContextOptions.h"
11 #include "GrGeometryProcessor.h" 11 #include "GrGeometryProcessor.h"
12 #include "GrGpuResourceCacheAccess.h" 12 #include "GrGpuResourceCacheAccess.h"
13 #include "GrMesh.h"
13 #include "GrPipeline.h" 14 #include "GrPipeline.h"
14 #include "GrRenderTargetPriv.h" 15 #include "GrRenderTargetPriv.h"
15 #include "GrSurfacePriv.h" 16 #include "GrSurfacePriv.h"
16 #include "GrTexturePriv.h" 17 #include "GrTexturePriv.h"
17 #include "GrVertices.h"
18 18
19 #include "GrVkCommandBuffer.h" 19 #include "GrVkCommandBuffer.h"
20 #include "GrVkImage.h" 20 #include "GrVkImage.h"
21 #include "GrVkIndexBuffer.h" 21 #include "GrVkIndexBuffer.h"
22 #include "GrVkMemory.h" 22 #include "GrVkMemory.h"
23 #include "GrVkPipeline.h" 23 #include "GrVkPipeline.h"
24 #include "GrVkProgram.h" 24 #include "GrVkProgram.h"
25 #include "GrVkProgramBuilder.h" 25 #include "GrVkProgramBuilder.h"
26 #include "GrVkProgramDesc.h" 26 #include "GrVkProgramDesc.h"
27 #include "GrVkRenderPass.h" 27 #include "GrVkRenderPass.h"
(...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after
643 tgt->unref(); 643 tgt->unref();
644 return nullptr; 644 return nullptr;
645 } 645 }
646 } 646 }
647 return tgt; 647 return tgt;
648 } 648 }
649 649
650 //////////////////////////////////////////////////////////////////////////////// 650 ////////////////////////////////////////////////////////////////////////////////
651 651
652 void GrVkGpu::bindGeometry(const GrPrimitiveProcessor& primProc, 652 void GrVkGpu::bindGeometry(const GrPrimitiveProcessor& primProc,
653 const GrNonInstancedVertices& vertices) { 653 const GrNonInstancedMesh& mesh) {
654 GrVkVertexBuffer* vbuf; 654 GrVkVertexBuffer* vbuf;
655 vbuf = (GrVkVertexBuffer*)vertices.vertexBuffer(); 655 vbuf = (GrVkVertexBuffer*)mesh.vertexBuffer();
656 SkASSERT(vbuf); 656 SkASSERT(vbuf);
657 SkASSERT(!vbuf->isMapped()); 657 SkASSERT(!vbuf->isMapped());
658 658
659 vbuf->addMemoryBarrier(this, 659 vbuf->addMemoryBarrier(this,
660 VK_ACCESS_HOST_WRITE_BIT, 660 VK_ACCESS_HOST_WRITE_BIT,
661 VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, 661 VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT,
662 VK_PIPELINE_STAGE_HOST_BIT, 662 VK_PIPELINE_STAGE_HOST_BIT,
663 VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 663 VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
664 false); 664 false);
665 665
666 fCurrentCmdBuffer->bindVertexBuffer(this, vbuf); 666 fCurrentCmdBuffer->bindVertexBuffer(this, vbuf);
667 667
668 if (vertices.isIndexed()) { 668 if (mesh.isIndexed()) {
669 GrVkIndexBuffer* ibuf = (GrVkIndexBuffer*)vertices.indexBuffer(); 669 GrVkIndexBuffer* ibuf = (GrVkIndexBuffer*)mesh.indexBuffer();
670 SkASSERT(ibuf); 670 SkASSERT(ibuf);
671 SkASSERT(!ibuf->isMapped()); 671 SkASSERT(!ibuf->isMapped());
672 672
673 ibuf->addMemoryBarrier(this, 673 ibuf->addMemoryBarrier(this,
674 VK_ACCESS_HOST_WRITE_BIT, 674 VK_ACCESS_HOST_WRITE_BIT,
675 VK_ACCESS_INDEX_READ_BIT, 675 VK_ACCESS_INDEX_READ_BIT,
676 VK_PIPELINE_STAGE_HOST_BIT, 676 VK_PIPELINE_STAGE_HOST_BIT,
677 VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 677 VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
678 false); 678 false);
679 679
680 fCurrentCmdBuffer->bindIndexBuffer(this, ibuf); 680 fCurrentCmdBuffer->bindIndexBuffer(this, ibuf);
681 } 681 }
682 } 682 }
683 683
684 void GrVkGpu::buildProgramDesc(GrProgramDesc* desc,
685 const GrPrimitiveProcessor& primProc,
686 const GrPipeline& pipeline) const {
687 if (!GrVkProgramDescBuilder::Build(desc, primProc, pipeline, *this->vkCaps() .glslCaps())) {
688 SkDEBUGFAIL("Failed to generate GL program descriptor");
689 }
690 }
691
692 //////////////////////////////////////////////////////////////////////////////// 684 ////////////////////////////////////////////////////////////////////////////////
693 685
694 GrStencilAttachment* GrVkGpu::createStencilAttachmentForRenderTarget(const GrRen derTarget* rt, 686 GrStencilAttachment* GrVkGpu::createStencilAttachmentForRenderTarget(const GrRen derTarget* rt,
695 int width, 687 int width,
696 int height) { 688 int height) {
697 SkASSERT(rt->asTexture()); 689 SkASSERT(rt->asTexture());
698 SkASSERT(width >= rt->width()); 690 SkASSERT(width >= rt->width());
699 SkASSERT(height >= rt->height()); 691 SkASSERT(height >= rt->height());
700 692
701 int samples = rt->numStencilSamples(); 693 int samples = rt->numStencilSamples();
(...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after
1316 memcpy(top, bottom, tightRowBytes); 1308 memcpy(top, bottom, tightRowBytes);
1317 memcpy(bottom, tmpRow, tightRowBytes); 1309 memcpy(bottom, tmpRow, tightRowBytes);
1318 top += rowBytes; 1310 top += rowBytes;
1319 bottom -= rowBytes; 1311 bottom -= rowBytes;
1320 } 1312 }
1321 } 1313 }
1322 1314
1323 return true; 1315 return true;
1324 } 1316 }
1325 1317
1326 void GrVkGpu::onDraw(const DrawArgs& args, const GrNonInstancedVertices& vertice s) { 1318 bool GrVkGpu::prepareDrawState(const GrPipeline& pipeline,
1327 GrRenderTarget* rt = args.fPipeline->getRenderTarget(); 1319 const GrPrimitiveProcessor& primProc,
1320 GrPrimitiveType primitiveType,
1321 const GrVkRenderPass& renderPass,
1322 GrVkProgram** program) {
1323 // Get GrVkProgramDesc
1324 GrVkProgramDesc desc;
1325 if (!GrVkProgramDescBuilder::Build(&desc, primProc, pipeline, *this->vkCaps( ).glslCaps())) {
1326 GrCapsDebugf(this->caps(), "Failed to vk program descriptor!\n");
1327 return false;
1328 }
1329
1330 *program = GrVkProgramBuilder::CreateProgram(this,
1331 pipeline,
1332 primProc,
1333 primitiveType,
1334 desc,
1335 renderPass);
1336 if (!program) {
1337 return false;
1338 }
1339
1340 (*program)->setData(this, primProc, pipeline);
1341
1342 (*program)->bind(this, fCurrentCmdBuffer);
1343 return true;
1344 }
1345
1346 void GrVkGpu::onDraw(const GrPipeline& pipeline,
1347 const GrPrimitiveProcessor& primProc,
1348 const GrMesh* meshes,
1349 int meshCount) {
1350 if (!meshCount) {
1351 return;
1352 }
1353 GrRenderTarget* rt = pipeline.getRenderTarget();
1328 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(rt); 1354 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(rt);
1329 const GrVkRenderPass* renderPass = vkRT->simpleRenderPass(); 1355 const GrVkRenderPass* renderPass = vkRT->simpleRenderPass();
1330 SkASSERT(renderPass); 1356 SkASSERT(renderPass);
1331 1357
1332 GrVkProgram* program = GrVkProgramBuilder::CreateProgram(this, args, 1358 GrVkProgram* program = nullptr;
1333 vertices.primitiveT ype(), 1359 GrPrimitiveType primitiveType = meshes[0].primitiveType();
1334 *renderPass); 1360 if (!this->prepareDrawState(pipeline, primProc, primitiveType, *renderPass, &program)) {
1335
1336 if (!program) {
1337 return; 1361 return;
1338 } 1362 }
1339 1363
1340 program->setData(this, *args.fPrimitiveProcessor, *args.fPipeline);
1341
1342 fCurrentCmdBuffer->beginRenderPass(this, renderPass, *vkRT);
1343
1344 program->bind(this, fCurrentCmdBuffer);
1345
1346 this->bindGeometry(*args.fPrimitiveProcessor, vertices);
1347
1348 // Change layout of our render target so it can be used as the color attachm ent 1364 // Change layout of our render target so it can be used as the color attachm ent
1349 VkImageLayout layout = vkRT->currentLayout(); 1365 VkImageLayout layout = vkRT->currentLayout();
1350 // Our color attachment is purely a destination and won't be read so don't n eed to flush or 1366 // Our color attachment is purely a destination and won't be read so don't n eed to flush or
1351 // invalidate any caches 1367 // invalidate any caches
1352 VkPipelineStageFlags srcStageMask = GrVkMemory::LayoutToPipelineStageFlags(l ayout); 1368 VkPipelineStageFlags srcStageMask = GrVkMemory::LayoutToPipelineStageFlags(l ayout);
1353 VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; 1369 VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
1354 VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(layout); 1370 VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(layout);
1355 VkAccessFlags dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 1371 VkAccessFlags dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
1356 vkRT->setImageLayout(this, 1372 vkRT->setImageLayout(this,
1357 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1373 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1358 srcAccessMask, 1374 srcAccessMask,
1359 dstAccessMask, 1375 dstAccessMask,
1360 srcStageMask, 1376 srcStageMask,
1361 dstStageMask, 1377 dstStageMask,
1362 false); 1378 false);
1363 1379
1364 // If we are using a stencil attachment we also need to update its layout 1380 // If we are using a stencil attachment we also need to update its layout
1365 if (!args.fPipeline->getStencil().isDisabled()) { 1381 if (!pipeline.getStencil().isDisabled()) {
1366 GrStencilAttachment* stencil = vkRT->renderTargetPriv().getStencilAttach ment(); 1382 GrStencilAttachment* stencil = vkRT->renderTargetPriv().getStencilAttach ment();
1367 GrVkStencilAttachment* vkStencil = (GrVkStencilAttachment*)stencil; 1383 GrVkStencilAttachment* vkStencil = (GrVkStencilAttachment*)stencil;
1368 VkImageLayout origDstLayout = vkStencil->currentLayout(); 1384 VkImageLayout origDstLayout = vkStencil->currentLayout();
1369 VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(origDstL ayout); 1385 VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(origDstL ayout);
1370 VkAccessFlags dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_B IT | 1386 VkAccessFlags dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_B IT |
1371 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BI T; 1387 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
1372 VkPipelineStageFlags srcStageMask = 1388 VkPipelineStageFlags srcStageMask =
1373 GrVkMemory::LayoutToPipelineStageFlags(origDstLayout); 1389 GrVkMemory::LayoutToPipelineStageFlags(origDstLayout);
1374 VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; 1390 VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
1375 vkStencil->setImageLayout(this, 1391 vkStencil->setImageLayout(this,
1376 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIM AL, 1392 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIM AL,
1377 srcAccessMask, 1393 srcAccessMask,
1378 dstAccessMask, 1394 dstAccessMask,
1379 srcStageMask, 1395 srcStageMask,
1380 dstStageMask, 1396 dstStageMask,
1381 false); 1397 false);
1382 } 1398 }
1383 1399
1384 if (vertices.isIndexed()) { 1400 fCurrentCmdBuffer->beginRenderPass(this, renderPass, *vkRT);
1385 fCurrentCmdBuffer->drawIndexed(this, 1401
1386 vertices.indexCount(), 1402 for (int i = 0; i < meshCount; ++i) {
1387 1, 1403 if (GrXferBarrierType barrierType = pipeline.xferBarrierType(*this->caps ())) {
1388 vertices.startIndex(), 1404 this->xferBarrier(pipeline.getRenderTarget(), barrierType);
1389 vertices.startVertex(), 1405 }
1390 0); 1406
1391 } else { 1407 const GrMesh& mesh = meshes[i];
1392 fCurrentCmdBuffer->draw(this, vertices.vertexCount(), 1, vertices.startV ertex(), 0); 1408 GrMesh::Iterator iter;
1409 const GrNonInstancedMesh* nonIdxMesh = iter.init(mesh);
1410 do {
1411 if (nonIdxMesh->primitiveType() != primitiveType) {
1412 // Technically we don't have to call this here (since there is a safety check in
1413 // program:setData but this will allow for quicker freeing of re sources if the
1414 // program sits in a cache for a while.
1415 program->freeTempResources(this);
1416 // This free will go away once we setup a program cache, and the n the cache will be
1417 // responsible for call freeGpuResources.
1418 program->freeGPUResources(this);
1419 program->unref();
1420 SkDEBUGCODE(program = nullptr);
1421 primitiveType = nonIdxMesh->primitiveType();
1422 if (!this->prepareDrawState(pipeline, primProc, primitiveType, * renderPass,
1423 &program)) {
1424 return;
1425 }
1426 }
1427 SkASSERT(program);
1428 this->bindGeometry(primProc, *nonIdxMesh);
1429
1430 if (nonIdxMesh->isIndexed()) {
1431 fCurrentCmdBuffer->drawIndexed(this,
1432 nonIdxMesh->indexCount(),
1433 1,
1434 nonIdxMesh->startIndex(),
1435 nonIdxMesh->startVertex(),
1436 0);
1437 } else {
1438 fCurrentCmdBuffer->draw(this,
1439 nonIdxMesh->vertexCount(),
1440 1,
1441 nonIdxMesh->startVertex(),
1442 0);
1443 }
1444
1445 fStats.incNumDraws();
1446 } while ((nonIdxMesh = iter.next()));
1393 } 1447 }
1394 1448
1395 fCurrentCmdBuffer->endRenderPass(this); 1449 fCurrentCmdBuffer->endRenderPass(this);
1396 1450
1397 // Technically we don't have to call this here (since there is a safety chec k in program:setData 1451 // Technically we don't have to call this here (since there is a safety chec k in program:setData
1398 // but this will allow for quicker freeing of resources if the program sits in a cache for a 1452 // but this will allow for quicker freeing of resources if the program sits in a cache for a
1399 // while. 1453 // while.
1400 program->freeTempResources(this); 1454 program->freeTempResources(this);
1401 // This free will go away once we setup a program cache, and then the cache will be responsible 1455 // This free will go away once we setup a program cache, and then the cache will be responsible
1402 // for call freeGpuResources. 1456 // for call freeGpuResources.
1403 program->freeGPUResources(this); 1457 program->freeGPUResources(this);
1404 program->unref(); 1458 program->unref();
1405 1459
1406 #if SWAP_PER_DRAW 1460 #if SWAP_PER_DRAW
1407 glFlush(); 1461 glFlush();
1408 #if defined(SK_BUILD_FOR_MAC) 1462 #if defined(SK_BUILD_FOR_MAC)
1409 aglSwapBuffers(aglGetCurrentContext()); 1463 aglSwapBuffers(aglGetCurrentContext());
1410 int set_a_break_pt_here = 9; 1464 int set_a_break_pt_here = 9;
1411 aglSwapBuffers(aglGetCurrentContext()); 1465 aglSwapBuffers(aglGetCurrentContext());
1412 #elif defined(SK_BUILD_FOR_WIN32) 1466 #elif defined(SK_BUILD_FOR_WIN32)
1413 SwapBuf(); 1467 SwapBuf();
1414 int set_a_break_pt_here = 9; 1468 int set_a_break_pt_here = 9;
1415 SwapBuf(); 1469 SwapBuf();
1416 #endif 1470 #endif
1417 #endif 1471 #endif
1418 } 1472 }
1419 1473
OLDNEW
« no previous file with comments | « src/gpu/vk/GrVkGpu.h ('k') | src/gpu/vk/GrVkProgramBuilder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698