#include "pch.h" #include "VknMeshModder.h" #include #include #include #include #include #include #include namespace idk::vkn { namespace hlp { vk::UniqueCommandBuffer CreateCommandBuffer(vk::CommandPool command_pool, vk::Device device, vk::CommandBufferLevel cmd_level = vk::CommandBufferLevel::ePrimary) { //For RenderState //rss.resize(max_frames_in_flight); vk::CommandBufferAllocateInfo rs_alloc_info { command_pool ,cmd_level ,1 }; auto cmd_buffers = device.allocateCommandBuffersUnique(rs_alloc_info); return std::move(cmd_buffers[0]); } struct StagingStuff { vk::UniqueCommandBuffer cmd_buffer; vk::UniqueBuffer buffer; vk::UniqueDeviceMemory memory; ~StagingStuff() { } }; //Expensive (probably). StagingStuff TransferData(vk::CommandPool cmd_pool, vk::Queue queue, vk::PhysicalDevice pdevice, vk::Device device, size_t dst_offset, size_t num_bytes, const void* data, vk::Buffer dst_buffer, vk::Fence fence) { auto tmp_cmd_buffer = hlp::CreateCommandBuffer(cmd_pool, device); vk::DeviceSize bufferSize = num_bytes; auto [stagingBuffer, stagingBufferMemory] = hlp::CreateAllocBindBuffer( pdevice, device, bufferSize, vk::BufferUsageFlagBits::eTransferSrc, vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent); { hlp::MapMemory(device, *stagingBufferMemory, dst_offset, data, bufferSize); } //m_vertex_buffers.emplace_back( std::move(instance_buffer)); //m_vertex_memories.emplace_back(std::move(instance_memory)); hlp::CopyBuffer(*tmp_cmd_buffer, queue, *stagingBuffer, dst_buffer, bufferSize,fence,false); return { std::move(tmp_cmd_buffer), std::move(stagingBuffer), std::move(stagingBufferMemory) }; } } struct MeshModder::PImpl { vk::UniqueCommandPool cmd_pool_{}; vk::UniqueFence copy_fence_{}; PImpl() { vk::CommandPoolCreateInfo cpci { vk::CommandPoolCreateFlagBits::eTransient| vk::CommandPoolCreateFlagBits::eResetCommandBuffer, *View().QueueFamily().graphics_family }; cmd_pool_ = View().Device()->createCommandPoolUnique(cpci); vk::FenceCreateInfo fci { }; copy_fence_ = View().Device()->createFenceUnique(fci); } }; MeshModder::MeshModder() :allocator{ *Core::GetSystem().Instance().View().Device(),Core::GetSystem().Instance().View().PDevice() }, pimpl_{std::make_unique()} { } extern std::vector debug_messages; MeshModder::~MeshModder() { } std::shared_ptr MeshModder::CreateBuffer(string_view raw_data) { auto& vview = Core::GetSystem().Instance().View(); //auto& pdevice = vview.PDevice(); auto& m_device = vview.Device(); auto num_vtx_bytes = hlp::buffer_size(raw_data); auto data = std::data(raw_data); std::unique_lock create_allock{ create_alloc_mutex }; auto&& [pbuffer, palloc] = hlp::CreateAllocBindBuffer(vview.PDevice(), *vview.Device(), num_vtx_bytes, vk::BufferUsageFlagBits::eVertexBuffer | vk::BufferUsageFlagBits::eIndexBuffer | vk::BufferUsageFlagBits::eTransferDst, vk::MemoryPropertyFlagBits::eDeviceLocal, allocator, vview.Dispatcher()); create_allock.unlock(); vk::Result res; { auto& mtx = View().GraphicsTexMutex(); std::lock_guard lock{ mtx }; auto& fence = *pimpl_->copy_fence_; View().Device()->resetFences(fence); auto cmd_buffer = hlp::TransferData(*pimpl_->cmd_pool_, vview.GraphicsTexQueue(), vview.PDevice(), *m_device, 0, num_vtx_bytes, data, *pbuffer,fence); while((res=View().Device()->waitForFences(fence,true,0))==vk::Result::eTimeout); } return std::make_shared(std::move(pbuffer), std::move(palloc), num_vtx_bytes); } void MeshModder::RegisterAttribs(VulkanMesh& mesh, const hash_table, size_t>>& attribs) { for (auto& attrib : attribs) { mesh.SetBuffer(attrib.first, MeshBuffer{ attrib.second.first, attrib.second.second }); } } void MeshModder::SetIndexBuffer(VulkanMesh& mesh, const vector& index_buffer) { auto& vview = Core::GetSystem().Instance().View(); //auto& pdevice = vview.PDevice(); auto& m_device = vview.Device(); //auto& dispatcher = vview.Dispatcher(); { auto num_vtx_bytes = hlp::buffer_size(index_buffer); auto data = std::data(index_buffer); auto&& [pbuffer, palloc] = hlp::CreateAllocBindBuffer(vview.PDevice(), *vview.Device(), num_vtx_bytes, vk::BufferUsageFlagBits::eIndexBuffer | vk::BufferUsageFlagBits::eTransferDst, vk::MemoryPropertyFlagBits::eDeviceLocal, allocator, vview.Dispatcher()); { auto& mtx = View().GraphicsTexMutex(); std::lock_guard lock{ mtx }; auto& fence = *pimpl_->copy_fence_; View().Device()->resetFences(fence); auto cmd_buffer =hlp::TransferData(*vview.Commandpool(), vview.GraphicsTexQueue(), vview.PDevice(), *m_device, 0, num_vtx_bytes, data, *pbuffer,fence); while (View().Device()->waitForFences(fence, true, 0) == vk::Result::eTimeout); } mesh.SetIndexBuffer( MeshBuffer{ std::make_shared(std::move(pbuffer),std::move(palloc) , num_vtx_bytes) }, s_cast(index_buffer.size()), vk::IndexType::eUint16 ); } } //Index buffer elements are 16 bytes void MeshModder::SetIndexBuffer16(VulkanMesh& mesh, shared_ptr index_buffer, uint32_t num_indices) { [[maybe_unused]] auto& vview = Core::GetSystem().Instance().View(); //auto& pdevice = vview.PDevice(); //auto& m_device = vview.Device(); //auto& dispatcher = vview.Dispatcher(); { mesh.SetIndexBuffer( MeshBuffer{ index_buffer }, num_indices, vk::IndexType::eUint16 ); } } //Index buffer elements are 32 bytes void MeshModder::SetIndexBuffer32(VulkanMesh& mesh, shared_ptr index_buffer, uint32_t num_indices) { [[maybe_unused]] auto& vview = Core::GetSystem().Instance().View(); //auto& pdevice = vview.PDevice(); //auto& m_device = vview.Device(); //auto& dispatcher = vview.Dispatcher(); { mesh.SetIndexBuffer( MeshBuffer{ index_buffer }, num_indices, vk::IndexType::eUint32 ); } } }