BsVulkanHardwareBuffer.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsVulkanHardwareBuffer.h"
  4. #include "BsVulkanRenderAPI.h"
  5. #include "BsVulkanDevice.h"
  6. #include "BsVulkanUtility.h"
  7. #include "BsException.h"
  8. namespace BansheeEngine
  9. {
  10. VulkanBuffer::VulkanBuffer(VulkanResourceManager* owner, VkBuffer buffer, VkBufferView view, VkDeviceMemory memory)
  11. :VulkanResource(owner, false), mBuffer(buffer), mView(view), mMemory(memory)
  12. {
  13. }
  14. VulkanBuffer::~VulkanBuffer()
  15. {
  16. VulkanDevice& device = mOwner->getDevice();
  17. if (mView != VK_NULL_HANDLE)
  18. vkDestroyBufferView(device.getLogical(), mView, gVulkanAllocator);
  19. vkDestroyBuffer(device.getLogical(), mBuffer, gVulkanAllocator);
  20. device.freeMemory(mMemory);
  21. }
  22. VulkanHardwareBuffer::VulkanHardwareBuffer(BufferType type, GpuBufferFormat format, GpuBufferUsage usage,
  23. UINT32 size, GpuDeviceFlags deviceMask)
  24. : HardwareBuffer(usage), mBuffers()
  25. {
  26. bool staging = type == BT_STAGING;
  27. bool needsView = false;
  28. VkMemoryPropertyFlags flags = staging ?
  29. (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) : // Note: Try using cached uncoherent memory
  30. VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
  31. VkBufferUsageFlags usageFlags = 0;
  32. switch(type)
  33. {
  34. case BT_VERTEX:
  35. usageFlags = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
  36. break;
  37. case BT_INDEX:
  38. usageFlags = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
  39. break;
  40. case BT_UNIFORM:
  41. usageFlags = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
  42. break;
  43. case BT_GENERIC:
  44. usageFlags = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
  45. needsView = true;
  46. break;
  47. case BT_STORAGE:
  48. usageFlags = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
  49. needsView = true;
  50. break;
  51. case BT_STAGING:
  52. usageFlags = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
  53. break;
  54. }
  55. VulkanRenderAPI& rapi = static_cast<VulkanRenderAPI&>(RenderAPICore::instance());
  56. VulkanDevice* devices[BS_MAX_DEVICES];
  57. VulkanUtility::getDevices(rapi, deviceMask, devices);
  58. // Allocate buffers per-device
  59. for (UINT32 i = 0; i < BS_MAX_DEVICES; i++)
  60. {
  61. if (devices[i] == nullptr)
  62. break;
  63. VkBufferCreateInfo bufferCI;
  64. bufferCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
  65. bufferCI.pNext = nullptr;
  66. bufferCI.flags = 0;
  67. bufferCI.size = size;
  68. bufferCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
  69. bufferCI.usage = usageFlags;
  70. bufferCI.queueFamilyIndexCount = 0;
  71. bufferCI.pQueueFamilyIndices = nullptr;
  72. VkDevice device = devices[i]->getLogical();
  73. VkBuffer buffer;
  74. VkResult result = vkCreateBuffer(device, &bufferCI, gVulkanAllocator, &buffer);
  75. assert(result == VK_SUCCESS);
  76. VkMemoryRequirements memReqs;
  77. vkGetBufferMemoryRequirements(device, buffer, &memReqs);
  78. VkDeviceMemory memory = devices[i]->allocateMemory(memReqs, flags);
  79. result = vkBindBufferMemory(device, buffer, memory, 0);
  80. assert(result == VK_SUCCESS);
  81. VkBufferView view;
  82. if (needsView)
  83. {
  84. VkBufferViewCreateInfo bufferViewCI;
  85. bufferViewCI.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
  86. bufferViewCI.pNext = nullptr;
  87. bufferViewCI.flags = 0;
  88. bufferViewCI.buffer = buffer;
  89. bufferViewCI.format = VulkanUtility::getBufferFormat(format);
  90. bufferViewCI.offset = 0;
  91. bufferViewCI.range = VK_WHOLE_SIZE;
  92. result = vkCreateBufferView(device, &bufferViewCI, gVulkanAllocator, &view);
  93. assert(result == VK_SUCCESS);
  94. }
  95. else
  96. view = VK_NULL_HANDLE;
  97. mBuffers[i] = devices[i]->getResourceManager().create<VulkanBuffer>(buffer, view, memory);
  98. }
  99. mSizeInBytes = size;
  100. }
  101. VulkanHardwareBuffer::~VulkanHardwareBuffer()
  102. {
  103. for (UINT32 i = 0; i < BS_MAX_DEVICES; i++)
  104. {
  105. if (mBuffers[i] == nullptr)
  106. return;
  107. mBuffers[i]->destroy();
  108. }
  109. }
  110. void* VulkanHardwareBuffer::map(UINT32 offset, UINT32 length, GpuLockOptions options, UINT32 syncMask)
  111. {
  112. if ((offset + length) > mSizeInBytes)
  113. BS_EXCEPT(RenderingAPIException, "Provided offset(" + toString(offset) + ") + length(" + toString(length) + ") "
  114. "is larger than the buffer " + toString(mSizeInBytes) + ".");
  115. switch (options)
  116. {
  117. case GBL_WRITE_ONLY_DISCARD:
  118. break;
  119. case GBL_WRITE_ONLY_NO_OVERWRITE:
  120. break;
  121. case GBL_WRITE_ONLY:
  122. break;
  123. case GBL_READ_WRITE:
  124. break;
  125. case GBL_READ_ONLY:
  126. break;
  127. }
  128. return nullptr;
  129. }
  130. void VulkanHardwareBuffer::unmap()
  131. {
  132. }
  133. void VulkanHardwareBuffer::copyData(HardwareBuffer& srcBuffer, UINT32 srcOffset,
  134. UINT32 dstOffset, UINT32 length, bool discardWholeBuffer, UINT32 syncMask)
  135. {
  136. }
  137. void VulkanHardwareBuffer::readData(UINT32 offset, UINT32 length, void* pDest, UINT32 syncMask)
  138. {
  139. }
  140. void VulkanHardwareBuffer::writeData(UINT32 offset, UINT32 length, const void* pSource, BufferWriteType writeFlags, UINT32 syncMask)
  141. {
  142. }
  143. }