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

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

Issue 1916563002: Add automatic generation of mipmaps to Vulkan (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Address comments Created 4 years, 8 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/GrVkImageView.h » ('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 451 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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 }
OLDNEW
« no previous file with comments | « src/gpu/vk/GrVkGpu.h ('k') | src/gpu/vk/GrVkImageView.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698