OLD | NEW |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |