StreamBuffer.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. /**
  2. * Copyright (c) 2006-2022 LOVE Development Team
  3. *
  4. * This software is provided 'as-is', without any express or implied
  5. * warranty. In no event will the authors be held liable for any damages
  6. * arising from the use of this software.
  7. *
  8. * Permission is granted to anyone to use this software for any purpose,
  9. * including commercial applications, and to alter it and redistribute it
  10. * freely, subject to the following restrictions:
  11. *
  12. * 1. The origin of this software must not be misrepresented; you must not
  13. * claim that you wrote the original software. If you use this software
  14. * in a product, an acknowledgment in the product documentation would be
  15. * appreciated but is not required.
  16. * 2. Altered source versions must be plainly marked as such, and must not be
  17. * misrepresented as being the original software.
  18. * 3. This notice may not be removed or altered from any source distribution.
  19. **/
  20. #include "StreamBuffer.h"
  21. #include "Graphics.h"
  22. namespace love
  23. {
  24. namespace graphics
  25. {
  26. namespace vulkan
  27. {
  28. static VkBufferUsageFlags getUsageFlags(BufferUsage mode)
  29. {
  30. switch (mode)
  31. {
  32. case BUFFERUSAGE_VERTEX: return VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
  33. case BUFFERUSAGE_INDEX: return VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
  34. case BUFFERUSAGE_UNIFORM: return VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
  35. default:
  36. throw love::Exception("unsupported BufferUsage mode");
  37. }
  38. }
  39. StreamBuffer::StreamBuffer(graphics::Graphics *gfx, BufferUsage mode, size_t size)
  40. : love::graphics::StreamBuffer(mode, size)
  41. , vgfx(dynamic_cast<Graphics*>(gfx))
  42. {
  43. loadVolatile();
  44. }
  45. bool StreamBuffer::loadVolatile()
  46. {
  47. allocator = vgfx->getVmaAllocator();
  48. VkBufferCreateInfo bufferInfo{};
  49. bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
  50. bufferInfo.size = getSize() * MAX_FRAMES_IN_FLIGHT; // TODO: Is this sufficient or should it be +1?
  51. bufferInfo.usage = getUsageFlags(mode);
  52. bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
  53. VmaAllocationCreateInfo allocCreateInfo = {};
  54. allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
  55. allocCreateInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT;
  56. if (vmaCreateBuffer(allocator, &bufferInfo, &allocCreateInfo, &buffer, &allocation, &allocInfo) != VK_SUCCESS)
  57. throw love::Exception("Cannot create stream buffer: out of graphics memory.");
  58. return true;
  59. }
  60. void StreamBuffer::unloadVolatile()
  61. {
  62. if (buffer == VK_NULL_HANDLE)
  63. return;
  64. vgfx->queueCleanUp([allocator=allocator, buffer=buffer, allocation=allocation](){
  65. vmaDestroyBuffer(allocator, buffer, allocation);
  66. });
  67. buffer = VK_NULL_HANDLE;
  68. }
  69. StreamBuffer::~StreamBuffer()
  70. {
  71. unloadVolatile();
  72. }
  73. ptrdiff_t StreamBuffer::getHandle() const
  74. {
  75. return (ptrdiff_t) buffer;
  76. }
  77. love::graphics::StreamBuffer::MapInfo StreamBuffer::map(size_t /*minsize*/)
  78. {
  79. // TODO: do we also need to wait until a fence is complete, here?
  80. MapInfo info;
  81. info.size = bufferSize - frameGPUReadOffset;
  82. info.data = (uint8*)allocInfo.pMappedData + (frameIndex * bufferSize) + frameGPUReadOffset;
  83. return info;
  84. }
  85. size_t StreamBuffer::unmap(size_t /*usedSize*/)
  86. {
  87. size_t offset = (frameIndex * bufferSize) + frameGPUReadOffset;
  88. return offset;
  89. }
  90. void StreamBuffer::markUsed(size_t usedSize)
  91. {
  92. frameGPUReadOffset += usedSize;
  93. }
  94. void StreamBuffer::nextFrame()
  95. {
  96. frameIndex = (frameIndex + 1) % MAX_FRAMES_IN_FLIGHT;
  97. frameGPUReadOffset = 0;
  98. }
  99. } // vulkan
  100. } // graphics
  101. } // love