PersistentFlushBuffer.cs 3.1 KB

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