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 759 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
770 return tgt; | 770 return tgt; |
771 } | 771 } |
772 | 772 |
773 void GrVkGpu::generateMipmap(GrVkTexture* tex) { | 773 void GrVkGpu::generateMipmap(GrVkTexture* tex) { |
774 // don't do anything for linearly tiled textures (can't have mipmaps) | 774 // don't do anything for linearly tiled textures (can't have mipmaps) |
775 if (tex->isLinearTiled()) { | 775 if (tex->isLinearTiled()) { |
776 SkDebugf("Trying to create mipmap for linear tiled texture"); | 776 SkDebugf("Trying to create mipmap for linear tiled texture"); |
777 return; | 777 return; |
778 } | 778 } |
779 | 779 |
780 // We cannot generate mipmaps for images that are multisampled. | 780 // We currently don't support generating mipmaps for images that are multisa mpled. |
781 // TODO: does it even make sense for rendertargets in general? | 781 // TODO: Add support for mipmapping the resolve target of a multisampled ima ge |
782 if (tex->asRenderTarget() && tex->asRenderTarget()->numColorSamples() > 1) { | 782 if (tex->asRenderTarget() && tex->asRenderTarget()->numColorSamples() > 1) { |
783 return; | 783 return; |
784 } | 784 } |
785 | 785 |
786 // determine if we can blit to and from this format | 786 // determine if we can blit to and from this format |
787 const GrVkCaps& caps = this->vkCaps(); | 787 const GrVkCaps& caps = this->vkCaps(); |
788 if (!caps.configCanBeDstofBlit(tex->config(), false) || | 788 if (!caps.configCanBeDstofBlit(tex->config(), false) || |
789 !caps.configCanBeSrcofBlit(tex->config(), false) || | 789 !caps.configCanBeSrcofBlit(tex->config(), false) || |
790 !caps.mipMapSupport()) { | 790 !caps.mipMapSupport()) { |
791 return; | 791 return; |
792 } | 792 } |
793 | 793 |
794 // change the original image's layout | 794 int width = tex->width(); |
jvanverth1
2016/07/15 18:57:30
Move inside the conditional?
egdaniel
2016/07/15 19:02:06
It is used in the while loop (doing the blits) as
jvanverth1
2016/07/15 19:32:50
Ah, it was hidden. Cool beans.
| |
795 tex->setImageLayout(this, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, | 795 int height = tex->height(); |
796 VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_ BIT, false); | 796 VkImageBlit blitRegion; |
797 | 797 memset(&blitRegion, 0, sizeof(VkImageBlit)); |
798 // grab handle to the original image resource | |
799 const GrVkResource* oldResource = tex->resource(); | |
800 oldResource->ref(); | |
801 VkImage oldImage = tex->image(); | |
802 | 798 |
803 // SkMipMap doesn't include the base level in the level count so we have to add 1 | 799 // SkMipMap doesn't include the base level in the level count so we have to add 1 |
804 uint32_t levelCount = SkMipMap::ComputeLevelCount(tex->width(), tex->height( )) + 1; | 800 uint32_t levelCount = SkMipMap::ComputeLevelCount(tex->width(), tex->height( )) + 1; |
805 if (!tex->reallocForMipmap(this, levelCount)) { | 801 if (levelCount != tex->mipLevels()) { |
802 const GrVkResource* oldResource = tex->resource(); | |
803 oldResource->ref(); | |
804 // grab handle to the original image resource | |
805 VkImage oldImage = tex->image(); | |
806 | |
807 // change the original image's layout so we can copy from it | |
808 tex->setImageLayout(this, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, | |
809 VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANS FER_BIT, false); | |
810 | |
811 if (!tex->reallocForMipmap(this, levelCount)) { | |
812 oldResource->unref(this); | |
813 return; | |
814 } | |
815 // change the new image's layout so we can blit to it | |
816 tex->setImageLayout(this, VK_IMAGE_LAYOUT_GENERAL, | |
817 VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRAN SFER_BIT, false); | |
818 | |
819 // Blit original image to top level of new image | |
820 blitRegion.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; | |
821 blitRegion.srcOffsets[0] = { 0, 0, 0 }; | |
822 blitRegion.srcOffsets[1] = { width, height, 1 }; | |
823 blitRegion.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; | |
824 blitRegion.dstOffsets[0] = { 0, 0, 0 }; | |
825 blitRegion.dstOffsets[1] = { width, height, 1 }; | |
826 | |
827 fCurrentCmdBuffer->blitImage(this, | |
828 oldResource, | |
829 oldImage, | |
830 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, | |
831 tex->resource(), | |
832 tex->image(), | |
833 VK_IMAGE_LAYOUT_GENERAL, | |
834 1, | |
835 &blitRegion, | |
836 VK_FILTER_LINEAR); | |
837 | |
806 oldResource->unref(this); | 838 oldResource->unref(this); |
807 return; | 839 } else { |
840 // change layout of the layers so we can write to them. | |
841 tex->setImageLayout(this, VK_IMAGE_LAYOUT_GENERAL, | |
842 VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRAN SFER_BIT, false); | |
808 } | 843 } |
809 | 844 |
810 // change the new image's layout | |
811 tex->setImageLayout(this, VK_IMAGE_LAYOUT_GENERAL, | |
812 VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER _BIT, false); | |
813 | |
814 // Blit original image | |
815 int width = tex->width(); | |
816 int height = tex->height(); | |
817 | |
818 VkImageBlit blitRegion; | |
819 memset(&blitRegion, 0, sizeof(VkImageBlit)); | |
820 blitRegion.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; | |
821 blitRegion.srcOffsets[0] = { 0, 0, 0 }; | |
822 blitRegion.srcOffsets[1] = { width, height, 1 }; | |
823 blitRegion.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; | |
824 blitRegion.dstOffsets[0] = { 0, 0, 0 }; | |
825 blitRegion.dstOffsets[1] = { width, height, 1 }; | |
826 | |
827 fCurrentCmdBuffer->blitImage(this, | |
828 oldResource, | |
829 oldImage, | |
830 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, | |
831 tex->resource(), | |
832 tex->image(), | |
833 VK_IMAGE_LAYOUT_GENERAL, | |
834 1, | |
835 &blitRegion, | |
836 VK_FILTER_LINEAR); | |
837 | |
838 // setup memory barrier | 845 // setup memory barrier |
839 SkASSERT(GrVkFormatToPixelConfig(tex->imageFormat(), nullptr)); | 846 SkASSERT(GrVkFormatToPixelConfig(tex->imageFormat(), nullptr)); |
840 VkImageAspectFlags aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT; | 847 VkImageAspectFlags aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT; |
841 VkImageMemoryBarrier imageMemoryBarrier = { | 848 VkImageMemoryBarrier imageMemoryBarrier = { |
842 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType | 849 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType |
843 NULL, // pNext | 850 NULL, // pNext |
844 VK_ACCESS_TRANSFER_WRITE_BIT, // outputMask | 851 VK_ACCESS_TRANSFER_WRITE_BIT, // srcAccessMask |
845 VK_ACCESS_TRANSFER_READ_BIT, // inputMask | 852 VK_ACCESS_TRANSFER_READ_BIT, // dstAccessMask |
846 VK_IMAGE_LAYOUT_GENERAL, // oldLayout | 853 VK_IMAGE_LAYOUT_GENERAL, // oldLayout |
847 VK_IMAGE_LAYOUT_GENERAL, // newLayout | 854 VK_IMAGE_LAYOUT_GENERAL, // newLayout |
848 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex | 855 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex |
849 VK_QUEUE_FAMILY_IGNORED, // dstQueueFamilyIndex | 856 VK_QUEUE_FAMILY_IGNORED, // dstQueueFamilyIndex |
850 tex->image(), // image | 857 tex->image(), // image |
851 { aspectFlags, 0, 1, 0, 1 } // subresourceRange | 858 { aspectFlags, 0, 1, 0, 1 } // subresourceRange |
852 }; | 859 }; |
853 | 860 |
854 // Blit the miplevels | 861 // Blit the miplevels |
855 uint32_t mipLevel = 1; | 862 uint32_t mipLevel = 1; |
(...skipping 14 matching lines...) Expand all Loading... | |
870 blitRegion.dstOffsets[0] = { 0, 0, 0 }; | 877 blitRegion.dstOffsets[0] = { 0, 0, 0 }; |
871 blitRegion.dstOffsets[1] = { width, height, 1 }; | 878 blitRegion.dstOffsets[1] = { width, height, 1 }; |
872 fCurrentCmdBuffer->blitImage(this, | 879 fCurrentCmdBuffer->blitImage(this, |
873 *tex, | 880 *tex, |
874 *tex, | 881 *tex, |
875 1, | 882 1, |
876 &blitRegion, | 883 &blitRegion, |
877 VK_FILTER_LINEAR); | 884 VK_FILTER_LINEAR); |
878 ++mipLevel; | 885 ++mipLevel; |
879 } | 886 } |
880 | |
881 oldResource->unref(this); | |
882 } | 887 } |
883 | 888 |
884 //////////////////////////////////////////////////////////////////////////////// | 889 //////////////////////////////////////////////////////////////////////////////// |
885 | 890 |
886 GrStencilAttachment* GrVkGpu::createStencilAttachmentForRenderTarget(const GrRen derTarget* rt, | 891 GrStencilAttachment* GrVkGpu::createStencilAttachmentForRenderTarget(const GrRen derTarget* rt, |
887 int width, | 892 int width, |
888 int height) { | 893 int height) { |
889 SkASSERT(width >= rt->width()); | 894 SkASSERT(width >= rt->width()); |
890 SkASSERT(height >= rt->height()); | 895 SkASSERT(height >= rt->height()); |
891 | 896 |
(...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1557 } | 1562 } |
1558 | 1563 |
1559 // Currently it is fine for us to always pass in 1 for the clear count even if no attachment | 1564 // Currently it is fine for us to always pass in 1 for the clear count even if no attachment |
1560 // uses it. In the current state, we also only use the LOAD_OP_CLEAR for the color attachment | 1565 // uses it. In the current state, we also only use the LOAD_OP_CLEAR for the color attachment |
1561 // which is always at the first attachment. | 1566 // which is always at the first attachment. |
1562 fCurrentCmdBuffer->beginRenderPass(this, renderPass, 1, colorClear, *target, *pBounds, true); | 1567 fCurrentCmdBuffer->beginRenderPass(this, renderPass, 1, colorClear, *target, *pBounds, true); |
1563 fCurrentCmdBuffer->executeCommands(this, buffer); | 1568 fCurrentCmdBuffer->executeCommands(this, buffer); |
1564 fCurrentCmdBuffer->endRenderPass(this); | 1569 fCurrentCmdBuffer->endRenderPass(this); |
1565 } | 1570 } |
1566 | 1571 |
OLD | NEW |