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

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

Issue 2294533002: Add some copy support for vulkan msaa (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: cleanup Created 4 years, 3 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
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"
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
OLDNEW
« src/gpu/GrGpu.h ('K') | « src/gpu/vk/GrVkGpu.h ('k') | src/gpu/vk/GrVkRenderTarget.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698