Newer
Older
ForwardPlusRenderer / src / Memory.cpp
#include "Memory.h"

namespace fpr
{
uint32_t FindMemoryTypeIndex(
    vk::PhysicalDevice      physical_device,
    uint32_t                type_field,
    vk::MemoryPropertyFlags type_flags)
{
  vk::PhysicalDeviceMemoryProperties device_mem_properties = physical_device.getMemoryProperties();

  for(uint32_t index = 0; index < device_mem_properties.memoryTypeCount; ++index)
  {
    bool memory_type_index_found = IsNthBitSet(type_field, index) &&
        IsOnlyNthBitSet(static_cast<uint32_t>(device_mem_properties.memoryTypes[index].propertyFlags),
                        static_cast<uint32_t>(type_flags));
    if(memory_type_index_found)
      return index;
  }
  return std::numeric_limits<uint32_t>::max();
}

bool IsNthBitSet(uint32_t bit_field, uint32_t nth_bit) FPR_NOEXCEPT
{
  return (bit_field & (1 << nth_bit));
};

bool IsOnlyNthBitSet(uint32_t bit_field, uint32_t nth_bit) FPR_NOEXCEPT
{
  return (bit_field & nth_bit) == nth_bit;
}


vk::UniqueDeviceMemory CreateImageMemory(fpr::Device* device, vk::Image image)
{
  vk::MemoryRequirements mem_req = device->GetLogicalDeviceHandle().getImageMemoryRequirements(image);

  vk::MemoryAllocateInfo mem_alloc_info{};
  mem_alloc_info.allocationSize  = mem_req.size;
  mem_alloc_info.memoryTypeIndex = fpr::FindMemoryTypeIndex(
      device->GetPhysicalDeviceHandle(), mem_req.memoryTypeBits, vk::MemoryPropertyFlagBits::eDeviceLocal);
  auto [alloc_result, img_mem] = device->GetLogicalDeviceHandle().allocateMemoryUnique(mem_alloc_info);
  assert(("Failed to allocate image memory!", alloc_result == vk::Result::eSuccess));
  [[maybe_unused]] vk::Result bind_result = device->GetLogicalDeviceHandle().bindImageMemory(image, *img_mem, 0);

  assert(("Failed to bind image memory!", bind_result == vk::Result::eSuccess));

  return std::move(img_mem);
}

}