Beispiel #1
0
        public void CopyTo(ITexture destination, int srcLayer, int dstLayer, int srcLevel, int dstLevel)
        {
            _gd.FlushAllCommands();

            var src = this;
            var dst = (TextureView)destination;

            if (!Valid || !dst.Valid)
            {
                return;
            }

            using var cbs = _gd.CommandBufferPool.Rent();

            var srcImage = src.GetImage().Get(cbs).Value;
            var dstImage = dst.GetImage().Get(cbs).Value;

            TextureCopy.Copy(
                _gd.Api,
                cbs.CommandBuffer,
                srcImage,
                dstImage,
                src.Info,
                dst.Info,
                src.FirstLayer,
                dst.FirstLayer,
                src.FirstLevel,
                dst.FirstLevel,
                srcLayer,
                dstLayer,
                srcLevel,
                dstLevel,
                1,
                1);
        }
Beispiel #2
0
        public void CopyTo(ITexture destination, int firstLayer, int firstLevel)
        {
            var src = this;
            var dst = (TextureView)destination;

            if (!Valid || !dst.Valid)
            {
                return;
            }

            _gd.PipelineInternal.EndRenderPass();

            var cbs = _gd.PipelineInternal.CurrentCommandBuffer;

            var srcImage = src.GetImage().Get(cbs).Value;
            var dstImage = dst.GetImage().Get(cbs).Value;

            if (src.Info.Target.IsMultisample())
            {
                int depth  = Math.Min(src.Info.Depth, dst.Info.Depth - firstLayer);
                int levels = Math.Min(src.Info.Levels, dst.Info.Levels - firstLevel);

                CopyMSToNonMS(_gd, cbs, src, dst, srcImage, dstImage, 0, firstLayer, 0, firstLevel, depth, levels);
            }
            else
            {
                TextureCopy.Copy(
                    _gd.Api,
                    cbs.CommandBuffer,
                    srcImage,
                    dstImage,
                    src.Info,
                    dst.Info,
                    src.FirstLayer,
                    dst.FirstLayer,
                    src.FirstLevel,
                    dst.FirstLevel,
                    0,
                    firstLayer,
                    0,
                    firstLevel);
            }
        }
Beispiel #3
0
        private void CopyToImpl(CommandBufferScoped cbs, TextureView dst, Extents2D srcRegion, Extents2D dstRegion, bool linearFilter)
        {
            var src = this;

            var srcFormat = GetCompatibleGalFormat(src.Info.Format);
            var dstFormat = GetCompatibleGalFormat(dst.Info.Format);

            bool srcUsesStorageFormat = src.VkFormat == src.Storage.VkFormat;
            bool dstUsesStorageFormat = dst.VkFormat == dst.Storage.VkFormat;

            int layers = Math.Min(dst.Info.GetDepthOrLayers(), src.Info.GetDepthOrLayers());
            int levels = Math.Min(dst.Info.Levels, src.Info.Levels);

            if (srcUsesStorageFormat && dstUsesStorageFormat)
            {
                if ((srcRegion.X1 | dstRegion.X1) == 0 &&
                    (srcRegion.Y1 | dstRegion.Y1) == 0 &&
                    srcRegion.X2 == src.Width &&
                    srcRegion.Y2 == src.Height &&
                    dstRegion.X2 == dst.Width &&
                    dstRegion.Y2 == dst.Height &&
                    src.Width == dst.Width &&
                    src.Height == dst.Height &&
                    src.VkFormat == dst.VkFormat)
                {
                    TextureCopy.Copy(
                        _gd.Api,
                        cbs.CommandBuffer,
                        src.GetImage().Get(cbs).Value,
                        dst.GetImage().Get(cbs).Value,
                        src.Info,
                        dst.Info,
                        src.FirstLayer,
                        dst.FirstLayer,
                        src.FirstLevel,
                        dst.FirstLevel,
                        0,
                        0,
                        0,
                        0,
                        layers,
                        levels);

                    return;
                }
                else if (_gd.FormatCapabilities.FormatSupports(srcFormat, FormatFeatureFlags.FormatFeatureBlitSrcBit) &&
                         _gd.FormatCapabilities.FormatSupports(dstFormat, FormatFeatureFlags.FormatFeatureBlitDstBit))
                {
                    TextureCopy.Blit(
                        _gd.Api,
                        cbs.CommandBuffer,
                        src.GetImage().Get(cbs).Value,
                        dst.GetImage().Get(cbs).Value,
                        src.Info,
                        dst.Info,
                        srcRegion,
                        dstRegion,
                        src.FirstLayer,
                        dst.FirstLayer,
                        src.FirstLevel,
                        dst.FirstLevel,
                        layers,
                        levels,
                        linearFilter);

                    return;
                }
                else if (srcFormat == GAL.Format.D32FloatS8Uint && srcFormat == dstFormat && SupportsBlitFromD32FS8ToD32FAndS8())
                {
                    var d32StorageInfo = TextureStorage.NewCreateInfoWith(src.Info, GAL.Format.D32Float, 4);
                    var s8StorageInfo  = TextureStorage.NewCreateInfoWith(dst.Info, GAL.Format.S8Uint, 1);

                    using var d32Storage = _gd.CreateTextureStorage(d32StorageInfo, dst.Storage.ScaleFactor);
                    using var s8Storage  = _gd.CreateTextureStorage(s8StorageInfo, dst.Storage.ScaleFactor);

                    void BlitAndCopy(ref TextureCreateInfo info, TextureStorage storage, ImageAspectFlags aspectFlags)
                    {
                        TextureCopy.Blit(
                            _gd.Api,
                            cbs.CommandBuffer,
                            src.GetImage().Get(cbs).Value,
                            storage.GetImage().Get(cbs).Value,
                            src.Info,
                            info,
                            srcRegion,
                            dstRegion,
                            src.FirstLayer,
                            0,
                            src.FirstLevel,
                            0,
                            layers,
                            levels,
                            false,
                            aspectFlags,
                            aspectFlags);

                        TextureCopy.Copy(
                            _gd.Api,
                            cbs.CommandBuffer,
                            storage.GetImage().Get(cbs).Value,
                            dst.GetImage().Get(cbs).Value,
                            info,
                            dst.Info,
                            0,
                            dst.FirstLayer,
                            0,
                            dst.FirstLevel,
                            0,
                            0,
                            0,
                            0,
                            layers,
                            levels);
                    }

                    BlitAndCopy(ref d32StorageInfo, d32Storage, ImageAspectFlags.ImageAspectDepthBit);
                    BlitAndCopy(ref s8StorageInfo, s8Storage, ImageAspectFlags.ImageAspectStencilBit);

                    return;
                }
            }

            if (VulkanConfiguration.UseSlowSafeBlitOnAmd &&
                _gd.Vendor == Vendor.Amd &&
                src.Info.Target == Target.Texture2D &&
                dst.Info.Target == Target.Texture2D &&
                !dst.Info.Format.IsDepthOrStencil())
            {
                _gd.HelperShader.Blit(
                    _gd,
                    src,
                    dst.GetIdentityImageView(),
                    dst.Width,
                    dst.Height,
                    dst.VkFormat,
                    srcRegion,
                    dstRegion,
                    linearFilter);

                return;
            }

            Auto <DisposableImage> srcImage;
            Auto <DisposableImage> dstImage;

            if (dst.Info.Format.IsDepthOrStencil())
            {
                srcImage = src.Storage.CreateAliasedColorForDepthStorageUnsafe(srcFormat).GetImage();
                dstImage = dst.Storage.CreateAliasedColorForDepthStorageUnsafe(dstFormat).GetImage();
            }
            else
            {
                srcImage = src.Storage.CreateAliasedStorageUnsafe(srcFormat).GetImage();
                dstImage = dst.Storage.CreateAliasedStorageUnsafe(dstFormat).GetImage();
            }

            TextureCopy.Blit(
                _gd.Api,
                cbs.CommandBuffer,
                srcImage.Get(cbs).Value,
                dstImage.Get(cbs).Value,
                src.Info,
                dst.Info,
                srcRegion,
                dstRegion,
                src.FirstLevel,
                dst.FirstLevel,
                src.FirstLayer,
                dst.FirstLayer,
                layers,
                levels,
                linearFilter,
                ImageAspectFlags.ImageAspectColorBit,
                ImageAspectFlags.ImageAspectColorBit);
        }
Beispiel #4
0
        private static void CopyMSToNonMS(
            VulkanRenderer gd,
            CommandBufferScoped cbs,
            TextureView src,
            TextureView dst,
            Image srcImage,
            Image dstImage,
            int srcLayer,
            int dstLayer,
            int srcLevel,
            int dstLevel,
            int layers,
            int levels)
        {
            bool differentFormats = src.Info.Format != dst.Info.Format;

            var target = src.Info.Target switch
            {
                Target.Texture2D => Target.Texture2DMultisample,
                Target.Texture2DArray => Target.Texture2DMultisampleArray,
                Target.Texture2DMultisampleArray => Target.Texture2DArray,
                _ => Target.Texture2D
            };

            var intermmediateTarget = differentFormats ? dst.Info.Target : target;

            using var intermmediate = CreateIntermmediateTexture(gd, src, ref dst._info, intermmediateTarget, layers, levels);
            var intermmediateImage = intermmediate.GetImage().Get(cbs).Value;

            if (differentFormats)
            {
                // If the formats are different, the resolve would perform format conversion.
                // So we need yet another intermmediate texture and do a copy to reinterpret the
                // data into the correct (destination) format, without doing any sort of conversion.
                using var intermmediate2 = CreateIntermmediateTexture(gd, src, ref src._info, target, layers, levels);
                var intermmediate2Image = intermmediate2.GetImage().Get(cbs).Value;

                TextureCopy.Copy(
                    gd.Api,
                    cbs.CommandBuffer,
                    srcImage,
                    intermmediate2Image,
                    src.Info,
                    intermmediate2.Info,
                    src.FirstLayer,
                    0,
                    src.FirstLevel,
                    0,
                    srcLayer,
                    0,
                    srcLevel,
                    0,
                    layers,
                    levels);

                TextureCopy.Copy(
                    gd.Api,
                    cbs.CommandBuffer,
                    intermmediate2Image,
                    intermmediateImage,
                    intermmediate2.Info,
                    intermmediate.Info,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0,
                    layers,
                    levels);
            }
            else
            {
                TextureCopy.Copy(
                    gd.Api,
                    cbs.CommandBuffer,
                    srcImage,
                    intermmediateImage,
                    src.Info,
                    intermmediate.Info,
                    src.FirstLayer,
                    0,
                    src.FirstLevel,
                    0,
                    srcLayer,
                    0,
                    srcLevel,
                    0,
                    layers,
                    levels);
            }

            var srcRegion = new Extents2D(0, 0, src.Width, src.Height);
            var dstRegion = new Extents2D(0, 0, dst.Width, dst.Height);

            TextureCopy.Blit(
                gd.Api,
                cbs.CommandBuffer,
                intermmediateImage,
                dstImage,
                intermmediate.Info,
                dst.Info,
                srcRegion,
                dstRegion,
                0,
                dst.FirstLevel + dstLevel,
                0,
                dst.FirstLayer + dstLayer,
                layers,
                levels,
                true,
                ImageAspectFlags.ImageAspectColorBit,
                ImageAspectFlags.ImageAspectColorBit);
        }
Beispiel #5
0
        private void CopyToImpl(CommandBufferScoped cbs, TextureView dst, Extents2D srcRegion, Extents2D dstRegion, bool linearFilter)
        {
            var src = this;

            var srcFormat = GetCompatibleGalFormat(src.Info.Format);
            var dstFormat = GetCompatibleGalFormat(dst.Info.Format);

            bool srcUsesStorageFormat = src.VkFormat == src.Storage.VkFormat;
            bool dstUsesStorageFormat = dst.VkFormat == dst.Storage.VkFormat;

            if (srcUsesStorageFormat && dstUsesStorageFormat)
            {
                if ((srcRegion.X1 | dstRegion.X1) == 0 &&
                    (srcRegion.Y1 | dstRegion.Y1) == 0 &&
                    srcRegion.X2 == src.Width &&
                    srcRegion.Y2 == src.Height &&
                    dstRegion.X2 == dst.Width &&
                    dstRegion.Y2 == dst.Height &&
                    src.Width == dst.Width &&
                    src.Height == dst.Height &&
                    src.VkFormat == dst.VkFormat)
                {
                    TextureCopy.Copy(
                        _gd.Api,
                        cbs.CommandBuffer,
                        src.GetImage().Get(cbs).Value,
                        dst.GetImage().Get(cbs).Value,
                        src.Info,
                        dst.Info,
                        src.FirstLayer,
                        dst.FirstLayer,
                        src.FirstLevel,
                        dst.FirstLevel,
                        0,
                        0,
                        0,
                        0,
                        1,
                        1);

                    return;
                }
                else if (_gd.FormatCapabilities.FormatSupports(srcFormat, FormatFeatureFlags.FormatFeatureBlitSrcBit) &&
                         _gd.FormatCapabilities.FormatSupports(dstFormat, FormatFeatureFlags.FormatFeatureBlitDstBit))
                {
                    TextureCopy.Blit(
                        _gd.Api,
                        cbs.CommandBuffer,
                        src.GetImage().Get(cbs).Value,
                        dst.GetImage().Get(cbs).Value,
                        src.Info,
                        dst.Info,
                        srcRegion,
                        dstRegion,
                        src.FirstLayer,
                        dst.FirstLayer,
                        src.FirstLevel,
                        dst.FirstLevel,
                        linearFilter);

                    return;
                }
            }

            Auto <DisposableImage> srcImage;
            Auto <DisposableImage> dstImage;

            if (dst.Info.Format.IsDepthOrStencil())
            {
                srcImage = src.Storage.CreateAliasedColorForDepthStorageUnsafe(srcFormat).GetImage();
                dstImage = dst.Storage.CreateAliasedColorForDepthStorageUnsafe(dstFormat).GetImage();
            }
            else
            {
                srcImage = src.Storage.CreateAliasedStorageUnsafe(srcFormat).GetImage();
                dstImage = dst.Storage.CreateAliasedStorageUnsafe(dstFormat).GetImage();
            }

            TextureCopy.Blit(
                _gd.Api,
                cbs.CommandBuffer,
                srcImage.Get(cbs).Value,
                dstImage.Get(cbs).Value,
                src.Info,
                dst.Info,
                srcRegion,
                dstRegion,
                src.FirstLevel,
                dst.FirstLevel,
                src.FirstLayer,
                dst.FirstLayer,
                linearFilter,
                forceColorAspect: true);
        }