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

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: Update initDesc name 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
« no previous file with comments | « src/gpu/vk/GrVkGpu.h ('k') | src/gpu/vk/GrVkRenderTarget.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 911 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
OLDNEW
« no previous file with comments | « 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