@@ -27,6 +27,16 @@ constexpr size_t kStagingBufferSize = 1024 * 16;
27
27
28
28
constexpr VkFormatFeatureFlags kBlitFeatureFlags =
29
29
VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT;
30
+
31
+ bool CanCopyWithDraw (RendererVk *renderer,
32
+ const vk::Format &srcFormat,
33
+ const vk::Format &destFormat)
34
+ {
35
+ return renderer->hasTextureFormatFeatureBits (srcFormat.vkTextureFormat ,
36
+ VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) &&
37
+ renderer->hasTextureFormatFeatureBits (destFormat.vkTextureFormat ,
38
+ VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT);
39
+ }
30
40
} // anonymous namespace
31
41
32
42
// StagingStorage implementation.
@@ -575,21 +585,25 @@ angle::Result TextureVk::copySubImageImpl(const gl::Context *context,
575
585
const vk::Format &destFormat = renderer->getFormat (internalFormat.sizedInternalFormat );
576
586
577
587
// TODO(syoussefi): Support draw path for when !mImage.valid(). http://anglebug.com/2958
578
- bool canDraw = mImage .valid () &&
579
- renderer->hasTextureFormatFeatureBits (srcFormat.vkTextureFormat ,
580
- VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) &&
581
- renderer->hasTextureFormatFeatureBits (destFormat.vkTextureFormat ,
582
- VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT);
588
+ bool canDraw = mImage .valid () && CanCopyWithDraw (renderer, srcFormat, destFormat);
589
+ bool forceCpuPath =
590
+ mImage .getLayerCount () > 1 && renderer->getFeatures ().forceCpuPathForCubeMapCopy ;
583
591
584
592
// If it's possible to perform the copy with a draw call, do that.
585
- if (canDraw)
593
+ if (canDraw && !forceCpuPath )
586
594
{
587
- ANGLE_TRY (ensureImageInitialized (contextVk));
595
+ RenderTargetVk *colorReadRT = framebufferVk->getColorReadRenderTarget ();
596
+ bool isViewportFlipY = contextVk->isViewportFlipEnabledForDrawFBO ();
597
+
598
+ // Layer count can only be 1 as the source is a framebuffer.
599
+ ASSERT (index .getLayerCount () == 1 );
588
600
589
- return copySubImageImplWithDraw (contextVk, index , modifiedDestOffset,
590
- gl::Offset (clippedSourceArea.x , clippedSourceArea.y , 0 ),
591
- gl::Extents (destArea.width , destArea.height , 1 ),
592
- framebufferVk);
601
+ ANGLE_TRY (copySubImageImplWithDraw (
602
+ contextVk, index , modifiedDestOffset, 0 , clippedSourceArea, isViewportFlipY, false ,
603
+ false , false , &colorReadRT->getImage (), colorReadRT->getReadImageView ()));
604
+
605
+ framebufferVk->getFramebuffer ()->addReadDependency (&mImage );
606
+ return angle::Result::Continue;
593
607
}
594
608
595
609
// Do a CPU readback that does the conversion, and then stage the change to the pixel buffer.
@@ -603,51 +617,6 @@ angle::Result TextureVk::copySubImageImpl(const gl::Context *context,
603
617
return angle::Result::Continue;
604
618
}
605
619
606
- angle::Result TextureVk::copySubImageImplWithDraw (ContextVk *contextVk,
607
- const gl::ImageIndex &index,
608
- const gl::Offset &destOffset,
609
- const gl::Offset &srcOffset,
610
- const gl::Extents &extents,
611
- FramebufferVk *source)
612
- {
613
- UtilsVk::CopyImageParameters params;
614
- params.srcOffset [0 ] = srcOffset.x ;
615
- params.srcOffset [1 ] = srcOffset.y ;
616
- params.srcExtents [0 ] = extents.width ;
617
- params.srcExtents [1 ] = extents.height ;
618
- params.destOffset [0 ] = destOffset.x ;
619
- params.destOffset [1 ] = destOffset.y ;
620
- params.srcMip = 0 ;
621
- params.srcHeight = source->getReadImageExtents ().height ;
622
- params.flipY = contextVk->isViewportFlipEnabledForDrawFBO ();
623
-
624
- uint32_t level = index .getLevelIndex ();
625
- uint32_t baseLayer = index .hasLayer () ? index .getLayerIndex () : 0 ;
626
- uint32_t layerCount = index .getLayerCount ();
627
-
628
- // TODO(syoussefi): currently this is only called from copy[Sub]Image,
629
- // where layer count can only be 1, and source's level and layer are both 0.
630
- // Once this code is expanded to cover copy[Sub]Texture, it should be
631
- // adapted to get single-layer/level image views of the source as well.
632
- // http://anglebug.com/2958
633
- ASSERT (layerCount == 1 );
634
- vk::ImageHelper *srcImage = &source->getColorReadRenderTarget ()->getImage ();
635
- vk::ImageView *srcView = source->getColorReadRenderTarget ()->getReadImageView ();
636
-
637
- for (uint32_t i = 0 ; i < layerCount; ++i)
638
- {
639
- vk::ImageView *destView;
640
- ANGLE_TRY (getLayerLevelDrawImageView (contextVk, baseLayer + i, level, &destView));
641
-
642
- ANGLE_TRY (contextVk->getRenderer ()->getUtils ().copyImage (contextVk, &mImage , destView,
643
- srcImage, srcView, params));
644
- }
645
-
646
- source->getFramebuffer ()->addReadDependency (&mImage );
647
-
648
- return angle::Result::Continue;
649
- }
650
-
651
620
angle::Result TextureVk::copySubTextureImpl (ContextVk *contextVk,
652
621
const gl::ImageIndex &index,
653
622
const gl::Offset &destOffset,
@@ -661,6 +630,28 @@ angle::Result TextureVk::copySubTextureImpl(ContextVk *contextVk,
661
630
{
662
631
RendererVk *renderer = contextVk->getRenderer ();
663
632
633
+ ANGLE_TRY (source->ensureImageInitialized (contextVk));
634
+
635
+ const vk::Format &sourceVkFormat = source->getImage ().getFormat ();
636
+ const vk::Format &destVkFormat = renderer->getFormat (destFormat.sizedInternalFormat );
637
+
638
+ // TODO(syoussefi): Support draw path for when !mImage.valid(). http://anglebug.com/2958
639
+ bool canDraw = mImage .valid () && CanCopyWithDraw (renderer, sourceVkFormat, destVkFormat);
640
+ bool forceCpuPath =
641
+ mImage .getLayerCount () > 1 && renderer->getFeatures ().forceCpuPathForCubeMapCopy ;
642
+
643
+ // If it's possible to perform the copy with a draw call, do that.
644
+ if (canDraw && !forceCpuPath)
645
+ {
646
+ ANGLE_TRY (copySubImageImplWithDraw (contextVk, index , destOffset, sourceLevel, sourceArea,
647
+ false , unpackFlipY, unpackPremultiplyAlpha,
648
+ unpackUnmultiplyAlpha, &source->getImage (),
649
+ &source->getReadImageView ()));
650
+
651
+ source->getImage ().addReadDependency (&mImage );
652
+ return angle::Result::Continue;
653
+ }
654
+
664
655
if (sourceLevel != 0 )
665
656
{
666
657
WARN () << " glCopyTextureCHROMIUM with sourceLevel != 0 not implemented." ;
@@ -671,9 +662,6 @@ angle::Result TextureVk::copySubTextureImpl(ContextVk *contextVk,
671
662
uint8_t *sourceData = nullptr ;
672
663
ANGLE_TRY (source->copyImageDataToBuffer (contextVk, sourceLevel, 1 , sourceArea, &sourceData));
673
664
674
- const vk::Format &sourceVkFormat = source->getImage ().getFormat ();
675
- const vk::Format &destVkFormat = renderer->getFormat (destFormat.sizedInternalFormat );
676
-
677
665
const angle::Format &sourceTextureFormat = sourceVkFormat.textureFormat ();
678
666
const angle::Format &destTextureFormat = destVkFormat.textureFormat ();
679
667
size_t destinationAllocationSize =
@@ -716,6 +704,53 @@ angle::Result TextureVk::copySubTextureImpl(ContextVk *contextVk,
716
704
return angle::Result::Continue;
717
705
}
718
706
707
+ angle::Result TextureVk::copySubImageImplWithDraw (ContextVk *contextVk,
708
+ const gl::ImageIndex &index,
709
+ const gl::Offset &destOffset,
710
+ size_t sourceLevel,
711
+ const gl::Rectangle &sourceArea,
712
+ bool isSrcFlipY,
713
+ bool unpackFlipY,
714
+ bool unpackPremultiplyAlpha,
715
+ bool unpackUnmultiplyAlpha,
716
+ vk::ImageHelper *srcImage,
717
+ const vk::ImageView *srcView)
718
+ {
719
+ ANGLE_TRY (ensureImageInitialized (contextVk));
720
+
721
+ UtilsVk &utilsVk = contextVk->getRenderer ()->getUtils ();
722
+
723
+ UtilsVk::CopyImageParameters params;
724
+ params.srcOffset [0 ] = sourceArea.x ;
725
+ params.srcOffset [1 ] = sourceArea.y ;
726
+ params.srcExtents [0 ] = sourceArea.width ;
727
+ params.srcExtents [1 ] = sourceArea.height ;
728
+ params.destOffset [0 ] = destOffset.x ;
729
+ params.destOffset [1 ] = destOffset.y ;
730
+ params.srcMip = sourceLevel;
731
+ params.srcHeight = srcImage->getExtents ().height ;
732
+ params.srcPremultiplyAlpha = unpackPremultiplyAlpha && !unpackUnmultiplyAlpha;
733
+ params.srcUnmultiplyAlpha = unpackUnmultiplyAlpha && !unpackPremultiplyAlpha;
734
+ params.srcFlipY = isSrcFlipY;
735
+ params.destFlipY = unpackFlipY;
736
+
737
+ uint32_t level = index .getLevelIndex ();
738
+ uint32_t baseLayer = index .hasLayer () ? index .getLayerIndex () : 0 ;
739
+ uint32_t layerCount = index .getLayerCount ();
740
+
741
+ for (uint32_t layerIndex = 0 ; layerIndex < layerCount; ++layerIndex)
742
+ {
743
+ params.srcLayer = layerIndex;
744
+
745
+ vk::ImageView *destView;
746
+ ANGLE_TRY (getLayerLevelDrawImageView (contextVk, baseLayer + layerIndex, level, &destView));
747
+
748
+ ANGLE_TRY (utilsVk.copyImage (contextVk, &mImage , destView, srcImage, srcView, params));
749
+ }
750
+
751
+ return angle::Result::Continue;
752
+ }
753
+
719
754
angle::Result TextureVk::setStorage (const gl::Context *context,
720
755
gl::TextureType type,
721
756
size_t levels,
0 commit comments