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 911 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1326 | 1339 |
1327 // TODO: I imagine that most times we want to clear a stencil it will be at
the beginning of a | 1340 // TODO: I imagine that most times we want to clear a stencil it will be at
the beginning of a |
1328 // draw. Thus we should look into using the load op functions on the render
pass to clear out | 1341 // draw. Thus we should look into using the load op functions on the render
pass to clear out |
1329 // the stencil there. | 1342 // the stencil there. |
1330 fCurrentCmdBuffer->clearDepthStencilImage(this, vkStencil, &vkStencilColor,
1, &subRange); | 1343 fCurrentCmdBuffer->clearDepthStencilImage(this, vkStencil, &vkStencilColor,
1, &subRange); |
1331 } | 1344 } |
1332 | 1345 |
1333 inline bool can_copy_image(const GrSurface* dst, | 1346 inline bool can_copy_image(const GrSurface* dst, |
1334 const GrSurface* src, | 1347 const GrSurface* src, |
1335 const GrVkGpu* gpu) { | 1348 const GrVkGpu* gpu) { |
1336 // Currently we don't support msaa | 1349 const GrRenderTarget* dstRT = dst->asRenderTarget(); |
1337 if ((dst->asRenderTarget() && dst->asRenderTarget()->numColorSamples() > 1)
|| | 1350 const GrRenderTarget* srcRT = src->asRenderTarget(); |
1338 (src->asRenderTarget() && src->asRenderTarget()->numColorSamples() > 1))
{ | 1351 if (dstRT && srcRT) { |
1339 return false; | 1352 if (srcRT->numColorSamples() != dstRT->numColorSamples()) { |
| 1353 return false; |
| 1354 } |
| 1355 } else if (dstRT) { |
| 1356 if (dstRT->numColorSamples() > 1) { |
| 1357 return false; |
| 1358 } |
| 1359 } else if (srcRT) { |
| 1360 if (srcRT->numColorSamples() > 1) { |
| 1361 return false; |
| 1362 } |
1340 } | 1363 } |
1341 | 1364 |
1342 // We require that all vulkan GrSurfaces have been created with transfer_dst
and transfer_src | 1365 // We require that all vulkan GrSurfaces have been created with transfer_dst
and transfer_src |
1343 // as image usage flags. | 1366 // as image usage flags. |
1344 if (src->origin() == dst->origin() && | 1367 if (src->origin() == dst->origin() && |
1345 GrBytesPerPixel(src->config()) == GrBytesPerPixel(dst->config())) { | 1368 GrBytesPerPixel(src->config()) == GrBytesPerPixel(dst->config())) { |
1346 return true; | 1369 return true; |
1347 } | 1370 } |
1348 | 1371 |
1349 // How does msaa play into this? If a VkTexture is multisampled, are we copy
ing the multisampled | |
1350 // or the resolved image here? Im multisampled, Vulkan requires sample count
s to be the same. | |
1351 | |
1352 return false; | 1372 return false; |
1353 } | 1373 } |
1354 | 1374 |
1355 void GrVkGpu::copySurfaceAsCopyImage(GrSurface* dst, | 1375 void GrVkGpu::copySurfaceAsCopyImage(GrSurface* dst, |
1356 GrSurface* src, | 1376 GrSurface* src, |
1357 GrVkImage* dstImage, | 1377 GrVkImage* dstImage, |
1358 GrVkImage* srcImage, | 1378 GrVkImage* srcImage, |
1359 const SkIRect& srcRect, | 1379 const SkIRect& srcRect, |
1360 const SkIPoint& dstPoint) { | 1380 const SkIPoint& dstPoint) { |
1361 SkASSERT(can_copy_image(dst, src, this)); | 1381 SkASSERT(can_copy_image(dst, src, this)); |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1493 fCurrentCmdBuffer->blitImage(this, | 1513 fCurrentCmdBuffer->blitImage(this, |
1494 *srcImage, | 1514 *srcImage, |
1495 *dstImage, | 1515 *dstImage, |
1496 1, | 1516 1, |
1497 &blitRegion, | 1517 &blitRegion, |
1498 VK_FILTER_NEAREST); // We never scale so any fi
lter works here | 1518 VK_FILTER_NEAREST); // We never scale so any fi
lter works here |
1499 | 1519 |
1500 this->didWriteToSurface(dst, &dstRect); | 1520 this->didWriteToSurface(dst, &dstRect); |
1501 } | 1521 } |
1502 | 1522 |
| 1523 inline bool can_copy_as_resolve(const GrSurface* dst, |
| 1524 const GrSurface* src, |
| 1525 const GrVkGpu* gpu) { |
| 1526 // Our src must be a multisampled render target |
| 1527 if (!src->asRenderTarget() || src->asRenderTarget()->numColorSamples() <= 1)
{ |
| 1528 return false; |
| 1529 } |
| 1530 |
| 1531 // The dst must be a render target but not multisampled |
| 1532 if (!dst->asRenderTarget() || dst->asRenderTarget()->numColorSamples() > 1)
{ |
| 1533 return false; |
| 1534 } |
| 1535 |
| 1536 // Surfaces must have the same origin. |
| 1537 if (src->origin() != dst->origin()) { |
| 1538 return false; |
| 1539 } |
| 1540 |
| 1541 return true; |
| 1542 } |
| 1543 |
| 1544 void GrVkGpu::copySurfaceAsResolve(GrSurface* dst, |
| 1545 GrSurface* src, |
| 1546 const SkIRect& srcRect, |
| 1547 const SkIPoint& dstPoint) { |
| 1548 GrVkRenderTarget* dstRT = static_cast<GrVkRenderTarget*>(dst->asRenderTarget
()); |
| 1549 GrVkRenderTarget* srcRT = static_cast<GrVkRenderTarget*>(src->asRenderTarget
()); |
| 1550 SkASSERT(dstRT && dstRT->numColorSamples() <= 1); |
| 1551 this->resolveImage(dstRT, srcRT, srcRect, dstPoint); |
| 1552 } |
| 1553 |
1503 inline bool can_copy_as_draw(const GrSurface* dst, | 1554 inline bool can_copy_as_draw(const GrSurface* dst, |
1504 const GrSurface* src, | 1555 const GrSurface* src, |
1505 const GrVkGpu* gpu) { | 1556 const GrVkGpu* gpu) { |
1506 return false; | 1557 return false; |
1507 } | 1558 } |
1508 | 1559 |
1509 void GrVkGpu::copySurfaceAsDraw(GrSurface* dst, | 1560 void GrVkGpu::copySurfaceAsDraw(GrSurface* dst, |
1510 GrSurface* src, | 1561 GrSurface* src, |
1511 const SkIRect& srcRect, | 1562 const SkIRect& srcRect, |
1512 const SkIPoint& dstPoint) { | 1563 const SkIPoint& dstPoint) { |
1513 SkASSERT(false); | 1564 SkASSERT(false); |
1514 } | 1565 } |
1515 | 1566 |
1516 bool GrVkGpu::onCopySurface(GrSurface* dst, | 1567 bool GrVkGpu::onCopySurface(GrSurface* dst, |
1517 GrSurface* src, | 1568 GrSurface* src, |
1518 const SkIRect& srcRect, | 1569 const SkIRect& srcRect, |
1519 const SkIPoint& dstPoint) { | 1570 const SkIPoint& dstPoint) { |
| 1571 if (can_copy_as_resolve(dst, src, this)) { |
| 1572 this->copySurfaceAsResolve(dst, src, srcRect, dstPoint); |
| 1573 } |
| 1574 |
1520 GrVkImage* dstImage; | 1575 GrVkImage* dstImage; |
1521 GrVkImage* srcImage; | 1576 GrVkImage* srcImage; |
1522 if (dst->asTexture()) { | 1577 GrRenderTarget* dstRT = dst->asRenderTarget(); |
| 1578 if (dstRT) { |
| 1579 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(dstRT); |
| 1580 dstImage = vkRT->numColorSamples() > 1 ? vkRT->msaaImage() : vkRT; |
| 1581 } else { |
| 1582 SkASSERT(dst->asTexture()); |
1523 dstImage = static_cast<GrVkTexture*>(dst->asTexture()); | 1583 dstImage = static_cast<GrVkTexture*>(dst->asTexture()); |
| 1584 } |
| 1585 GrRenderTarget* srcRT = src->asRenderTarget(); |
| 1586 if (srcRT) { |
| 1587 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(srcRT); |
| 1588 srcImage = vkRT->numColorSamples() > 1 ? vkRT->msaaImage() : vkRT; |
1524 } else { | 1589 } else { |
1525 SkASSERT(dst->asRenderTarget()); | 1590 SkASSERT(src->asTexture()); |
1526 dstImage = static_cast<GrVkRenderTarget*>(dst->asRenderTarget()); | |
1527 } | |
1528 if (src->asTexture()) { | |
1529 srcImage = static_cast<GrVkTexture*>(src->asTexture()); | 1591 srcImage = static_cast<GrVkTexture*>(src->asTexture()); |
1530 } else { | |
1531 SkASSERT(src->asRenderTarget()); | |
1532 srcImage = static_cast<GrVkRenderTarget*>(src->asRenderTarget()); | |
1533 } | 1592 } |
1534 | 1593 |
1535 if (can_copy_image(dst, src, this)) { | 1594 if (can_copy_image(dst, src, this)) { |
1536 this->copySurfaceAsCopyImage(dst, src, dstImage, srcImage, srcRect, dstP
oint); | 1595 this->copySurfaceAsCopyImage(dst, src, dstImage, srcImage, srcRect, dstP
oint); |
1537 return true; | 1596 return true; |
1538 } | 1597 } |
1539 | 1598 |
1540 if (can_copy_as_blit(dst, src, dstImage, srcImage, this)) { | 1599 if (can_copy_as_blit(dst, src, dstImage, srcImage, this)) { |
1541 this->copySurfaceAsBlit(dst, src, dstImage, srcImage, srcRect, dstPoint)
; | 1600 this->copySurfaceAsBlit(dst, src, dstImage, srcImage, srcRect, dstPoint)
; |
1542 return true; | 1601 return true; |
1543 } | 1602 } |
1544 | 1603 |
1545 if (can_copy_as_draw(dst, src, this)) { | 1604 if (can_copy_as_draw(dst, src, this)) { |
1546 this->copySurfaceAsDraw(dst, src, srcRect, dstPoint); | 1605 this->copySurfaceAsDraw(dst, src, srcRect, dstPoint); |
1547 return true; | 1606 return true; |
1548 } | 1607 } |
1549 | 1608 |
1550 return false; | 1609 return false; |
1551 } | 1610 } |
1552 | 1611 |
1553 bool GrVkGpu::initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc)
const { | 1612 bool GrVkGpu::initDescForDstCopy(const GrRenderTarget* src, GrSurfaceDesc* desc)
const { |
1554 // Currently we don't support msaa | 1613 // We can always succeed here with either a CopyImage (none msaa src) or Res
olveImage (msaa). |
1555 if (src->asRenderTarget() && src->asRenderTarget()->numColorSamples() > 1) { | 1614 // For CopyImage we can make a simple texture, for ResolveImage we require t
he dst to be a |
1556 return false; | 1615 // render target as well. |
1557 } | |
1558 | |
1559 // This will support copying the dst as CopyImage since all of our surfaces
require transferSrc | |
1560 // and transferDst usage flags in Vulkan. | |
1561 desc->fOrigin = src->origin(); | 1616 desc->fOrigin = src->origin(); |
1562 desc->fConfig = src->config(); | 1617 desc->fConfig = src->config(); |
1563 desc->fFlags = kNone_GrSurfaceFlags; | 1618 desc->fFlags = src->numColorSamples() > 1 ? kRenderTarget_GrSurfaceFlag : kN
one_GrSurfaceFlags; |
1564 return true; | 1619 return true; |
1565 } | 1620 } |
1566 | 1621 |
1567 void GrVkGpu::onGetMultisampleSpecs(GrRenderTarget* rt, const GrStencilSettings&
, | 1622 void GrVkGpu::onGetMultisampleSpecs(GrRenderTarget* rt, const GrStencilSettings&
, |
1568 int* effectiveSampleCnt, SamplePattern*) { | 1623 int* effectiveSampleCnt, SamplePattern*) { |
1569 // TODO: stub. | 1624 // TODO: stub. |
1570 SkASSERT(!this->caps()->sampleLocationsSupport()); | 1625 SkASSERT(!this->caps()->sampleLocationsSupport()); |
1571 *effectiveSampleCnt = rt->desc().fSampleCnt; | 1626 *effectiveSampleCnt = rt->desc().fSampleCnt; |
1572 } | 1627 } |
1573 | 1628 |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1775 // Currently it is fine for us to always pass in 1 for the clear count even
if no attachment | 1830 // Currently it is fine for us to always pass in 1 for the clear count even
if no attachment |
1776 // uses it. In the current state, we also only use the LOAD_OP_CLEAR for the
color attachment | 1831 // uses it. In the current state, we also only use the LOAD_OP_CLEAR for the
color attachment |
1777 // which is always at the first attachment. | 1832 // which is always at the first attachment. |
1778 fCurrentCmdBuffer->beginRenderPass(this, renderPass, 1, colorClear, *target,
*pBounds, true); | 1833 fCurrentCmdBuffer->beginRenderPass(this, renderPass, 1, colorClear, *target,
*pBounds, true); |
1779 fCurrentCmdBuffer->executeCommands(this, buffer); | 1834 fCurrentCmdBuffer->executeCommands(this, buffer); |
1780 fCurrentCmdBuffer->endRenderPass(this); | 1835 fCurrentCmdBuffer->endRenderPass(this); |
1781 | 1836 |
1782 this->didWriteToSurface(target, &bounds); | 1837 this->didWriteToSurface(target, &bounds); |
1783 } | 1838 } |
1784 | 1839 |
OLD | NEW |