PersistentFlushBuffer.cs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. using Ryujinx.Graphics.GAL;
  2. using Silk.NET.Vulkan;
  3. using System;
  4. using Buffer = Silk.NET.Vulkan.Buffer;
  5. namespace Ryujinx.Graphics.Vulkan
  6. {
  7. internal class PersistentFlushBuffer : IDisposable
  8. {
  9. private readonly VulkanRenderer _gd;
  10. private BufferHolder _flushStorage;
  11. public PersistentFlushBuffer(VulkanRenderer gd)
  12. {
  13. _gd = gd;
  14. }
  15. private BufferHolder ResizeIfNeeded(int size)
  16. {
  17. BufferHolder flushStorage = _flushStorage;
  18. if (flushStorage == null || size > _flushStorage.Size)
  19. {
  20. flushStorage?.Dispose();
  21. flushStorage = _gd.BufferManager.Create(_gd, size);
  22. _flushStorage = flushStorage;
  23. }
  24. return flushStorage;
  25. }
  26. public Span<byte> GetBufferData(CommandBufferPool cbp, BufferHolder buffer, int offset, int size)
  27. {
  28. BufferHolder flushStorage = ResizeIfNeeded(size);
  29. Auto<DisposableBuffer> srcBuffer;
  30. using (CommandBufferScoped cbs = cbp.Rent())
  31. {
  32. srcBuffer = buffer.GetBuffer(cbs.CommandBuffer);
  33. Auto<DisposableBuffer> dstBuffer = flushStorage.GetBuffer(cbs.CommandBuffer);
  34. if (srcBuffer.TryIncrementReferenceCount())
  35. {
  36. BufferHolder.Copy(_gd, cbs, srcBuffer, dstBuffer, offset, 0, size, registerSrcUsage: false);
  37. }
  38. else
  39. {
  40. // Source buffer is no longer alive, don't copy anything to flush storage.
  41. srcBuffer = null;
  42. }
  43. }
  44. flushStorage.WaitForFences();
  45. srcBuffer?.DecrementReferenceCount();
  46. return flushStorage.GetDataStorage(0, size);
  47. }
  48. public Span<byte> GetTextureData(CommandBufferPool cbp, TextureView view, int size)
  49. {
  50. TextureCreateInfo info = view.Info;
  51. BufferHolder flushStorage = ResizeIfNeeded(size);
  52. using (CommandBufferScoped cbs = cbp.Rent())
  53. {
  54. Buffer buffer = flushStorage.GetBuffer(cbs.CommandBuffer).Get(cbs).Value;
  55. Image image = view.GetImage().Get(cbs).Value;
  56. view.CopyFromOrToBuffer(cbs.CommandBuffer, buffer, image, size, true, 0, 0, info.GetLayers(), info.Levels, singleSlice: false);
  57. }
  58. flushStorage.WaitForFences();
  59. return flushStorage.GetDataStorage(0, size);
  60. }
  61. public Span<byte> GetTextureData(CommandBufferPool cbp, TextureView view, int size, int layer, int level)
  62. {
  63. BufferHolder flushStorage = ResizeIfNeeded(size);
  64. using (CommandBufferScoped cbs = cbp.Rent())
  65. {
  66. Buffer buffer = flushStorage.GetBuffer(cbs.CommandBuffer).Get(cbs).Value;
  67. Image image = view.GetImage().Get(cbs).Value;
  68. view.CopyFromOrToBuffer(cbs.CommandBuffer, buffer, image, size, true, layer, level, 1, 1, singleSlice: true);
  69. }
  70. flushStorage.WaitForFences();
  71. return flushStorage.GetDataStorage(0, size);
  72. }
  73. public void Dispose()
  74. {
  75. _flushStorage.Dispose();
  76. }
  77. }
  78. }