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 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
277 tempDrawInfo->fTempSurfaceDesc.fConfig = srcConfig; | 277 tempDrawInfo->fTempSurfaceDesc.fConfig = srcConfig; |
278 tempDrawInfo->fTempSurfaceDesc.fWidth = width; | 278 tempDrawInfo->fTempSurfaceDesc.fWidth = width; |
279 tempDrawInfo->fTempSurfaceDesc.fHeight = height; | 279 tempDrawInfo->fTempSurfaceDesc.fHeight = height; |
280 tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 0; | 280 tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 0; |
281 tempDrawInfo->fTempSurfaceDesc.fOrigin = kTopLeft_GrSurfaceOrigin; | 281 tempDrawInfo->fTempSurfaceDesc.fOrigin = kTopLeft_GrSurfaceOrigin; |
282 | 282 |
283 if (dstSurface->config() == srcConfig) { | 283 if (dstSurface->config() == srcConfig) { |
284 return true; | 284 return true; |
285 } | 285 } |
286 | 286 |
287 if (renderTarget && this->vkCaps().isConfigRenderable(renderTarget->config() , false)) { | 287 if (renderTarget && this->vkCaps().isConfigRenderable(renderTarget->config() , |
288 renderTarget->numColor Samples() > 1)) { | |
288 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); | 289 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); |
289 | 290 |
290 bool configsAreRBSwaps = GrPixelConfigSwapRAndB(srcConfig) == dstSurface ->config(); | 291 bool configsAreRBSwaps = GrPixelConfigSwapRAndB(srcConfig) == dstSurface ->config(); |
291 | 292 |
292 if (!this->vkCaps().isConfigTexturable(srcConfig) && configsAreRBSwaps) { | 293 if (!this->vkCaps().isConfigTexturable(srcConfig) && configsAreRBSwaps) { |
293 if (!this->vkCaps().isConfigTexturable(dstSurface->config())) { | 294 if (!this->vkCaps().isConfigTexturable(dstSurface->config())) { |
294 return false; | 295 return false; |
295 } | 296 } |
296 tempDrawInfo->fTempSurfaceDesc.fConfig = dstSurface->config(); | 297 tempDrawInfo->fTempSurfaceDesc.fConfig = dstSurface->config(); |
297 tempDrawInfo->fSwizzle = GrSwizzle::BGRA(); | 298 tempDrawInfo->fSwizzle = GrSwizzle::BGRA(); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
359 } | 360 } |
360 } | 361 } |
361 success = this->uploadTexDataOptimal(vkTex, left, top, width, height , config, texels); | 362 success = this->uploadTexDataOptimal(vkTex, left, top, width, height , config, texels); |
362 } | 363 } |
363 } | 364 } |
364 | 365 |
365 return success; | 366 return success; |
366 } | 367 } |
367 | 368 |
368 void GrVkGpu::onResolveRenderTarget(GrRenderTarget* target) { | 369 void GrVkGpu::onResolveRenderTarget(GrRenderTarget* target) { |
369 if (target->needsResolve() && target->numColorSamples() > 1) { | 370 if (target->needsResolve()) { |
371 SkASSERT(target->numColorSamples() > 1); | |
egdaniel
2016/08/05 19:07:15
going back to this. Returning getResolveType as au
| |
370 GrVkRenderTarget* rt = static_cast<GrVkRenderTarget*>(target); | 372 GrVkRenderTarget* rt = static_cast<GrVkRenderTarget*>(target); |
371 SkASSERT(rt->msaaImage()); | 373 SkASSERT(rt->msaaImage()); |
372 | 374 |
373 // Flip rect if necessary | 375 // Flip rect if necessary |
374 SkIRect srcVkRect = rt->getResolveRect(); | 376 SkIRect srcVkRect = rt->getResolveRect(); |
375 | 377 |
376 if (kBottomLeft_GrSurfaceOrigin == rt->origin()) { | 378 if (kBottomLeft_GrSurfaceOrigin == rt->origin()) { |
377 srcVkRect.fTop = rt->height() - rt->getResolveRect().fBottom; | 379 srcVkRect.fTop = rt->height() - rt->getResolveRect().fBottom; |
378 srcVkRect.fBottom = rt->height() - rt->getResolveRect().fTop; | 380 srcVkRect.fBottom = rt->height() - rt->getResolveRect().fTop; |
379 } | 381 } |
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
810 return tgt; | 812 return tgt; |
811 } | 813 } |
812 | 814 |
813 void GrVkGpu::generateMipmap(GrVkTexture* tex) { | 815 void GrVkGpu::generateMipmap(GrVkTexture* tex) { |
814 // don't do anything for linearly tiled textures (can't have mipmaps) | 816 // don't do anything for linearly tiled textures (can't have mipmaps) |
815 if (tex->isLinearTiled()) { | 817 if (tex->isLinearTiled()) { |
816 SkDebugf("Trying to create mipmap for linear tiled texture"); | 818 SkDebugf("Trying to create mipmap for linear tiled texture"); |
817 return; | 819 return; |
818 } | 820 } |
819 | 821 |
820 // We currently don't support generating mipmaps for images that are multisa mpled. | |
821 // TODO: Add support for mipmapping the resolve target of a multisampled ima ge | |
822 if (tex->asRenderTarget() && tex->asRenderTarget()->numColorSamples() > 1) { | |
823 return; | |
824 } | |
825 | |
826 // determine if we can blit to and from this format | 822 // determine if we can blit to and from this format |
827 const GrVkCaps& caps = this->vkCaps(); | 823 const GrVkCaps& caps = this->vkCaps(); |
828 if (!caps.configCanBeDstofBlit(tex->config(), false) || | 824 if (!caps.configCanBeDstofBlit(tex->config(), false) || |
829 !caps.configCanBeSrcofBlit(tex->config(), false) || | 825 !caps.configCanBeSrcofBlit(tex->config(), false) || |
830 !caps.mipMapSupport()) { | 826 !caps.mipMapSupport()) { |
831 return; | 827 return; |
832 } | 828 } |
833 | 829 |
830 // We may need to resolve the texture first if it is also a render target | |
831 GrVkRenderTarget* texRT = static_cast<GrVkRenderTarget*>(tex->asRenderTarget ()); | |
832 if (texRT) { | |
833 this->onResolveRenderTarget(texRT); | |
834 } | |
835 | |
834 int width = tex->width(); | 836 int width = tex->width(); |
835 int height = tex->height(); | 837 int height = tex->height(); |
836 VkImageBlit blitRegion; | 838 VkImageBlit blitRegion; |
837 memset(&blitRegion, 0, sizeof(VkImageBlit)); | 839 memset(&blitRegion, 0, sizeof(VkImageBlit)); |
838 | 840 |
839 // SkMipMap doesn't include the base level in the level count so we have to add 1 | 841 // SkMipMap doesn't include the base level in the level count so we have to add 1 |
840 uint32_t levelCount = SkMipMap::ComputeLevelCount(tex->width(), tex->height( )) + 1; | 842 uint32_t levelCount = SkMipMap::ComputeLevelCount(tex->width(), tex->height( )) + 1; |
841 if (levelCount != tex->mipLevels()) { | 843 if (levelCount != tex->mipLevels()) { |
842 const GrVkResource* oldResource = tex->resource(); | 844 const GrVkResource* oldResource = tex->resource(); |
843 oldResource->ref(); | 845 oldResource->ref(); |
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1255 SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, | 1257 SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, |
1256 srcRect.width(), srcRect.height()); | 1258 srcRect.width(), srcRect.height()); |
1257 this->didWriteToSurface(dst, &dstRect); | 1259 this->didWriteToSurface(dst, &dstRect); |
1258 } | 1260 } |
1259 | 1261 |
1260 inline bool can_copy_as_blit(const GrSurface* dst, | 1262 inline bool can_copy_as_blit(const GrSurface* dst, |
1261 const GrSurface* src, | 1263 const GrSurface* src, |
1262 const GrVkImage* dstImage, | 1264 const GrVkImage* dstImage, |
1263 const GrVkImage* srcImage, | 1265 const GrVkImage* srcImage, |
1264 const GrVkGpu* gpu) { | 1266 const GrVkGpu* gpu) { |
1265 // We require that all vulkan GrSurfaces have been created with transfer_dst and transfer_src | 1267 // We require that all vulkan GrSurfaces have been created with transfer_dst and transfer_src |
1266 // as image usage flags. | 1268 // as image usage flags. |
1267 const GrVkCaps& caps = gpu->vkCaps(); | 1269 const GrVkCaps& caps = gpu->vkCaps(); |
1268 if (!caps.configCanBeDstofBlit(dst->config(), dstImage->isLinearTiled()) || | 1270 if (!caps.configCanBeDstofBlit(dst->config(), dstImage->isLinearTiled()) || |
1269 !caps.configCanBeSrcofBlit(src->config(), srcImage->isLinearTiled())) { | 1271 !caps.configCanBeSrcofBlit(src->config(), srcImage->isLinearTiled())) { |
1270 return false; | 1272 return false; |
1271 } | 1273 } |
1272 | 1274 |
1273 // We cannot blit images that are multisampled. Will need to figure out if w e can blit the | 1275 // We cannot blit images that are multisampled. Will need to figure out if w e can blit the |
1274 // resolved msaa though. | 1276 // resolved msaa though. |
1275 if ((dst->asRenderTarget() && dst->asRenderTarget()->numColorSamples() > 1) || | 1277 if ((dst->asRenderTarget() && dst->asRenderTarget()->numColorSamples() > 1) || |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1437 // from will be srcConfig and we will read readConfig pixels from it. | 1439 // from will be srcConfig and we will read readConfig pixels from it. |
1438 // Not that if we require a draw and return a non-renderable format for the temp surface the | 1440 // Not that if we require a draw and return a non-renderable format for the temp surface the |
1439 // base class will fail for us. | 1441 // base class will fail for us. |
1440 tempDrawInfo->fTempSurfaceDesc.fConfig = srcSurface->config(); | 1442 tempDrawInfo->fTempSurfaceDesc.fConfig = srcSurface->config(); |
1441 tempDrawInfo->fReadConfig = readConfig; | 1443 tempDrawInfo->fReadConfig = readConfig; |
1442 | 1444 |
1443 if (srcSurface->config() == readConfig) { | 1445 if (srcSurface->config() == readConfig) { |
1444 return true; | 1446 return true; |
1445 } | 1447 } |
1446 | 1448 |
1447 if (this->vkCaps().isConfigRenderable(readConfig, false)) { | 1449 if (this->vkCaps().isConfigRenderable(readConfig, srcSurface->desc().fSample Cnt > 1)) { |
1448 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); | 1450 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); |
1449 tempDrawInfo->fTempSurfaceDesc.fConfig = readConfig; | 1451 tempDrawInfo->fTempSurfaceDesc.fConfig = readConfig; |
1450 tempDrawInfo->fReadConfig = readConfig; | 1452 tempDrawInfo->fReadConfig = readConfig; |
1451 return true; | 1453 return true; |
1452 } | 1454 } |
1453 | 1455 |
1454 return false; | 1456 return false; |
1455 } | 1457 } |
1456 | 1458 |
1457 bool GrVkGpu::onReadPixels(GrSurface* surface, | 1459 bool GrVkGpu::onReadPixels(GrSurface* surface, |
1458 int left, int top, int width, int height, | 1460 int left, int top, int width, int height, |
1459 GrPixelConfig config, | 1461 GrPixelConfig config, |
1460 void* buffer, | 1462 void* buffer, |
1461 size_t rowBytes) { | 1463 size_t rowBytes) { |
1462 VkFormat pixelFormat; | 1464 VkFormat pixelFormat; |
1463 if (!GrPixelConfigToVkFormat(config, &pixelFormat)) { | 1465 if (!GrPixelConfigToVkFormat(config, &pixelFormat)) { |
1464 return false; | 1466 return false; |
1465 } | 1467 } |
1466 | 1468 |
1467 GrVkTexture* tgt = static_cast<GrVkTexture*>(surface->asTexture()); | 1469 GrVkImage* image = nullptr; |
1468 if (!tgt) { | 1470 GrVkRenderTarget* rt = static_cast<GrVkRenderTarget*>(surface->asRenderTarge t()); |
Brian Osman
2016/08/18 13:28:22
This is the only place where you're doing the extr
egdaniel
2016/08/18 13:31:39
Yeah I can move it up there. I was actually just c
egdaniel
2016/08/18 13:36:23
Actually I see the reasoning now. onResolveRenderT
| |
1471 if (rt) { | |
1472 // resolve the render target if necessary | |
1473 switch (rt->getResolveType()) { | |
1474 case GrVkRenderTarget::kCantResolve_ResolveType: | |
1475 return false; | |
1476 case GrVkRenderTarget::kAutoResolves_ResolveType: | |
1477 break; | |
1478 case GrVkRenderTarget::kCanResolve_ResolveType: | |
1479 this->onResolveRenderTarget(rt); | |
1480 break; | |
1481 default: | |
1482 SkFAIL("Unknown resolve type"); | |
1483 } | |
1484 image = rt; | |
1485 } else { | |
1486 image = static_cast<GrVkTexture*>(surface->asTexture()); | |
1487 } | |
1488 | |
1489 if (!image) { | |
1469 return false; | 1490 return false; |
1470 } | 1491 } |
1471 | 1492 |
1472 // Change layout of our target so it can be used as copy | 1493 // Change layout of our target so it can be used as copy |
1473 tgt->setImageLayout(this, | 1494 image->setImageLayout(this, |
1474 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, | 1495 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, |
1475 VK_ACCESS_TRANSFER_READ_BIT, | 1496 VK_ACCESS_TRANSFER_READ_BIT, |
1476 VK_PIPELINE_STAGE_TRANSFER_BIT, | 1497 VK_PIPELINE_STAGE_TRANSFER_BIT, |
1477 false); | 1498 false); |
1478 | 1499 |
1479 GrVkTransferBuffer* transferBuffer = | 1500 GrVkTransferBuffer* transferBuffer = |
1480 static_cast<GrVkTransferBuffer*>(this->createBuffer(rowBytes * height, | 1501 static_cast<GrVkTransferBuffer*>(this->createBuffer(rowBytes * height, |
1481 kXferGpuToCpu_GrBuff erType, | 1502 kXferGpuToCpu_GrBuff erType, |
1482 kStream_GrAccessPatt ern)); | 1503 kStream_GrAccessPatt ern)); |
1483 | 1504 |
1484 bool flipY = kBottomLeft_GrSurfaceOrigin == surface->origin(); | 1505 bool flipY = kBottomLeft_GrSurfaceOrigin == surface->origin(); |
1485 VkOffset3D offset = { | 1506 VkOffset3D offset = { |
1486 left, | 1507 left, |
1487 flipY ? surface->height() - top - height : top, | 1508 flipY ? surface->height() - top - height : top, |
1488 0 | 1509 0 |
1489 }; | 1510 }; |
1490 | 1511 |
1491 // Copy the image to a buffer so we can map it to cpu memory | 1512 // Copy the image to a buffer so we can map it to cpu memory |
1492 VkBufferImageCopy region; | 1513 VkBufferImageCopy region; |
1493 memset(®ion, 0, sizeof(VkBufferImageCopy)); | 1514 memset(®ion, 0, sizeof(VkBufferImageCopy)); |
1494 region.bufferOffset = transferBuffer->offset(); | 1515 region.bufferOffset = transferBuffer->offset(); |
1495 region.bufferRowLength = 0; // Forces RowLength to be width. We handle the r owBytes below. | 1516 region.bufferRowLength = 0; // Forces RowLength to be width. We handle the r owBytes below. |
1496 region.bufferImageHeight = 0; // Forces height to be tightly packed. Only us eful for 3d images. | 1517 region.bufferImageHeight = 0; // Forces height to be tightly packed. Only us eful for 3d images. |
1497 region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; | 1518 region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; |
1498 region.imageOffset = offset; | 1519 region.imageOffset = offset; |
1499 region.imageExtent = { (uint32_t)width, (uint32_t)height, 1 }; | 1520 region.imageExtent = { (uint32_t)width, (uint32_t)height, 1 }; |
1500 | 1521 |
1501 fCurrentCmdBuffer->copyImageToBuffer(this, | 1522 fCurrentCmdBuffer->copyImageToBuffer(this, |
1502 tgt, | 1523 image, |
1503 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, | 1524 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, |
1504 transferBuffer, | 1525 transferBuffer, |
1505 1, | 1526 1, |
1506 ®ion); | 1527 ®ion); |
1507 | 1528 |
1508 // make sure the copy to buffer has finished | 1529 // make sure the copy to buffer has finished |
1509 transferBuffer->addMemoryBarrier(this, | 1530 transferBuffer->addMemoryBarrier(this, |
1510 VK_ACCESS_TRANSFER_WRITE_BIT, | 1531 VK_ACCESS_TRANSFER_WRITE_BIT, |
1511 VK_ACCESS_HOST_READ_BIT, | 1532 VK_ACCESS_HOST_READ_BIT, |
1512 VK_PIPELINE_STAGE_TRANSFER_BIT, | 1533 VK_PIPELINE_STAGE_TRANSFER_BIT, |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1600 target->width(), target->height()); | 1621 target->width(), target->height()); |
1601 pBounds = &adjustedBounds; | 1622 pBounds = &adjustedBounds; |
1602 } | 1623 } |
1603 | 1624 |
1604 // Currently it is fine for us to always pass in 1 for the clear count even if no attachment | 1625 // Currently it is fine for us to always pass in 1 for the clear count even if no attachment |
1605 // uses it. In the current state, we also only use the LOAD_OP_CLEAR for the color attachment | 1626 // uses it. In the current state, we also only use the LOAD_OP_CLEAR for the color attachment |
1606 // which is always at the first attachment. | 1627 // which is always at the first attachment. |
1607 fCurrentCmdBuffer->beginRenderPass(this, renderPass, 1, colorClear, *target, *pBounds, true); | 1628 fCurrentCmdBuffer->beginRenderPass(this, renderPass, 1, colorClear, *target, *pBounds, true); |
1608 fCurrentCmdBuffer->executeCommands(this, buffer); | 1629 fCurrentCmdBuffer->executeCommands(this, buffer); |
1609 fCurrentCmdBuffer->endRenderPass(this); | 1630 fCurrentCmdBuffer->endRenderPass(this); |
1631 | |
1632 this->didWriteToSurface(target, pBounds); | |
1610 } | 1633 } |
1611 | 1634 |
OLD | NEW |