#pragma once #include #include "BufferHelpers.h" size_t Track(size_t s); namespace idk::vkn::hlp { template vk::UniqueBuffer CreateBuffer(vk::Device device, vk::DeviceSize size, vk::BufferUsageFlags usage, Dispatcher const& dispatcher) { vk::BufferCreateInfo bufferInfo { vk::BufferCreateFlags{} ,size ,usage ,vk::SharingMode::eExclusive //Exclusive to the graphics queue family }; return device.createBufferUnique(bufferInfo, nullptr); } template vk::UniqueBuffer CreateVertexBuffer(vk::Device device, T* const begin, T* const end, const Dispatcher& dispatcher) { return CreateBuffer(device, buffer_size(begin, end), vk::BufferUsageFlagBits::eVertexBuffer); } template vk::UniqueBuffer CreateVertexBuffer(vk::Device device, std::vector const& vertices, const Dispatcher& dispatcher) { return CreateVertexBuffer(device, vertices.data(), vertices.data() + vertices.size()); } // template vk::UniqueDeviceMemory AllocateBuffer( vk::PhysicalDevice pdevice, vk::Device device, vk::Buffer const& buffer, vk::MemoryPropertyFlags memory_flags, Dispatcher const& dispatcher) { vk::MemoryRequirements req = device.getBufferMemoryRequirements(buffer); vk::MemoryAllocateInfo allocInfo { Track(req.size) ,findMemoryType(pdevice,req.memoryTypeBits, memory_flags) }; return device.allocateMemoryUnique(allocInfo, nullptr); } template void BindBufferMemory(vk::Device device, vk::Buffer buffer, vk::DeviceMemory memory, uint32_t offset, Dispatcher const& dispatcher) { device.bindBufferMemory(buffer, memory, offset); } template std::pair CreateAllocBindBuffer( vk::PhysicalDevice pdevice, vk::Device device, vk::DeviceSize buffer_size, vk::BufferUsageFlags buffer_usage, vk::MemoryPropertyFlags memory_flags, const Dispatcher& dispatcher ) { auto buffer = CreateBuffer(device, buffer_size, buffer_usage); auto memory = AllocateBuffer(pdevice, device, *buffer, memory_flags); BindBufferMemory(device, *buffer, *memory, 0); return std::make_pair(std::move(buffer), std::move(memory)); } template std::pair CreateAllocBindBuffer( vk::PhysicalDevice pdevice, vk::Device device, vk::DeviceSize buffer_size, vk::BufferUsageFlags buffer_usage, vk::MemoryPropertyFlags memory_flags, MemoryAllocator& allocator, const Dispatcher& dispatcher ) { auto buffer = CreateBuffer(device, buffer_size, buffer_usage); auto memory = allocator.Allocate(pdevice, device, *buffer, memory_flags); BindBufferMemory(device, *buffer, memory->Memory(), s_cast(memory->Offset())); return std::make_pair(std::move(buffer), std::move(memory)); } template std::pair CreateAllocBindVertexBuffer( vk::PhysicalDevice pdevice, vk::Device device, T const* vertices, T const* vertices_end, const Dispatcher& dispatcher ) { return CreateAllocBindBuffer(pdevice, device, buffer_size(vertices, vertices_end), vk::BufferUsageFlagBits::eVertexBuffer, vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent); } template std::pair CreateAllocBindVertexBuffer( vk::PhysicalDevice pdevice, vk::Device device, std::vector const& vertices, const Dispatcher& dispatcher ) { return CreateAllocBindVertexBuffer(pdevice, device, vertices.data(), vertices.data() + vertices.size()); } template void MapMemory(vk::Device device, vk::DeviceMemory memory, vk::DeviceSize dest_offset, T* src_start, vk::DeviceSize trf_size, Dispatcher const& dispatcher) { vk::MappedMemoryRange mmr { memory ,dest_offset ,trf_size }; auto handle = device.mapMemory(memory, mmr.offset, mmr.size, vk::MemoryMapFlags{}); memcpy_s(handle, mmr.size, src_start, mmr.size); //std::vector memory_ranges //{ // mmr //}; //Not necessary rn since we set the HostCoherent bit //This command only guarantees that the memory(on gpu) will be updated by vkQueueSubmit //device.flushMappedMemoryRanges(memory_ranges, dispatcher); device.unmapMemory(memory); } template vk::ArrayProxy make_array_proxy(uint32_t sz, T* arr) { return vk::ArrayProxy{sz, arr}; } namespace detail { template()))> std::true_type has_data(const T&); template std::false_type has_data(T, Args...); template static constexpr bool has_data_v = std::is_same_v())), std::true_type>; } // template RT buffer_size(T const& vertices) { if constexpr (detail::has_data_v) { return static_cast(sizeof(*std::data(vertices)) * hlp::arr_count(vertices)); } else { return static_cast(sizeof(vertices)); } } template RT buffer_size(T* begin, T* end) { return static_cast(sizeof(T) * (end - begin)); } template auto buffer_data(T& obj) { if constexpr (detail::has_data_v) { return std::data(obj); } else { return &obj; } } template RT buffer_data(T& obj) { return reinterpret_cast(buffer_data(obj)); } #pragma optimize("",on) template string_view to_data(const T& obj) { static_assert(!std::is_pointer_v, "Pointers should not be read as data. Convert to intptr_t if that is indeed the intention."); return string_view{ reinterpret_cast(hlp::buffer_data(obj)), hlp::buffer_size(obj) }; } }