| 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 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 } | 462 } |
| 463 | 463 |
| 464 VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_SAMPLED_BIT; | 464 VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_SAMPLED_BIT; |
| 465 if (renderTarget) { | 465 if (renderTarget) { |
| 466 usageFlags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; | 466 usageFlags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; |
| 467 } | 467 } |
| 468 | 468 |
| 469 // For now we will set the VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT and | 469 // For now we will set the VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT and |
| 470 // VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT on every texture since we do not know
whether or not we | 470 // VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT on every texture since we do not know
whether or not we |
| 471 // will be using this texture in some copy or not. Also this assumes, as is
the current case, | 471 // will be using this texture in some copy or not. Also this assumes, as is
the current case, |
| 472 // that all render targets in vulkan are also texutres. If we change this pr
actice of setting | 472 // that all render targets in vulkan are also textures. If we change this pr
actice of setting |
| 473 // both bits, we must make sure to set the destination bit if we are uploadi
ng srcData to the | 473 // both bits, we must make sure to set the destination bit if we are uploadi
ng srcData to the |
| 474 // texture. | 474 // texture. |
| 475 usageFlags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_
BIT; | 475 usageFlags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_
BIT; |
| 476 | 476 |
| 477 VkFlags memProps = (!texels.empty() && linearTiling) ? VK_MEMORY_PROPERTY_HO
ST_VISIBLE_BIT : | 477 VkFlags memProps = (!texels.empty() && linearTiling) ? VK_MEMORY_PROPERTY_HO
ST_VISIBLE_BIT : |
| 478 VK_MEMORY_PROPERTY_DE
VICE_LOCAL_BIT; | 478 VK_MEMORY_PROPERTY_DE
VICE_LOCAL_BIT; |
| 479 | 479 |
| 480 // This ImageDesc refers to the texture that will be read by the client. Thu
s even if msaa is | 480 // This ImageDesc refers to the texture that will be read by the client. Thu
s even if msaa is |
| 481 // requested, this ImageDesc describes the resolved texutre. Therefore we al
ways have samples set | 481 // requested, this ImageDesc describes the resolved texture. Therefore we al
ways have samples set |
| 482 // to 1. | 482 // to 1. |
| 483 GrVkImage::ImageDesc imageDesc; | 483 GrVkImage::ImageDesc imageDesc; |
| 484 imageDesc.fImageType = VK_IMAGE_TYPE_2D; | 484 imageDesc.fImageType = VK_IMAGE_TYPE_2D; |
| 485 imageDesc.fFormat = pixelFormat; | 485 imageDesc.fFormat = pixelFormat; |
| 486 imageDesc.fWidth = desc.fWidth; | 486 imageDesc.fWidth = desc.fWidth; |
| 487 imageDesc.fHeight = desc.fHeight; | 487 imageDesc.fHeight = desc.fHeight; |
| 488 imageDesc.fLevels = 1; | 488 imageDesc.fLevels = 1; // TODO: support miplevels for optimal tiling |
| 489 imageDesc.fSamples = 1; | 489 imageDesc.fSamples = 1; |
| 490 imageDesc.fImageTiling = linearTiling ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TI
LING_OPTIMAL; | 490 imageDesc.fImageTiling = linearTiling ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TI
LING_OPTIMAL; |
| 491 imageDesc.fUsageFlags = usageFlags; | 491 imageDesc.fUsageFlags = usageFlags; |
| 492 imageDesc.fMemProps = memProps; | 492 imageDesc.fMemProps = memProps; |
| 493 | 493 |
| 494 GrVkTexture* tex; | 494 GrVkTexture* tex; |
| 495 if (renderTarget) { | 495 if (renderTarget) { |
| 496 tex = GrVkTextureRenderTarget::CreateNewTextureRenderTarget(this, budget
ed, desc, | 496 tex = GrVkTextureRenderTarget::CreateNewTextureRenderTarget(this, budget
ed, desc, |
| 497 imageDesc); | 497 imageDesc); |
| 498 } else { | 498 } else { |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 599 info); | 599 info); |
| 600 if (tgt && wrapDesc.fStencilBits) { | 600 if (tgt && wrapDesc.fStencilBits) { |
| 601 if (!createStencilAttachmentForRenderTarget(tgt, desc.fWidth, desc.fHeig
ht)) { | 601 if (!createStencilAttachmentForRenderTarget(tgt, desc.fWidth, desc.fHeig
ht)) { |
| 602 tgt->unref(); | 602 tgt->unref(); |
| 603 return nullptr; | 603 return nullptr; |
| 604 } | 604 } |
| 605 } | 605 } |
| 606 return tgt; | 606 return tgt; |
| 607 } | 607 } |
| 608 | 608 |
| 609 void GrVkGpu::generateMipmap(GrVkTexture* tex) const { |
| 610 // don't need to do anything for linearly tiled textures (can't have mipmaps
) |
| 611 if (tex->isLinearTiled()) { |
| 612 return; |
| 613 } |
| 614 |
| 615 // We cannot generate mipmaps for images that are multisampled. |
| 616 // TODO: does it even make sense for rendertargets in general? |
| 617 if (tex->asRenderTarget() && tex->asRenderTarget()->numColorSamples() > 1) { |
| 618 return; |
| 619 } |
| 620 |
| 621 // determine if we can blit to and from this format |
| 622 const GrVkCaps& caps = this->vkCaps(); |
| 623 if (!caps.configCanBeDstofBlit(tex->config(), false) || |
| 624 !caps.configCanBeSrcofBlit(tex->config(), false)) { |
| 625 return; |
| 626 } |
| 627 |
| 628 // change the original image's layout |
| 629 VkImageLayout origSrcLayout = tex->currentLayout(); |
| 630 VkPipelineStageFlags srcStageMask = GrVkMemory::LayoutToPipelineStageFlags(o
rigSrcLayout); |
| 631 VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT; |
| 632 |
| 633 VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(origSrcLayou
t); |
| 634 VkAccessFlags dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; |
| 635 |
| 636 tex->setImageLayout(this, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, |
| 637 srcAccessMask, dstAccessMask, srcStageMask, dstStageMask
, false); |
| 638 |
| 639 // grab handle to the original image resource |
| 640 const GrVkImage::Resource* oldResource = tex->resource(); |
| 641 oldResource->ref(); |
| 642 |
| 643 if (!tex->reallocForMipmap(this)) { |
| 644 oldResource->unref(this); |
| 645 return; |
| 646 } |
| 647 |
| 648 // change the new image's layout |
| 649 VkImageLayout origDstLayout = tex->currentLayout(); |
| 650 |
| 651 srcStageMask = GrVkMemory::LayoutToPipelineStageFlags(origDstLayout); |
| 652 dstStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT; |
| 653 |
| 654 srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(origDstLayout); |
| 655 dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; |
| 656 |
| 657 tex->setImageLayout(this, |
| 658 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, |
| 659 srcAccessMask, |
| 660 dstAccessMask, |
| 661 srcStageMask, |
| 662 dstStageMask, |
| 663 false); |
| 664 |
| 665 // Blit original image |
| 666 int width = tex->width(); |
| 667 int height = tex->height(); |
| 668 uint32_t mipLevel = 0; |
| 669 |
| 670 VkImageBlit blitRegion; |
| 671 memset(&blitRegion, 0, sizeof(VkImageBlit)); |
| 672 blitRegion.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; |
| 673 blitRegion.srcOffsets[0] = { 0, 0, 0 }; |
| 674 blitRegion.srcOffsets[1] = { width, height, 0 }; |
| 675 blitRegion.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, mipLevel, 0, 1 }; |
| 676 blitRegion.dstOffsets[0] = { 0, 0, 0 }; |
| 677 blitRegion.dstOffsets[1] = { width, height, 0 }; |
| 678 |
| 679 fCurrentCmdBuffer->blitImage(this, |
| 680 oldResource, |
| 681 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, |
| 682 tex->resource(), |
| 683 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, |
| 684 1, |
| 685 &blitRegion, |
| 686 VK_FILTER_LINEAR); |
| 687 // Blit the miplevels |
| 688 while (width/2 > 0 && height/2 > 0) { |
| 689 blitRegion.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, mipLevel, 0, 1
}; |
| 690 blitRegion.srcOffsets[0] = { 0, 0, 0 }; |
| 691 blitRegion.srcOffsets[1] = { width, height, 0 }; |
| 692 blitRegion.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, mipLevel+1, 0,
1 }; |
| 693 blitRegion.dstOffsets[0] = { 0, 0, 0 }; |
| 694 blitRegion.dstOffsets[1] = { width/2, height/2, 0 }; |
| 695 |
| 696 fCurrentCmdBuffer->blitImage(this, |
| 697 tex->resource(), |
| 698 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, |
| 699 tex->resource(), |
| 700 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, |
| 701 1, |
| 702 &blitRegion, |
| 703 VK_FILTER_LINEAR); |
| 704 |
| 705 width /= 2; |
| 706 height /= 2; |
| 707 mipLevel++; |
| 708 } |
| 709 |
| 710 oldResource->unref(this); |
| 711 } |
| 712 |
| 713 |
| 714 |
| 609 //////////////////////////////////////////////////////////////////////////////// | 715 //////////////////////////////////////////////////////////////////////////////// |
| 610 | 716 |
| 611 void GrVkGpu::bindGeometry(const GrPrimitiveProcessor& primProc, | 717 void GrVkGpu::bindGeometry(const GrPrimitiveProcessor& primProc, |
| 612 const GrNonInstancedMesh& mesh) { | 718 const GrNonInstancedMesh& mesh) { |
| 613 // There is no need to put any memory barriers to make sure host writes have
finished here. | 719 // There is no need to put any memory barriers to make sure host writes have
finished here. |
| 614 // When a command buffer is submitted to a queue, there is an implicit memor
y barrier that | 720 // When a command buffer is submitted to a queue, there is an implicit memor
y barrier that |
| 615 // occurs for all host writes. Additionally, BufferMemoryBarriers are not al
lowed inside of | 721 // occurs for all host writes. Additionally, BufferMemoryBarriers are not al
lowed inside of |
| 616 // an active RenderPass. | 722 // an active RenderPass. |
| 617 GrVkVertexBuffer* vbuf; | 723 GrVkVertexBuffer* vbuf; |
| 618 vbuf = (GrVkVertexBuffer*)mesh.vertexBuffer(); | 724 vbuf = (GrVkVertexBuffer*)mesh.vertexBuffer(); |
| (...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1261 VkImageBlit blitRegion; | 1367 VkImageBlit blitRegion; |
| 1262 memset(&blitRegion, 0, sizeof(VkImageBlit)); | 1368 memset(&blitRegion, 0, sizeof(VkImageBlit)); |
| 1263 blitRegion.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; | 1369 blitRegion.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; |
| 1264 blitRegion.srcOffsets[0] = { srcVkRect.fLeft, srcVkRect.fTop, 0 }; | 1370 blitRegion.srcOffsets[0] = { srcVkRect.fLeft, srcVkRect.fTop, 0 }; |
| 1265 blitRegion.srcOffsets[1] = { srcVkRect.fRight, srcVkRect.fBottom, 0 }; | 1371 blitRegion.srcOffsets[1] = { srcVkRect.fRight, srcVkRect.fBottom, 0 }; |
| 1266 blitRegion.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; | 1372 blitRegion.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; |
| 1267 blitRegion.dstOffsets[0] = { dstRect.fLeft, dstRect.fTop, 0 }; | 1373 blitRegion.dstOffsets[0] = { dstRect.fLeft, dstRect.fTop, 0 }; |
| 1268 blitRegion.dstOffsets[1] = { dstRect.fRight, dstRect.fBottom, 0 }; | 1374 blitRegion.dstOffsets[1] = { dstRect.fRight, dstRect.fBottom, 0 }; |
| 1269 | 1375 |
| 1270 fCurrentCmdBuffer->blitImage(this, | 1376 fCurrentCmdBuffer->blitImage(this, |
| 1271 srcImage, | 1377 srcImage->resource(), |
| 1272 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, | 1378 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, |
| 1273 dstImage, | 1379 dstImage->resource(), |
| 1274 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, | 1380 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, |
| 1275 1, | 1381 1, |
| 1276 &blitRegion, | 1382 &blitRegion, |
| 1277 VK_FILTER_NEAREST); // We never scale so any fi
lter works here | 1383 VK_FILTER_NEAREST); // We never scale so any fi
lter works here |
| 1278 } | 1384 } |
| 1279 | 1385 |
| 1280 inline bool can_copy_as_draw(const GrSurface* dst, | 1386 inline bool can_copy_as_draw(const GrSurface* dst, |
| 1281 const GrSurface* src, | 1387 const GrSurface* src, |
| 1282 const GrVkGpu* gpu) { | 1388 const GrVkGpu* gpu) { |
| 1283 return false; | 1389 return false; |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1601 aglSwapBuffers(aglGetCurrentContext()); | 1707 aglSwapBuffers(aglGetCurrentContext()); |
| 1602 int set_a_break_pt_here = 9; | 1708 int set_a_break_pt_here = 9; |
| 1603 aglSwapBuffers(aglGetCurrentContext()); | 1709 aglSwapBuffers(aglGetCurrentContext()); |
| 1604 #elif defined(SK_BUILD_FOR_WIN32) | 1710 #elif defined(SK_BUILD_FOR_WIN32) |
| 1605 SwapBuf(); | 1711 SwapBuf(); |
| 1606 int set_a_break_pt_here = 9; | 1712 int set_a_break_pt_here = 9; |
| 1607 SwapBuf(); | 1713 SwapBuf(); |
| 1608 #endif | 1714 #endif |
| 1609 #endif | 1715 #endif |
| 1610 } | 1716 } |
| OLD | NEW |