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" |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
359 return false; | 359 return false; |
360 } | 360 } |
361 } | 361 } |
362 success = this->uploadTexDataOptimal(vkTex, left, top, width, height
, config, texels); | 362 success = this->uploadTexDataOptimal(vkTex, left, top, width, height
, config, texels); |
363 } | 363 } |
364 } | 364 } |
365 | 365 |
366 return success; | 366 return success; |
367 } | 367 } |
368 | 368 |
| 369 void GrVkGpu::resolveImage(GrVkRenderTarget* dst, GrVkRenderTarget* src, const S
kIRect& srcRect, |
| 370 const SkIPoint& dstPoint) { |
| 371 SkASSERT(dst); |
| 372 SkASSERT(src && src->numColorSamples() > 1 && src->msaaImage()); |
| 373 |
| 374 // Flip rect if necessary |
| 375 SkIRect srcVkRect = srcRect; |
| 376 int32_t dstY = dstPoint.fY; |
| 377 |
| 378 if (kBottomLeft_GrSurfaceOrigin == src->origin()) { |
| 379 SkASSERT(kBottomLeft_GrSurfaceOrigin == dst->origin()); |
| 380 srcVkRect.fTop = src->height() - srcRect.fBottom; |
| 381 srcVkRect.fBottom = src->height() - srcRect.fTop; |
| 382 dstY = dst->height() - dstPoint.fY - srcVkRect.height(); |
| 383 } |
| 384 |
| 385 VkImageResolve resolveInfo; |
| 386 resolveInfo.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; |
| 387 resolveInfo.srcOffset = { srcVkRect.fLeft, srcVkRect.fTop, 0 }; |
| 388 resolveInfo.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; |
| 389 resolveInfo.dstOffset = { dstPoint.fX, dstY, 0 }; |
| 390 // By the spec the depth of the extent should be ignored for 2D images, but
certain devices |
| 391 // (e.g. nexus 5x) currently fail if it is not 1 |
| 392 resolveInfo.extent = { (uint32_t)srcVkRect.width(), (uint32_t)srcVkRect.heig
ht(), 1 }; |
| 393 |
| 394 dst->setImageLayout(this, |
| 395 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, |
| 396 VK_ACCESS_TRANSFER_WRITE_BIT, |
| 397 VK_PIPELINE_STAGE_TRANSFER_BIT, |
| 398 false); |
| 399 |
| 400 src->msaaImage()->setImageLayout(this, |
| 401 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, |
| 402 VK_ACCESS_TRANSFER_READ_BIT, |
| 403 VK_PIPELINE_STAGE_TRANSFER_BIT, |
| 404 false); |
| 405 |
| 406 fCurrentCmdBuffer->resolveImage(this, *src->msaaImage(), *dst, 1, &resolveIn
fo); |
| 407 } |
| 408 |
369 void GrVkGpu::onResolveRenderTarget(GrRenderTarget* target) { | 409 void GrVkGpu::onResolveRenderTarget(GrRenderTarget* target) { |
370 if (target->needsResolve()) { | 410 if (target->needsResolve()) { |
371 SkASSERT(target->numColorSamples() > 1); | 411 SkASSERT(target->numColorSamples() > 1); |
372 GrVkRenderTarget* rt = static_cast<GrVkRenderTarget*>(target); | 412 GrVkRenderTarget* rt = static_cast<GrVkRenderTarget*>(target); |
373 SkASSERT(rt->msaaImage()); | 413 SkASSERT(rt->msaaImage()); |
| 414 |
| 415 const SkIRect& srcRect = rt->getResolveRect(); |
374 | 416 |
375 // Flip rect if necessary | 417 this->resolveImage(rt, rt, srcRect, SkIPoint::Make(srcRect.fLeft, srcRec
t.fTop)); |
376 SkIRect srcVkRect = rt->getResolveRect(); | |
377 | |
378 if (kBottomLeft_GrSurfaceOrigin == rt->origin()) { | |
379 srcVkRect.fTop = rt->height() - rt->getResolveRect().fBottom; | |
380 srcVkRect.fBottom = rt->height() - rt->getResolveRect().fTop; | |
381 } | |
382 | |
383 VkImageResolve resolveInfo; | |
384 resolveInfo.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; | |
385 resolveInfo.srcOffset = { srcVkRect.fLeft, srcVkRect.fTop, 0 }; | |
386 resolveInfo.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; | |
387 resolveInfo.dstOffset = { srcVkRect.fLeft, srcVkRect.fTop, 0 }; | |
388 // By the spec the depth of the extent should be ignored for 2D images,
but certain devices | |
389 // (e.g. nexus 5x) currently fail if it is not 1 | |
390 resolveInfo.extent = { (uint32_t)srcVkRect.width(), (uint32_t)srcVkRect.
height(), 1 }; | |
391 | |
392 rt->setImageLayout(this, | |
393 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, | |
394 VK_ACCESS_TRANSFER_WRITE_BIT, | |
395 VK_PIPELINE_STAGE_TRANSFER_BIT, | |
396 false); | |
397 | |
398 rt->msaaImage()->setImageLayout(this, | |
399 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, | |
400 VK_ACCESS_TRANSFER_READ_BIT, | |
401 VK_PIPELINE_STAGE_TRANSFER_BIT, | |
402 false); | |
403 | |
404 fCurrentCmdBuffer->resolveImage(this, *rt->msaaImage(), *rt, 1, &resolve
Info); | |
405 | 418 |
406 rt->flagAsResolved(); | 419 rt->flagAsResolved(); |
407 } | 420 } |
408 } | 421 } |
409 | 422 |
410 bool GrVkGpu::uploadTexDataLinear(GrVkTexture* tex, | 423 bool GrVkGpu::uploadTexDataLinear(GrVkTexture* tex, |
411 int left, int top, int width, int height, | 424 int left, int top, int width, int height, |
412 GrPixelConfig dataConfig, | 425 GrPixelConfig dataConfig, |
413 const void* data, | 426 const void* data, |
414 size_t rowBytes) { | 427 size_t rowBytes) { |
(...skipping 932 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1347 | 1360 |
1348 // TODO: I imagine that most times we want to clear a stencil it will be at
the beginning of a | 1361 // TODO: I imagine that most times we want to clear a stencil it will be at
the beginning of a |
1349 // draw. Thus we should look into using the load op functions on the render
pass to clear out | 1362 // draw. Thus we should look into using the load op functions on the render
pass to clear out |
1350 // the stencil there. | 1363 // the stencil there. |
1351 fCurrentCmdBuffer->clearDepthStencilImage(this, vkStencil, &vkStencilColor,
1, &subRange); | 1364 fCurrentCmdBuffer->clearDepthStencilImage(this, vkStencil, &vkStencilColor,
1, &subRange); |
1352 } | 1365 } |
1353 | 1366 |
1354 inline bool can_copy_image(const GrSurface* dst, | 1367 inline bool can_copy_image(const GrSurface* dst, |
1355 const GrSurface* src, | 1368 const GrSurface* src, |
1356 const GrVkGpu* gpu) { | 1369 const GrVkGpu* gpu) { |
1357 // Currently we don't support msaa | 1370 const GrRenderTarget* dstRT = dst->asRenderTarget(); |
1358 if ((dst->asRenderTarget() && dst->asRenderTarget()->numColorSamples() > 1)
|| | 1371 const GrRenderTarget* srcRT = src->asRenderTarget(); |
1359 (src->asRenderTarget() && src->asRenderTarget()->numColorSamples() > 1))
{ | 1372 if (dstRT && srcRT) { |
1360 return false; | 1373 if (srcRT->numColorSamples() != dstRT->numColorSamples()) { |
| 1374 return false; |
| 1375 } |
| 1376 } else if (dstRT) { |
| 1377 if (dstRT->numColorSamples() > 1) { |
| 1378 return false; |
| 1379 } |
| 1380 } else if (srcRT) { |
| 1381 if (srcRT->numColorSamples() > 1) { |
| 1382 return false; |
| 1383 } |
1361 } | 1384 } |
1362 | 1385 |
1363 // We require that all vulkan GrSurfaces have been created with transfer_dst
and transfer_src | 1386 // We require that all vulkan GrSurfaces have been created with transfer_dst
and transfer_src |
1364 // as image usage flags. | 1387 // as image usage flags. |
1365 if (src->origin() == dst->origin() && | 1388 if (src->origin() == dst->origin() && |
1366 GrBytesPerPixel(src->config()) == GrBytesPerPixel(dst->config())) { | 1389 GrBytesPerPixel(src->config()) == GrBytesPerPixel(dst->config())) { |
1367 return true; | 1390 return true; |
1368 } | 1391 } |
1369 | 1392 |
1370 // How does msaa play into this? If a VkTexture is multisampled, are we copy
ing the multisampled | |
1371 // or the resolved image here? Im multisampled, Vulkan requires sample count
s to be the same. | |
1372 | |
1373 return false; | 1393 return false; |
1374 } | 1394 } |
1375 | 1395 |
1376 void GrVkGpu::copySurfaceAsCopyImage(GrSurface* dst, | 1396 void GrVkGpu::copySurfaceAsCopyImage(GrSurface* dst, |
1377 GrSurface* src, | 1397 GrSurface* src, |
1378 GrVkImage* dstImage, | 1398 GrVkImage* dstImage, |
1379 GrVkImage* srcImage, | 1399 GrVkImage* srcImage, |
1380 const SkIRect& srcRect, | 1400 const SkIRect& srcRect, |
1381 const SkIPoint& dstPoint) { | 1401 const SkIPoint& dstPoint) { |
1382 SkASSERT(can_copy_image(dst, src, this)); | 1402 SkASSERT(can_copy_image(dst, src, this)); |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1514 fCurrentCmdBuffer->blitImage(this, | 1534 fCurrentCmdBuffer->blitImage(this, |
1515 *srcImage, | 1535 *srcImage, |
1516 *dstImage, | 1536 *dstImage, |
1517 1, | 1537 1, |
1518 &blitRegion, | 1538 &blitRegion, |
1519 VK_FILTER_NEAREST); // We never scale so any fi
lter works here | 1539 VK_FILTER_NEAREST); // We never scale so any fi
lter works here |
1520 | 1540 |
1521 this->didWriteToSurface(dst, &dstRect); | 1541 this->didWriteToSurface(dst, &dstRect); |
1522 } | 1542 } |
1523 | 1543 |
| 1544 inline bool can_copy_as_resolve(const GrSurface* dst, |
| 1545 const GrSurface* src, |
| 1546 const GrVkGpu* gpu) { |
| 1547 // Our src must be a multisampled render target |
| 1548 if (!src->asRenderTarget() || src->asRenderTarget()->numColorSamples() <= 1)
{ |
| 1549 return false; |
| 1550 } |
| 1551 |
| 1552 // The dst must be a render target but not multisampled |
| 1553 if (!dst->asRenderTarget() || dst->asRenderTarget()->numColorSamples() > 1)
{ |
| 1554 return false; |
| 1555 } |
| 1556 |
| 1557 // Surfaces must have the same origin. |
| 1558 if (src->origin() != dst->origin()) { |
| 1559 return false; |
| 1560 } |
| 1561 |
| 1562 return true; |
| 1563 } |
| 1564 |
| 1565 void GrVkGpu::copySurfaceAsResolve(GrSurface* dst, |
| 1566 GrSurface* src, |
| 1567 const SkIRect& srcRect, |
| 1568 const SkIPoint& dstPoint) { |
| 1569 GrVkRenderTarget* dstRT = static_cast<GrVkRenderTarget*>(dst->asRenderTarget
()); |
| 1570 GrVkRenderTarget* srcRT = static_cast<GrVkRenderTarget*>(src->asRenderTarget
()); |
| 1571 SkASSERT(dstRT && dstRT->numColorSamples() <= 1); |
| 1572 this->resolveImage(dstRT, srcRT, srcRect, dstPoint); |
| 1573 } |
| 1574 |
1524 inline bool can_copy_as_draw(const GrSurface* dst, | 1575 inline bool can_copy_as_draw(const GrSurface* dst, |
1525 const GrSurface* src, | 1576 const GrSurface* src, |
1526 const GrVkGpu* gpu) { | 1577 const GrVkGpu* gpu) { |
1527 return false; | 1578 return false; |
1528 } | 1579 } |
1529 | 1580 |
1530 void GrVkGpu::copySurfaceAsDraw(GrSurface* dst, | 1581 void GrVkGpu::copySurfaceAsDraw(GrSurface* dst, |
1531 GrSurface* src, | 1582 GrSurface* src, |
1532 const SkIRect& srcRect, | 1583 const SkIRect& srcRect, |
1533 const SkIPoint& dstPoint) { | 1584 const SkIPoint& dstPoint) { |
1534 SkASSERT(false); | 1585 SkASSERT(false); |
1535 } | 1586 } |
1536 | 1587 |
1537 bool GrVkGpu::onCopySurface(GrSurface* dst, | 1588 bool GrVkGpu::onCopySurface(GrSurface* dst, |
1538 GrSurface* src, | 1589 GrSurface* src, |
1539 const SkIRect& srcRect, | 1590 const SkIRect& srcRect, |
1540 const SkIPoint& dstPoint) { | 1591 const SkIPoint& dstPoint) { |
| 1592 if (can_copy_as_resolve(dst, src, this)) { |
| 1593 this->copySurfaceAsResolve(dst, src, srcRect, dstPoint); |
| 1594 } |
| 1595 |
1541 GrVkImage* dstImage; | 1596 GrVkImage* dstImage; |
1542 GrVkImage* srcImage; | 1597 GrVkImage* srcImage; |
1543 if (dst->asTexture()) { | 1598 GrRenderTarget* dstRT = dst->asRenderTarget(); |
| 1599 if (dstRT) { |
| 1600 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(dstRT); |
| 1601 dstImage = vkRT->numColorSamples() > 1 ? vkRT->msaaImage() : vkRT; |
| 1602 } else { |
| 1603 SkASSERT(dst->asTexture()); |
1544 dstImage = static_cast<GrVkTexture*>(dst->asTexture()); | 1604 dstImage = static_cast<GrVkTexture*>(dst->asTexture()); |
| 1605 } |
| 1606 GrRenderTarget* srcRT = src->asRenderTarget(); |
| 1607 if (srcRT) { |
| 1608 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(srcRT); |
| 1609 srcImage = vkRT->numColorSamples() > 1 ? vkRT->msaaImage() : vkRT; |
1545 } else { | 1610 } else { |
1546 SkASSERT(dst->asRenderTarget()); | 1611 SkASSERT(src->asTexture()); |
1547 dstImage = static_cast<GrVkRenderTarget*>(dst->asRenderTarget()); | |
1548 } | |
1549 if (src->asTexture()) { | |
1550 srcImage = static_cast<GrVkTexture*>(src->asTexture()); | 1612 srcImage = static_cast<GrVkTexture*>(src->asTexture()); |
1551 } else { | |
1552 SkASSERT(src->asRenderTarget()); | |
1553 srcImage = static_cast<GrVkRenderTarget*>(src->asRenderTarget()); | |
1554 } | 1613 } |
1555 | 1614 |
1556 if (can_copy_image(dst, src, this)) { | 1615 if (can_copy_image(dst, src, this)) { |
1557 this->copySurfaceAsCopyImage(dst, src, dstImage, srcImage, srcRect, dstP
oint); | 1616 this->copySurfaceAsCopyImage(dst, src, dstImage, srcImage, srcRect, dstP
oint); |
1558 return true; | 1617 return true; |
1559 } | 1618 } |
1560 | 1619 |
1561 if (can_copy_as_blit(dst, src, dstImage, srcImage, this)) { | 1620 if (can_copy_as_blit(dst, src, dstImage, srcImage, this)) { |
1562 this->copySurfaceAsBlit(dst, src, dstImage, srcImage, srcRect, dstPoint)
; | 1621 this->copySurfaceAsBlit(dst, src, dstImage, srcImage, srcRect, dstPoint)
; |
1563 return true; | 1622 return true; |
1564 } | 1623 } |
1565 | 1624 |
1566 if (can_copy_as_draw(dst, src, this)) { | 1625 if (can_copy_as_draw(dst, src, this)) { |
1567 this->copySurfaceAsDraw(dst, src, srcRect, dstPoint); | 1626 this->copySurfaceAsDraw(dst, src, srcRect, dstPoint); |
1568 return true; | 1627 return true; |
1569 } | 1628 } |
1570 | 1629 |
1571 return false; | 1630 return false; |
1572 } | 1631 } |
1573 | 1632 |
1574 bool GrVkGpu::initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc)
const { | 1633 bool GrVkGpu::initCopySurfaceDstDesc(const GrRenderTarget* src, GrSurfaceDesc* d
esc) const { |
1575 // Currently we don't support msaa | 1634 // We can always succeed here with either a CopyImage (none msaa src) or Res
olveImage (msaa). |
1576 if (src->asRenderTarget() && src->asRenderTarget()->numColorSamples() > 1) { | 1635 // For CopyImage we can make a simple texture, for ResolveImage we require t
he dst to be a |
1577 return false; | 1636 // render target as well. |
1578 } | |
1579 | |
1580 // This will support copying the dst as CopyImage since all of our surfaces
require transferSrc | |
1581 // and transferDst usage flags in Vulkan. | |
1582 desc->fOrigin = src->origin(); | 1637 desc->fOrigin = src->origin(); |
1583 desc->fConfig = src->config(); | 1638 desc->fConfig = src->config(); |
1584 desc->fFlags = kNone_GrSurfaceFlags; | 1639 desc->fFlags = src->numColorSamples() > 1 ? kRenderTarget_GrSurfaceFlag : kN
one_GrSurfaceFlags; |
1585 return true; | 1640 return true; |
1586 } | 1641 } |
1587 | 1642 |
1588 void GrVkGpu::onGetMultisampleSpecs(GrRenderTarget* rt, const GrStencilSettings&
, | 1643 void GrVkGpu::onGetMultisampleSpecs(GrRenderTarget* rt, const GrStencilSettings&
, |
1589 int* effectiveSampleCnt, SamplePattern*) { | 1644 int* effectiveSampleCnt, SamplePattern*) { |
1590 // TODO: stub. | 1645 // TODO: stub. |
1591 SkASSERT(!this->caps()->sampleLocationsSupport()); | 1646 SkASSERT(!this->caps()->sampleLocationsSupport()); |
1592 *effectiveSampleCnt = rt->desc().fSampleCnt; | 1647 *effectiveSampleCnt = rt->desc().fSampleCnt; |
1593 } | 1648 } |
1594 | 1649 |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1796 // Currently it is fine for us to always pass in 1 for the clear count even
if no attachment | 1851 // Currently it is fine for us to always pass in 1 for the clear count even
if no attachment |
1797 // uses it. In the current state, we also only use the LOAD_OP_CLEAR for the
color attachment | 1852 // uses it. In the current state, we also only use the LOAD_OP_CLEAR for the
color attachment |
1798 // which is always at the first attachment. | 1853 // which is always at the first attachment. |
1799 fCurrentCmdBuffer->beginRenderPass(this, renderPass, 1, colorClear, *target,
*pBounds, true); | 1854 fCurrentCmdBuffer->beginRenderPass(this, renderPass, 1, colorClear, *target,
*pBounds, true); |
1800 fCurrentCmdBuffer->executeCommands(this, buffer); | 1855 fCurrentCmdBuffer->executeCommands(this, buffer); |
1801 fCurrentCmdBuffer->endRenderPass(this); | 1856 fCurrentCmdBuffer->endRenderPass(this); |
1802 | 1857 |
1803 this->didWriteToSurface(target, &bounds); | 1858 this->didWriteToSurface(target, &bounds); |
1804 } | 1859 } |
1805 | 1860 |
OLD | NEW |