| 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 "GrMesh.h" |
| 14 #include "GrPipeline.h" | 14 #include "GrPipeline.h" |
| 15 #include "GrRenderTargetPriv.h" | 15 #include "GrRenderTargetPriv.h" |
| 16 #include "GrSurfacePriv.h" | 16 #include "GrSurfacePriv.h" |
| 17 #include "GrTexturePriv.h" | 17 #include "GrTexturePriv.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 "GrVkPipelineState.h" |
| 25 #include "GrVkProgramBuilder.h" | |
| 26 #include "GrVkProgramDesc.h" | |
| 27 #include "GrVkRenderPass.h" | 25 #include "GrVkRenderPass.h" |
| 28 #include "GrVkResourceProvider.h" | 26 #include "GrVkResourceProvider.h" |
| 29 #include "GrVkTexture.h" | 27 #include "GrVkTexture.h" |
| 30 #include "GrVkTextureRenderTarget.h" | 28 #include "GrVkTextureRenderTarget.h" |
| 31 #include "GrVkTransferBuffer.h" | 29 #include "GrVkTransferBuffer.h" |
| 32 #include "GrVkVertexBuffer.h" | 30 #include "GrVkVertexBuffer.h" |
| 33 | 31 |
| 34 #include "SkConfig8888.h" | 32 #include "SkConfig8888.h" |
| 35 | 33 |
| 36 #include "vk/GrVkInterface.h" | 34 #include "vk/GrVkInterface.h" |
| (...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 357 | 355 |
| 358 // wait for all commands to finish | 356 // wait for all commands to finish |
| 359 fResourceProvider.checkCommandBuffers(); | 357 fResourceProvider.checkCommandBuffers(); |
| 360 SkDEBUGCODE(VkResult res =) VK_CALL(QueueWaitIdle(fQueue)); | 358 SkDEBUGCODE(VkResult res =) VK_CALL(QueueWaitIdle(fQueue)); |
| 361 // VK_ERROR_DEVICE_LOST is acceptable when tearing down (see 4.2.4 in spec) | 359 // VK_ERROR_DEVICE_LOST is acceptable when tearing down (see 4.2.4 in spec) |
| 362 SkASSERT(VK_SUCCESS == res || VK_ERROR_DEVICE_LOST == res); | 360 SkASSERT(VK_SUCCESS == res || VK_ERROR_DEVICE_LOST == res); |
| 363 | 361 |
| 364 // must call this just before we destroy the VkDevice | 362 // must call this just before we destroy the VkDevice |
| 365 fResourceProvider.destroyResources(); | 363 fResourceProvider.destroyResources(); |
| 366 | 364 |
| 367 #ifdef SK_DEBUG | 365 #ifdef ENABLE_VK_LAYERS |
| 368 VK_CALL(DestroyDebugReportCallbackEXT(fVkInstance, fCallback, nullptr)); | 366 VK_CALL(DestroyDebugReportCallbackEXT(fVkInstance, fCallback, nullptr)); |
| 369 #endif | 367 #endif |
| 370 | 368 |
| 371 VK_CALL(DestroyCommandPool(fDevice, fCmdPool, nullptr)); | 369 VK_CALL(DestroyCommandPool(fDevice, fCmdPool, nullptr)); |
| 372 VK_CALL(DestroyDevice(fDevice, nullptr)); | 370 VK_CALL(DestroyDevice(fDevice, nullptr)); |
| 373 VK_CALL(DestroyInstance(fVkInstance, nullptr)); | 371 VK_CALL(DestroyInstance(fVkInstance, nullptr)); |
| 374 } | 372 } |
| 375 | 373 |
| 376 /////////////////////////////////////////////////////////////////////////////// | 374 /////////////////////////////////////////////////////////////////////////////// |
| 377 | 375 |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 689 imageDesc.fLevels = 1; | 687 imageDesc.fLevels = 1; |
| 690 imageDesc.fSamples = 1; | 688 imageDesc.fSamples = 1; |
| 691 imageDesc.fImageTiling = linearTiling ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TI
LING_OPTIMAL; | 689 imageDesc.fImageTiling = linearTiling ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TI
LING_OPTIMAL; |
| 692 imageDesc.fUsageFlags = usageFlags; | 690 imageDesc.fUsageFlags = usageFlags; |
| 693 imageDesc.fMemProps = memProps; | 691 imageDesc.fMemProps = memProps; |
| 694 | 692 |
| 695 GrVkTexture* tex; | 693 GrVkTexture* tex; |
| 696 if (renderTarget) { | 694 if (renderTarget) { |
| 697 tex = GrVkTextureRenderTarget::CreateNewTextureRenderTarget(this, desc,
lifeCycle, | 695 tex = GrVkTextureRenderTarget::CreateNewTextureRenderTarget(this, desc,
lifeCycle, |
| 698 imageDesc); | 696 imageDesc); |
| 699 #if 0 | |
| 700 // This clear can be included to fix warning described in htttps://bugs.
skia.org/5045 | |
| 701 // Obviously we do not want to be clearling needlessly every time we cre
ate a render target. | |
| 702 SkIRect rect = SkIRect::MakeWH(tex->width(), tex->height()); | |
| 703 this->clear(rect, GrColor_TRANSPARENT_BLACK, tex->asRenderTarget()); | |
| 704 #endif | |
| 705 } else { | 697 } else { |
| 706 tex = GrVkTexture::CreateNewTexture(this, desc, lifeCycle, imageDesc); | 698 tex = GrVkTexture::CreateNewTexture(this, desc, lifeCycle, imageDesc); |
| 707 } | 699 } |
| 708 | 700 |
| 709 if (!tex) { | 701 if (!tex) { |
| 710 return nullptr; | 702 return nullptr; |
| 711 } | 703 } |
| 712 | 704 |
| 713 // TODO: We're ignoring MIP levels here. | 705 // TODO: We're ignoring MIP levels here. |
| 714 if (!texels.empty()) { | 706 if (!texels.empty()) { |
| (...skipping 787 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1502 memcpy(tmpRow, top, tightRowBytes); | 1494 memcpy(tmpRow, top, tightRowBytes); |
| 1503 memcpy(top, bottom, tightRowBytes); | 1495 memcpy(top, bottom, tightRowBytes); |
| 1504 memcpy(bottom, tmpRow, tightRowBytes); | 1496 memcpy(bottom, tmpRow, tightRowBytes); |
| 1505 top += rowBytes; | 1497 top += rowBytes; |
| 1506 bottom -= rowBytes; | 1498 bottom -= rowBytes; |
| 1507 } | 1499 } |
| 1508 } | 1500 } |
| 1509 | 1501 |
| 1510 return true; | 1502 return true; |
| 1511 } | 1503 } |
| 1512 | |
| 1513 bool GrVkGpu::prepareDrawState(const GrPipeline& pipeline, | 1504 bool GrVkGpu::prepareDrawState(const GrPipeline& pipeline, |
| 1514 const GrPrimitiveProcessor& primProc, | 1505 const GrPrimitiveProcessor& primProc, |
| 1515 GrPrimitiveType primitiveType, | 1506 GrPrimitiveType primitiveType, |
| 1516 const GrVkRenderPass& renderPass, | 1507 const GrVkRenderPass& renderPass, |
| 1517 GrVkProgram** program) { | 1508 GrVkPipelineState** pipelineState) { |
| 1518 // Get GrVkProgramDesc | 1509 *pipelineState = fResourceProvider.findOrCreateCompatiblePipelineState(pipel
ine, |
| 1519 GrVkProgramDesc desc; | 1510 primP
roc, |
| 1520 if (!GrVkProgramDescBuilder::Build(&desc, primProc, pipeline, *this->vkCaps(
).glslCaps())) { | 1511 primi
tiveType, |
| 1521 GrCapsDebugf(this->caps(), "Failed to vk program descriptor!\n"); | 1512 rende
rPass); |
| 1513 if (!pipelineState) { |
| 1522 return false; | 1514 return false; |
| 1523 } | 1515 } |
| 1524 | 1516 |
| 1525 *program = GrVkProgramBuilder::CreateProgram(this, | 1517 (*pipelineState)->setData(this, primProc, pipeline); |
| 1526 pipeline, | |
| 1527 primProc, | |
| 1528 primitiveType, | |
| 1529 desc, | |
| 1530 renderPass); | |
| 1531 if (!program) { | |
| 1532 return false; | |
| 1533 } | |
| 1534 | 1518 |
| 1535 (*program)->setData(this, primProc, pipeline); | 1519 (*pipelineState)->bind(this, fCurrentCmdBuffer); |
| 1536 | |
| 1537 (*program)->bind(this, fCurrentCmdBuffer); | |
| 1538 | 1520 |
| 1539 GrVkPipeline::SetDynamicState(this, fCurrentCmdBuffer, pipeline); | 1521 GrVkPipeline::SetDynamicState(this, fCurrentCmdBuffer, pipeline); |
| 1540 | 1522 |
| 1541 return true; | 1523 return true; |
| 1542 } | 1524 } |
| 1543 | 1525 |
| 1544 void GrVkGpu::onDraw(const GrPipeline& pipeline, | 1526 void GrVkGpu::onDraw(const GrPipeline& pipeline, |
| 1545 const GrPrimitiveProcessor& primProc, | 1527 const GrPrimitiveProcessor& primProc, |
| 1546 const GrMesh* meshes, | 1528 const GrMesh* meshes, |
| 1547 int meshCount) { | 1529 int meshCount) { |
| 1548 if (!meshCount) { | 1530 if (!meshCount) { |
| 1549 return; | 1531 return; |
| 1550 } | 1532 } |
| 1551 GrRenderTarget* rt = pipeline.getRenderTarget(); | 1533 GrRenderTarget* rt = pipeline.getRenderTarget(); |
| 1552 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(rt); | 1534 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(rt); |
| 1553 const GrVkRenderPass* renderPass = vkRT->simpleRenderPass(); | 1535 const GrVkRenderPass* renderPass = vkRT->simpleRenderPass(); |
| 1554 SkASSERT(renderPass); | 1536 SkASSERT(renderPass); |
| 1555 | 1537 |
| 1556 fCurrentCmdBuffer->beginRenderPass(this, renderPass, *vkRT); | 1538 fCurrentCmdBuffer->beginRenderPass(this, renderPass, *vkRT); |
| 1557 | 1539 |
| 1558 GrVkProgram* program = nullptr; | 1540 GrVkPipelineState* pipelineState = nullptr; |
| 1559 GrPrimitiveType primitiveType = meshes[0].primitiveType(); | 1541 GrPrimitiveType primitiveType = meshes[0].primitiveType(); |
| 1560 if (!this->prepareDrawState(pipeline, primProc, primitiveType, *renderPass,
&program)) { | 1542 if (!this->prepareDrawState(pipeline, primProc, primitiveType, *renderPass,
&pipelineState)) { |
| 1561 return; | 1543 return; |
| 1562 } | 1544 } |
| 1563 | 1545 |
| 1564 // Change layout of our render target so it can be used as the color attachm
ent | 1546 // Change layout of our render target so it can be used as the color attachm
ent |
| 1565 VkImageLayout layout = vkRT->currentLayout(); | 1547 VkImageLayout layout = vkRT->currentLayout(); |
| 1566 // Our color attachment is purely a destination and won't be read so don't n
eed to flush or | 1548 // Our color attachment is purely a destination and won't be read so don't n
eed to flush or |
| 1567 // invalidate any caches | 1549 // invalidate any caches |
| 1568 VkPipelineStageFlags srcStageMask = GrVkMemory::LayoutToPipelineStageFlags(l
ayout); | 1550 VkPipelineStageFlags srcStageMask = GrVkMemory::LayoutToPipelineStageFlags(l
ayout); |
| 1569 VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; | 1551 VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; |
| 1570 VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(layout); | 1552 VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(layout); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1602 if (GrXferBarrierType barrierType = pipeline.xferBarrierType(*this->caps
())) { | 1584 if (GrXferBarrierType barrierType = pipeline.xferBarrierType(*this->caps
())) { |
| 1603 this->xferBarrier(pipeline.getRenderTarget(), barrierType); | 1585 this->xferBarrier(pipeline.getRenderTarget(), barrierType); |
| 1604 } | 1586 } |
| 1605 | 1587 |
| 1606 const GrMesh& mesh = meshes[i]; | 1588 const GrMesh& mesh = meshes[i]; |
| 1607 GrMesh::Iterator iter; | 1589 GrMesh::Iterator iter; |
| 1608 const GrNonInstancedMesh* nonIdxMesh = iter.init(mesh); | 1590 const GrNonInstancedMesh* nonIdxMesh = iter.init(mesh); |
| 1609 do { | 1591 do { |
| 1610 if (nonIdxMesh->primitiveType() != primitiveType) { | 1592 if (nonIdxMesh->primitiveType() != primitiveType) { |
| 1611 // Technically we don't have to call this here (since there is a
safety check in | 1593 // Technically we don't have to call this here (since there is a
safety check in |
| 1612 // program:setData but this will allow for quicker freeing of re
sources if the | 1594 // pipelineState:setData but this will allow for quicker freeing
of resources if the |
| 1613 // program sits in a cache for a while. | 1595 // pipelineState sits in a cache for a while. |
| 1614 program->freeTempResources(this); | 1596 pipelineState->freeTempResources(this); |
| 1615 // This free will go away once we setup a program cache, and the
n the cache will be | 1597 pipelineState->unref(); |
| 1616 // responsible for call freeGpuResources. | 1598 SkDEBUGCODE(pipelineState = nullptr); |
| 1617 program->freeGPUResources(this); | |
| 1618 program->unref(); | |
| 1619 SkDEBUGCODE(program = nullptr); | |
| 1620 primitiveType = nonIdxMesh->primitiveType(); | 1599 primitiveType = nonIdxMesh->primitiveType(); |
| 1621 if (!this->prepareDrawState(pipeline, primProc, primitiveType, *
renderPass, | 1600 if (!this->prepareDrawState(pipeline, primProc, primitiveType, *
renderPass, |
| 1622 &program)) { | 1601 &pipelineState)) { |
| 1623 return; | 1602 return; |
| 1624 } | 1603 } |
| 1625 } | 1604 } |
| 1626 SkASSERT(program); | 1605 SkASSERT(pipelineState); |
| 1627 this->bindGeometry(primProc, *nonIdxMesh); | 1606 this->bindGeometry(primProc, *nonIdxMesh); |
| 1628 | 1607 |
| 1629 if (nonIdxMesh->isIndexed()) { | 1608 if (nonIdxMesh->isIndexed()) { |
| 1630 fCurrentCmdBuffer->drawIndexed(this, | 1609 fCurrentCmdBuffer->drawIndexed(this, |
| 1631 nonIdxMesh->indexCount(), | 1610 nonIdxMesh->indexCount(), |
| 1632 1, | 1611 1, |
| 1633 nonIdxMesh->startIndex(), | 1612 nonIdxMesh->startIndex(), |
| 1634 nonIdxMesh->startVertex(), | 1613 nonIdxMesh->startVertex(), |
| 1635 0); | 1614 0); |
| 1636 } else { | 1615 } else { |
| 1637 fCurrentCmdBuffer->draw(this, | 1616 fCurrentCmdBuffer->draw(this, |
| 1638 nonIdxMesh->vertexCount(), | 1617 nonIdxMesh->vertexCount(), |
| 1639 1, | 1618 1, |
| 1640 nonIdxMesh->startVertex(), | 1619 nonIdxMesh->startVertex(), |
| 1641 0); | 1620 0); |
| 1642 } | 1621 } |
| 1643 | 1622 |
| 1644 fStats.incNumDraws(); | 1623 fStats.incNumDraws(); |
| 1645 } while ((nonIdxMesh = iter.next())); | 1624 } while ((nonIdxMesh = iter.next())); |
| 1646 } | 1625 } |
| 1647 | 1626 |
| 1648 fCurrentCmdBuffer->endRenderPass(this); | 1627 fCurrentCmdBuffer->endRenderPass(this); |
| 1649 | 1628 |
| 1650 // Technically we don't have to call this here (since there is a safety chec
k in program:setData | 1629 // Technically we don't have to call this here (since there is a safety chec
k in |
| 1651 // but this will allow for quicker freeing of resources if the program sits
in a cache for a | 1630 // pipelineState:setData but this will allow for quicker freeing of resource
s if the |
| 1652 // while. | 1631 // pipelineState sits in a cache for a while. |
| 1653 program->freeTempResources(this); | 1632 pipelineState->freeTempResources(this); |
| 1654 // This free will go away once we setup a program cache, and then the cache
will be responsible | 1633 pipelineState->unref(); |
| 1655 // for call freeGpuResources. | |
| 1656 program->freeGPUResources(this); | |
| 1657 program->unref(); | |
| 1658 | 1634 |
| 1659 #if SWAP_PER_DRAW | 1635 #if SWAP_PER_DRAW |
| 1660 glFlush(); | 1636 glFlush(); |
| 1661 #if defined(SK_BUILD_FOR_MAC) | 1637 #if defined(SK_BUILD_FOR_MAC) |
| 1662 aglSwapBuffers(aglGetCurrentContext()); | 1638 aglSwapBuffers(aglGetCurrentContext()); |
| 1663 int set_a_break_pt_here = 9; | 1639 int set_a_break_pt_here = 9; |
| 1664 aglSwapBuffers(aglGetCurrentContext()); | 1640 aglSwapBuffers(aglGetCurrentContext()); |
| 1665 #elif defined(SK_BUILD_FOR_WIN32) | 1641 #elif defined(SK_BUILD_FOR_WIN32) |
| 1666 SwapBuf(); | 1642 SwapBuf(); |
| 1667 int set_a_break_pt_here = 9; | 1643 int set_a_break_pt_here = 9; |
| 1668 SwapBuf(); | 1644 SwapBuf(); |
| 1669 #endif | 1645 #endif |
| 1670 #endif | 1646 #endif |
| 1671 } | 1647 } |
| 1672 | 1648 |
| OLD | NEW |