aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Vulkan/ImageWindow.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Graphics.Vulkan/ImageWindow.cs')
-rw-r--r--Ryujinx.Graphics.Vulkan/ImageWindow.cs429
1 files changed, 0 insertions, 429 deletions
diff --git a/Ryujinx.Graphics.Vulkan/ImageWindow.cs b/Ryujinx.Graphics.Vulkan/ImageWindow.cs
deleted file mode 100644
index 69302fdf..00000000
--- a/Ryujinx.Graphics.Vulkan/ImageWindow.cs
+++ /dev/null
@@ -1,429 +0,0 @@
-using Ryujinx.Graphics.GAL;
-using Silk.NET.Vulkan;
-using System;
-using VkFormat = Silk.NET.Vulkan.Format;
-
-namespace Ryujinx.Graphics.Vulkan
-{
- class ImageWindow : WindowBase, IWindow, IDisposable
- {
- internal const VkFormat Format = VkFormat.R8G8B8A8Unorm;
-
- private const int ImageCount = 3;
- private const int SurfaceWidth = 1280;
- private const int SurfaceHeight = 720;
-
- private readonly VulkanRenderer _gd;
- private readonly PhysicalDevice _physicalDevice;
- private readonly Device _device;
-
- private Auto<DisposableImage>[] _images;
- private Auto<DisposableImageView>[] _imageViews;
- private Auto<MemoryAllocation>[] _imageAllocationAuto;
- private ImageState[] _states;
- private PresentImageInfo[] _presentedImages;
- private FenceHolder[] _fences;
-
- private ulong[] _imageSizes;
- private ulong[] _imageOffsets;
-
- private int _width = SurfaceWidth;
- private int _height = SurfaceHeight;
- private bool _recreateImages;
- private int _nextImage;
-
- public unsafe ImageWindow(VulkanRenderer gd, PhysicalDevice physicalDevice, Device device)
- {
- _gd = gd;
- _physicalDevice = physicalDevice;
- _device = device;
-
- _images = new Auto<DisposableImage>[ImageCount];
- _imageAllocationAuto = new Auto<MemoryAllocation>[ImageCount];
- _imageSizes = new ulong[ImageCount];
- _imageOffsets = new ulong[ImageCount];
- _states = new ImageState[ImageCount];
- _presentedImages = new PresentImageInfo[ImageCount];
-
- CreateImages();
- }
-
- private void RecreateImages()
- {
- for (int i = 0; i < ImageCount; i++)
- {
- lock (_states[i])
- {
- _states[i].IsValid = false;
- _fences[i]?.Wait();
- _fences[i]?.Put();
- _imageViews[i]?.Dispose();
- _imageAllocationAuto[i]?.Dispose();
- _images[i]?.Dispose();
- }
- }
- _presentedImages = null;
-
- CreateImages();
- }
-
- private unsafe void CreateImages()
- {
- _imageViews = new Auto<DisposableImageView>[ImageCount];
- _fences = new FenceHolder[ImageCount];
- _presentedImages = new PresentImageInfo[ImageCount];
-
- _nextImage = 0;
- var cbs = _gd.CommandBufferPool.Rent();
-
- var imageCreateInfo = new ImageCreateInfo
- {
- SType = StructureType.ImageCreateInfo,
- ImageType = ImageType.ImageType2D,
- Format = Format,
- Extent = new Extent3D((uint?)_width, (uint?)_height, 1),
- MipLevels = 1,
- ArrayLayers = 1,
- Samples = SampleCountFlags.SampleCount1Bit,
- Tiling = ImageTiling.Optimal,
- Usage = ImageUsageFlags.ImageUsageColorAttachmentBit | ImageUsageFlags.ImageUsageTransferSrcBit | ImageUsageFlags.ImageUsageTransferDstBit,
- SharingMode = SharingMode.Exclusive,
- InitialLayout = ImageLayout.Undefined,
- Flags = ImageCreateFlags.ImageCreateMutableFormatBit
- };
-
- for (int i = 0; i < _images.Length; i++)
- {
- _gd.Api.CreateImage(_device, imageCreateInfo, null, out var image).ThrowOnError();
- _images[i] = new Auto<DisposableImage>(new DisposableImage(_gd.Api, _device, image));
-
- _gd.Api.GetImageMemoryRequirements(_device, image,
- out var memoryRequirements);
- var allocation = _gd.MemoryAllocator.AllocateDeviceMemory(_physicalDevice, memoryRequirements, MemoryPropertyFlags.MemoryPropertyDeviceLocalBit);
-
- _imageSizes[i] = allocation.Size;
- _imageOffsets[i] = allocation.Offset;
-
- _imageAllocationAuto[i] = new Auto<MemoryAllocation>(allocation);
-
- _gd.Api.BindImageMemory(_device, image, allocation.Memory, allocation.Offset);
-
- _imageViews[i] = CreateImageView(image, Format);
-
- Transition(
- cbs.CommandBuffer,
- image,
- 0,
- 0,
- ImageLayout.Undefined,
- ImageLayout.TransferSrcOptimal);
-
- _states[i] = new ImageState();
- }
-
- _gd.CommandBufferPool.Return(cbs);
- }
-
- private unsafe Auto<DisposableImageView> CreateImageView(Image image, VkFormat format)
- {
- var componentMapping = new ComponentMapping(
- ComponentSwizzle.R,
- ComponentSwizzle.G,
- ComponentSwizzle.B,
- ComponentSwizzle.A);
-
- var subresourceRange = new ImageSubresourceRange(ImageAspectFlags.ImageAspectColorBit, 0, 1, 0, 1);
-
- var imageCreateInfo = new ImageViewCreateInfo()
- {
- SType = StructureType.ImageViewCreateInfo,
- Image = image,
- ViewType = ImageViewType.ImageViewType2D,
- Format = format,
- Components = componentMapping,
- SubresourceRange = subresourceRange
- };
-
- _gd.Api.CreateImageView(_device, imageCreateInfo, null, out var imageView).ThrowOnError();
- return new Auto<DisposableImageView>(new DisposableImageView(_gd.Api, _device, imageView));
- }
-
- public override unsafe void Present(ITexture texture, ImageCrop crop, Action<object> swapBuffersCallback)
- {
- if (_recreateImages)
- {
- RecreateImages();
- _recreateImages = false;
- }
-
- var image = _images[_nextImage];
-
- _gd.FlushAllCommands();
-
- var cbs = _gd.CommandBufferPool.Rent();
-
- Transition(
- cbs.CommandBuffer,
- image.GetUnsafe().Value,
- 0,
- AccessFlags.AccessTransferWriteBit,
- ImageLayout.TransferSrcOptimal,
- ImageLayout.General);
-
- var view = (TextureView)texture;
-
- int srcX0, srcX1, srcY0, srcY1;
- float scale = view.ScaleFactor;
-
- if (crop.Left == 0 && crop.Right == 0)
- {
- srcX0 = 0;
- srcX1 = (int)(view.Width / scale);
- }
- else
- {
- srcX0 = crop.Left;
- srcX1 = crop.Right;
- }
-
- if (crop.Top == 0 && crop.Bottom == 0)
- {
- srcY0 = 0;
- srcY1 = (int)(view.Height / scale);
- }
- else
- {
- srcY0 = crop.Top;
- srcY1 = crop.Bottom;
- }
-
- if (scale != 1f)
- {
- srcX0 = (int)(srcX0 * scale);
- srcY0 = (int)(srcY0 * scale);
- srcX1 = (int)Math.Ceiling(srcX1 * scale);
- srcY1 = (int)Math.Ceiling(srcY1 * scale);
- }
-
- if (ScreenCaptureRequested)
- {
- CaptureFrame(view, srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0, view.Info.Format.IsBgr(), crop.FlipX, crop.FlipY);
-
- ScreenCaptureRequested = false;
- }
-
- float ratioX = crop.IsStretched ? 1.0f : MathF.Min(1.0f, _height * crop.AspectRatioX / (_width * crop.AspectRatioY));
- float ratioY = crop.IsStretched ? 1.0f : MathF.Min(1.0f, _width * crop.AspectRatioY / (_height * crop.AspectRatioX));
-
- int dstWidth = (int)(_width * ratioX);
- int dstHeight = (int)(_height * ratioY);
-
- int dstPaddingX = (_width - dstWidth) / 2;
- int dstPaddingY = (_height - dstHeight) / 2;
-
- int dstX0 = crop.FlipX ? _width - dstPaddingX : dstPaddingX;
- int dstX1 = crop.FlipX ? dstPaddingX : _width - dstPaddingX;
-
- int dstY0 = crop.FlipY ? dstPaddingY : _height - dstPaddingY;
- int dstY1 = crop.FlipY ? _height - dstPaddingY : dstPaddingY;
-
- _gd.HelperShader.Blit(
- _gd,
- cbs,
- view,
- _imageViews[_nextImage],
- _width,
- _height,
- Format,
- new Extents2D(srcX0, srcY0, srcX1, srcY1),
- new Extents2D(dstX0, dstY1, dstX1, dstY0),
- true,
- true);
-
- Transition(
- cbs.CommandBuffer,
- image.GetUnsafe().Value,
- 0,
- 0,
- ImageLayout.General,
- ImageLayout.TransferSrcOptimal);
-
- _gd.CommandBufferPool.Return(
- cbs,
- null,
- stackalloc[] { PipelineStageFlags.PipelineStageColorAttachmentOutputBit },
- null);
-
- _fences[_nextImage]?.Put();
- _fences[_nextImage] = cbs.GetFence();
- cbs.GetFence().Get();
-
- PresentImageInfo info = _presentedImages[_nextImage];
-
- if (info == null)
- {
- info = new PresentImageInfo(
- image,
- _imageAllocationAuto[_nextImage],
- _device,
- _physicalDevice,
- _imageSizes[_nextImage],
- _imageOffsets[_nextImage],
- new Extent2D((uint)_width, (uint)_height),
- _states[_nextImage]);
-
- _presentedImages[_nextImage] = info;
- }
-
- swapBuffersCallback(info);
-
- _nextImage = (_nextImage + 1) % ImageCount;
- }
-
- private unsafe void Transition(
- CommandBuffer commandBuffer,
- Image image,
- AccessFlags srcAccess,
- AccessFlags dstAccess,
- ImageLayout srcLayout,
- ImageLayout dstLayout)
- {
- var subresourceRange = new ImageSubresourceRange(ImageAspectFlags.ImageAspectColorBit, 0, 1, 0, 1);
-
- var barrier = new ImageMemoryBarrier()
- {
- SType = StructureType.ImageMemoryBarrier,
- SrcAccessMask = srcAccess,
- DstAccessMask = dstAccess,
- OldLayout = srcLayout,
- NewLayout = dstLayout,
- SrcQueueFamilyIndex = Vk.QueueFamilyIgnored,
- DstQueueFamilyIndex = Vk.QueueFamilyIgnored,
- Image = image,
- SubresourceRange = subresourceRange
- };
-
- _gd.Api.CmdPipelineBarrier(
- commandBuffer,
- PipelineStageFlags.PipelineStageTopOfPipeBit,
- PipelineStageFlags.PipelineStageAllCommandsBit,
- 0,
- 0,
- null,
- 0,
- null,
- 1,
- barrier);
- }
-
- private void CaptureFrame(TextureView texture, int x, int y, int width, int height, bool isBgra, bool flipX, bool flipY)
- {
- byte[] bitmap = texture.GetData(x, y, width, height);
-
- _gd.OnScreenCaptured(new ScreenCaptureImageInfo(width, height, isBgra, bitmap, flipX, flipY));
- }
-
- public override void SetSize(int width, int height)
- {
- if (_width != width || _height != height)
- {
- _recreateImages = true;
- }
-
- _width = width;
- _height = height;
- }
-
- protected virtual void Dispose(bool disposing)
- {
- if (disposing)
- {
- unsafe
- {
- for (int i = 0; i < ImageCount; i++)
- {
- _states[i].IsValid = false;
- _fences[i]?.Wait();
- _fences[i]?.Put();
- _imageViews[i]?.Dispose();
- _imageAllocationAuto[i]?.Dispose();
- _images[i]?.Dispose();
- }
- }
- }
- }
-
- public override void Dispose()
- {
- Dispose(true);
- }
-
- public override void ChangeVSyncMode(bool vsyncEnabled) { }
- }
-
- public class ImageState
- {
- private bool _isValid = true;
-
- public bool IsValid
- {
- get => _isValid;
- internal set
- {
- _isValid = value;
-
- StateChanged?.Invoke(this, _isValid);
- }
- }
-
- public event EventHandler<bool> StateChanged;
- }
-
- public class PresentImageInfo
- {
- private readonly Auto<DisposableImage> _image;
- private readonly Auto<MemoryAllocation> _memory;
-
- public Image Image => _image.GetUnsafe().Value;
-
- public DeviceMemory Memory => _memory.GetUnsafe().Memory;
-
- public Device Device { get; }
- public PhysicalDevice PhysicalDevice { get; }
- public ulong MemorySize { get; }
- public ulong MemoryOffset { get; }
- public Extent2D Extent { get; }
- public ImageState State { get; internal set; }
- internal PresentImageInfo(
- Auto<DisposableImage> image,
- Auto<MemoryAllocation> memory,
- Device device,
- PhysicalDevice physicalDevice,
- ulong memorySize,
- ulong memoryOffset,
- Extent2D extent2D,
- ImageState state)
- {
- _image = image;
- _memory = memory;
- Device = device;
- PhysicalDevice = physicalDevice;
- MemorySize = memorySize;
- MemoryOffset = memoryOffset;
- Extent = extent2D;
- State = state;
- }
-
- public void Get()
- {
- _memory.IncrementReferenceCount();
- _image.IncrementReferenceCount();
- }
-
- public void Put()
- {
- _memory.DecrementReferenceCount();
- _image.DecrementReferenceCount();
- }
- }
-} \ No newline at end of file