diff options
| author | TSR Berry <20988865+TSRBerry@users.noreply.github.com> | 2023-04-08 01:22:00 +0200 |
|---|---|---|
| committer | Mary <thog@protonmail.com> | 2023-04-27 23:51:14 +0200 |
| commit | cee712105850ac3385cd0091a923438167433f9f (patch) | |
| tree | 4a5274b21d8b7f938c0d0ce18736d3f2993b11b1 /Ryujinx.Graphics.Vulkan/TextureStorage.cs | |
| parent | cd124bda587ef09668a971fa1cac1c3f0cfc9f21 (diff) | |
Move solution and projects to src
Diffstat (limited to 'Ryujinx.Graphics.Vulkan/TextureStorage.cs')
| -rw-r--r-- | Ryujinx.Graphics.Vulkan/TextureStorage.cs | 530 |
1 files changed, 0 insertions, 530 deletions
diff --git a/Ryujinx.Graphics.Vulkan/TextureStorage.cs b/Ryujinx.Graphics.Vulkan/TextureStorage.cs deleted file mode 100644 index 0582e6ca..00000000 --- a/Ryujinx.Graphics.Vulkan/TextureStorage.cs +++ /dev/null @@ -1,530 +0,0 @@ -using Ryujinx.Common; -using Ryujinx.Graphics.GAL; -using Silk.NET.Vulkan; -using System; -using System.Collections.Generic; -using System.Numerics; -using VkBuffer = Silk.NET.Vulkan.Buffer; -using VkFormat = Silk.NET.Vulkan.Format; - -namespace Ryujinx.Graphics.Vulkan -{ - class TextureStorage : IDisposable - { - private const MemoryPropertyFlags DefaultImageMemoryFlags = - MemoryPropertyFlags.DeviceLocalBit; - - private const ImageUsageFlags DefaultUsageFlags = - ImageUsageFlags.SampledBit | - ImageUsageFlags.TransferSrcBit | - ImageUsageFlags.TransferDstBit; - - public const AccessFlags DefaultAccessMask = - AccessFlags.ShaderReadBit | - AccessFlags.ShaderWriteBit | - AccessFlags.ColorAttachmentReadBit | - AccessFlags.ColorAttachmentWriteBit | - AccessFlags.DepthStencilAttachmentReadBit | - AccessFlags.DepthStencilAttachmentWriteBit | - AccessFlags.TransferReadBit | - AccessFlags.TransferWriteBit; - - private readonly VulkanRenderer _gd; - - private readonly Device _device; - - private TextureCreateInfo _info; - - public TextureCreateInfo Info => _info; - - private readonly Image _image; - private readonly Auto<DisposableImage> _imageAuto; - private readonly Auto<MemoryAllocation> _allocationAuto; - private Auto<MemoryAllocation> _foreignAllocationAuto; - - private Dictionary<GAL.Format, TextureStorage> _aliasedStorages; - - private AccessFlags _lastModificationAccess; - private PipelineStageFlags _lastModificationStage; - private AccessFlags _lastReadAccess; - private PipelineStageFlags _lastReadStage; - - private int _viewsCount; - private ulong _size; - - public VkFormat VkFormat { get; } - public float ScaleFactor { get; } - - public unsafe TextureStorage( - VulkanRenderer gd, - Device device, - TextureCreateInfo info, - float scaleFactor, - Auto<MemoryAllocation> foreignAllocation = null) - { - _gd = gd; - _device = device; - _info = info; - ScaleFactor = scaleFactor; - - var format = _gd.FormatCapabilities.ConvertToVkFormat(info.Format); - var levels = (uint)info.Levels; - var layers = (uint)info.GetLayers(); - var depth = (uint)(info.Target == Target.Texture3D ? info.Depth : 1); - - VkFormat = format; - - var type = info.Target.Convert(); - - var extent = new Extent3D((uint)info.Width, (uint)info.Height, depth); - - var sampleCountFlags = ConvertToSampleCountFlags(gd.Capabilities.SupportedSampleCounts, (uint)info.Samples); - - var usage = GetImageUsageFromFormat(info.Format); - - var flags = ImageCreateFlags.CreateMutableFormatBit; - - // This flag causes mipmapped texture arrays to break on AMD GCN, so for that copy dependencies are forced for aliasing as cube. - bool isCube = info.Target == Target.Cubemap || info.Target == Target.CubemapArray; - bool cubeCompatible = gd.IsAmdGcn ? isCube : (info.Width == info.Height && layers >= 6); - - if (type == ImageType.Type2D && cubeCompatible) - { - flags |= ImageCreateFlags.CreateCubeCompatibleBit; - } - - if (type == ImageType.Type3D && !gd.Capabilities.PortabilitySubset.HasFlag(PortabilitySubsetFlags.No3DImageView)) - { - flags |= ImageCreateFlags.Create2DArrayCompatibleBit; - } - - var imageCreateInfo = new ImageCreateInfo() - { - SType = StructureType.ImageCreateInfo, - ImageType = type, - Format = format, - Extent = extent, - MipLevels = levels, - ArrayLayers = layers, - Samples = sampleCountFlags, - Tiling = ImageTiling.Optimal, - Usage = usage, - SharingMode = SharingMode.Exclusive, - InitialLayout = ImageLayout.Undefined, - Flags = flags - }; - - gd.Api.CreateImage(device, imageCreateInfo, null, out _image).ThrowOnError(); - - if (foreignAllocation == null) - { - gd.Api.GetImageMemoryRequirements(device, _image, out var requirements); - var allocation = gd.MemoryAllocator.AllocateDeviceMemory(requirements, DefaultImageMemoryFlags); - - if (allocation.Memory.Handle == 0UL) - { - gd.Api.DestroyImage(device, _image, null); - throw new Exception("Image initialization failed."); - } - - _size = requirements.Size; - - gd.Api.BindImageMemory(device, _image, allocation.Memory, allocation.Offset).ThrowOnError(); - - _allocationAuto = new Auto<MemoryAllocation>(allocation); - _imageAuto = new Auto<DisposableImage>(new DisposableImage(_gd.Api, device, _image), null, _allocationAuto); - - InitialTransition(ImageLayout.Undefined, ImageLayout.General); - } - else - { - _foreignAllocationAuto = foreignAllocation; - foreignAllocation.IncrementReferenceCount(); - var allocation = foreignAllocation.GetUnsafe(); - - gd.Api.BindImageMemory(device, _image, allocation.Memory, allocation.Offset).ThrowOnError(); - - _imageAuto = new Auto<DisposableImage>(new DisposableImage(_gd.Api, device, _image)); - - InitialTransition(ImageLayout.Preinitialized, ImageLayout.General); - } - } - - public TextureStorage CreateAliasedColorForDepthStorageUnsafe(GAL.Format format) - { - var colorFormat = format switch - { - GAL.Format.S8Uint => GAL.Format.R8Unorm, - GAL.Format.D16Unorm => GAL.Format.R16Unorm, - GAL.Format.S8UintD24Unorm => GAL.Format.R8G8B8A8Unorm, - GAL.Format.D32Float => GAL.Format.R32Float, - GAL.Format.D24UnormS8Uint => GAL.Format.R8G8B8A8Unorm, - GAL.Format.D32FloatS8Uint => GAL.Format.R32G32Float, - _ => throw new ArgumentException($"\"{format}\" is not a supported depth or stencil format.") - }; - - return CreateAliasedStorageUnsafe(colorFormat); - } - - public TextureStorage CreateAliasedStorageUnsafe(GAL.Format format) - { - if (_aliasedStorages == null || !_aliasedStorages.TryGetValue(format, out var storage)) - { - _aliasedStorages ??= new Dictionary<GAL.Format, TextureStorage>(); - - var info = NewCreateInfoWith(ref _info, format, _info.BytesPerPixel); - - storage = new TextureStorage(_gd, _device, info, ScaleFactor, _allocationAuto); - - _aliasedStorages.Add(format, storage); - } - - return storage; - } - - public static TextureCreateInfo NewCreateInfoWith(ref TextureCreateInfo info, GAL.Format format, int bytesPerPixel) - { - return NewCreateInfoWith(ref info, format, bytesPerPixel, info.Width, info.Height); - } - - public static TextureCreateInfo NewCreateInfoWith( - ref TextureCreateInfo info, - GAL.Format format, - int bytesPerPixel, - int width, - int height) - { - return new TextureCreateInfo( - width, - height, - info.Depth, - info.Levels, - info.Samples, - info.BlockWidth, - info.BlockHeight, - bytesPerPixel, - format, - info.DepthStencilMode, - info.Target, - info.SwizzleR, - info.SwizzleG, - info.SwizzleB, - info.SwizzleA); - } - - public Auto<DisposableImage> GetImage() - { - return _imageAuto; - } - - public Image GetImageForViewCreation() - { - return _image; - } - - public bool HasCommandBufferDependency(CommandBufferScoped cbs) - { - if (_foreignAllocationAuto != null) - { - return _foreignAllocationAuto.HasCommandBufferDependency(cbs); - } - else if (_allocationAuto != null) - { - return _allocationAuto.HasCommandBufferDependency(cbs); - } - - return false; - } - - private unsafe void InitialTransition(ImageLayout srcLayout, ImageLayout dstLayout) - { - CommandBufferScoped cbs; - bool useTempCbs = !_gd.CommandBufferPool.OwnedByCurrentThread; - - if (useTempCbs) - { - cbs = _gd.BackgroundResources.Get().GetPool().Rent(); - } - else - { - if (_gd.PipelineInternal != null) - { - cbs = _gd.PipelineInternal.GetPreloadCommandBuffer(); - } - else - { - cbs = _gd.CommandBufferPool.Rent(); - useTempCbs = true; - } - } - - var aspectFlags = _info.Format.ConvertAspectFlags(); - - var subresourceRange = new ImageSubresourceRange(aspectFlags, 0, (uint)_info.Levels, 0, (uint)_info.GetLayers()); - - var barrier = new ImageMemoryBarrier() - { - SType = StructureType.ImageMemoryBarrier, - SrcAccessMask = 0, - DstAccessMask = DefaultAccessMask, - OldLayout = srcLayout, - NewLayout = dstLayout, - SrcQueueFamilyIndex = Vk.QueueFamilyIgnored, - DstQueueFamilyIndex = Vk.QueueFamilyIgnored, - Image = _imageAuto.Get(cbs).Value, - SubresourceRange = subresourceRange - }; - - _gd.Api.CmdPipelineBarrier( - cbs.CommandBuffer, - PipelineStageFlags.TopOfPipeBit, - PipelineStageFlags.AllCommandsBit, - 0, - 0, - null, - 0, - null, - 1, - barrier); - - if (useTempCbs) - { - cbs.Dispose(); - } - } - - public static ImageUsageFlags GetImageUsageFromFormat(GAL.Format format) - { - var usage = DefaultUsageFlags; - - if (format.IsDepthOrStencil()) - { - usage |= ImageUsageFlags.DepthStencilAttachmentBit; - } - else if (format.IsRtColorCompatible()) - { - usage |= ImageUsageFlags.ColorAttachmentBit; - } - - if (format.IsImageCompatible()) - { - usage |= ImageUsageFlags.StorageBit; - } - - return usage; - } - - public static SampleCountFlags ConvertToSampleCountFlags(SampleCountFlags supportedSampleCounts, uint samples) - { - if (samples == 0 || samples > (uint)SampleCountFlags.Count64Bit) - { - return SampleCountFlags.Count1Bit; - } - - // Round up to the nearest power of two. - SampleCountFlags converted = (SampleCountFlags)(1u << (31 - BitOperations.LeadingZeroCount(samples))); - - // Pick nearest sample count that the host actually supports. - while (converted != SampleCountFlags.Count1Bit && (converted & supportedSampleCounts) == 0) - { - converted = (SampleCountFlags)((uint)converted >> 1); - } - - return converted; - } - - public TextureView CreateView(TextureCreateInfo info, int firstLayer, int firstLevel) - { - return new TextureView(_gd, _device, info, this, firstLayer, firstLevel); - } - - public void CopyFromOrToBuffer( - CommandBuffer commandBuffer, - VkBuffer buffer, - Image image, - int size, - bool to, - int x, - int y, - int dstLayer, - int dstLevel, - int dstLayers, - int dstLevels, - bool singleSlice, - ImageAspectFlags aspectFlags, - bool forFlush) - { - bool is3D = Info.Target == Target.Texture3D; - int width = Info.Width; - int height = Info.Height; - int depth = is3D && !singleSlice ? Info.Depth : 1; - int layer = is3D ? 0 : dstLayer; - int layers = dstLayers; - int levels = dstLevels; - - int offset = 0; - - for (int level = 0; level < levels; level++) - { - int mipSize = Info.GetMipSize(level); - - if (forFlush) - { - mipSize = GetBufferDataLength(mipSize); - } - - int endOffset = offset + mipSize; - - if ((uint)endOffset > (uint)size) - { - break; - } - - int rowLength = (Info.GetMipStride(level) / Info.BytesPerPixel) * Info.BlockWidth; - - var sl = new ImageSubresourceLayers( - aspectFlags, - (uint)(dstLevel + level), - (uint)layer, - (uint)layers); - - var extent = new Extent3D((uint)width, (uint)height, (uint)depth); - - int z = is3D ? dstLayer : 0; - - var region = new BufferImageCopy( - (ulong)offset, - (uint)BitUtils.AlignUp(rowLength, Info.BlockWidth), - (uint)BitUtils.AlignUp(height, Info.BlockHeight), - sl, - new Offset3D(x, y, z), - extent); - - if (to) - { - _gd.Api.CmdCopyImageToBuffer(commandBuffer, image, ImageLayout.General, buffer, 1, region); - } - else - { - _gd.Api.CmdCopyBufferToImage(commandBuffer, buffer, image, ImageLayout.General, 1, region); - } - - offset += mipSize; - - width = Math.Max(1, width >> 1); - height = Math.Max(1, height >> 1); - - if (Info.Target == Target.Texture3D) - { - depth = Math.Max(1, depth >> 1); - } - } - } - - private int GetBufferDataLength(int length) - { - if (NeedsD24S8Conversion()) - { - return length * 2; - } - - return length; - } - - private bool NeedsD24S8Conversion() - { - return FormatCapabilities.IsD24S8(Info.Format) && VkFormat == VkFormat.D32SfloatS8Uint; - } - - public void SetModification(AccessFlags accessFlags, PipelineStageFlags stage) - { - _lastModificationAccess = accessFlags; - _lastModificationStage = stage; - } - - public void InsertReadToWriteBarrier(CommandBufferScoped cbs, AccessFlags dstAccessFlags, PipelineStageFlags dstStageFlags) - { - if (_lastReadAccess != AccessFlags.None) - { - ImageAspectFlags aspectFlags = Info.Format.ConvertAspectFlags(); - - TextureView.InsertImageBarrier( - _gd.Api, - cbs.CommandBuffer, - _imageAuto.Get(cbs).Value, - _lastReadAccess, - dstAccessFlags, - _lastReadStage, - dstStageFlags, - aspectFlags, - 0, - 0, - _info.GetLayers(), - _info.Levels); - - _lastReadAccess = AccessFlags.None; - _lastReadStage = PipelineStageFlags.None; - } - } - - public void InsertWriteToReadBarrier(CommandBufferScoped cbs, AccessFlags dstAccessFlags, PipelineStageFlags dstStageFlags) - { - _lastReadAccess |= dstAccessFlags; - _lastReadStage |= dstStageFlags; - - if (_lastModificationAccess != AccessFlags.None) - { - ImageAspectFlags aspectFlags = Info.Format.ConvertAspectFlags(); - - TextureView.InsertImageBarrier( - _gd.Api, - cbs.CommandBuffer, - _imageAuto.Get(cbs).Value, - _lastModificationAccess, - dstAccessFlags, - _lastModificationStage, - dstStageFlags, - aspectFlags, - 0, - 0, - _info.GetLayers(), - _info.Levels); - - _lastModificationAccess = AccessFlags.None; - } - } - - public void IncrementViewsCount() - { - _viewsCount++; - } - - public void DecrementViewsCount() - { - if (--_viewsCount == 0) - { - _gd.PipelineInternal?.FlushCommandsIfWeightExceeding(_imageAuto, _size); - - Dispose(); - } - } - - public void Dispose() - { - if (_aliasedStorages != null) - { - foreach (var storage in _aliasedStorages.Values) - { - storage.Dispose(); - } - - _aliasedStorages.Clear(); - } - - _imageAuto.Dispose(); - _allocationAuto?.Dispose(); - _foreignAllocationAuto?.DecrementReferenceCount(); - _foreignAllocationAuto = null; - } - } -} |
