@ -20,11 +20,19 @@ void Vulkan::init(GLFWwindow* window)
createRenderpass ( ) ; // Создание проходов рендера
createGraphicPipeline ( ) ; // Создание графического конвейера
createCommandPool ( ) ; // Создание пула команд
createVertexBuffer ( ) ; // Создание буфера вершин
createIndexBuffer ( ) ; // Создание буфера индексов
}
// завершение работы
void Vulkan : : destroy ( )
{
vkDestroyBuffer ( logicalDevice , indexBuffer , nullptr ) ; // Уничтожение буфера индексов
vkFreeMemory ( logicalDevice , indexBufferMemory , nullptr ) ; // Освобождение памяти буфера индексов
vkDestroyBuffer ( logicalDevice , vertexBuffer , nullptr ) ; // Уничтожение буфера вершин
vkFreeMemory ( logicalDevice , vertexBufferMemory , nullptr ) ; // Освобождение памяти буфера вершин
vkDestroyCommandPool ( logicalDevice , commandPool , nullptr ) ; // Уничтожение командного пула
vkDestroyPipeline ( logicalDevice , graphicsPipeline , nullptr ) ; // Уничтожение графического конвейера
@ -803,3 +811,112 @@ void Vulkan::createCommandPool()
throw std : : runtime_error ( " Unable to allocate command buffers " ) ;
}
}
// Копирование между буферами данных
void Vulkan : : copyBuffer ( VkBuffer srcBuffer , VkBuffer dstBuffer , VkDeviceSize size )
{
// Информация о выделяемом буфере команд
VkCommandBufferAllocateInfo allocInfo { } ;
allocInfo . sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO ;
allocInfo . level = VK_COMMAND_BUFFER_LEVEL_PRIMARY ;
allocInfo . commandPool = commandPool ;
allocInfo . commandBufferCount = 1 ;
// Дескриптор и выделение буфера команд
VkCommandBuffer commandBuffer ;
vkAllocateCommandBuffers ( logicalDevice , & allocInfo , & commandBuffer ) ;
// Начало записи команд
VkCommandBufferBeginInfo beginInfo { } ;
beginInfo . sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO ;
beginInfo . flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT ;
vkBeginCommandBuffer ( commandBuffer , & beginInfo ) ;
// Операция копирования
VkBufferCopy copyRegion { } ;
copyRegion . size = size ;
vkCmdCopyBuffer ( commandBuffer , srcBuffer , dstBuffer , 1 , & copyRegion ) ;
// Конец записи команд
vkEndCommandBuffer ( commandBuffer ) ;
// Информация о запускаемых буферах команд
VkSubmitInfo submitInfo { } ;
submitInfo . sType = VK_STRUCTURE_TYPE_SUBMIT_INFO ;
submitInfo . commandBufferCount = 1 ;
submitInfo . pCommandBuffers = & commandBuffer ;
// Запуск командного буфера копирования и ожидание завершения
vkQueueSubmit ( queue . descriptor , 1 , & submitInfo , VK_NULL_HANDLE ) ;
vkQueueWaitIdle ( queue . descriptor ) ;
// Освобождение командного буфера копирования
vkFreeCommandBuffers ( logicalDevice , commandPool , 1 , & commandBuffer ) ;
}
// Создание вершинного буфера
void Vulkan : : createVertexBuffer ( )
{
//Вершины, записываемые в буфер
Vertex vertices [ ] = {
{ { - 0.5f , - 0.5f } , { 1.0f , 0.0f , 0.0f } } ,
{ { 0.5f , - 0.5f } , { 0.0f , 1.0f , 0.0f } } ,
{ { 0.5f , 0.5f } , { 0.0f , 0.0f , 1.0f } } ,
{ { - 0.5f , 0.5f } , { 1.0f , 1.0f , 1.0f } }
} ;
// Размер буфера в байтах
VkDeviceSize bufferSize = sizeof ( Vertex ) * 4 ;
// Промежуточный буфер для переноса на устройство
VkBuffer stagingBuffer ;
VkDeviceMemory stagingBufferMemory ;
createBuffer ( bufferSize , VK_BUFFER_USAGE_TRANSFER_SRC_BIT , VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT , stagingBuffer , stagingBufferMemory ) ;
// Отображение памяти буфера
void * data ;
vkMapMemory ( logicalDevice , stagingBufferMemory , 0 , bufferSize , 0 , & data ) ;
// Копирование вершин в промежуточный буфер
memcpy ( data , vertices , ( size_t ) bufferSize ) ;
// Прекращение отображения памяти буфера
vkUnmapMemory ( logicalDevice , stagingBufferMemory ) ;
// Создание буфера вершин
createBuffer ( bufferSize , VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT , VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT , vertexBuffer , vertexBufferMemory ) ;
// Копирование из промежуточного в буфер вершин
copyBuffer ( stagingBuffer , vertexBuffer , bufferSize ) ;
// Освобождение памяти и уничтожение буферов
vkDestroyBuffer ( logicalDevice , stagingBuffer , nullptr ) ;
vkFreeMemory ( logicalDevice , stagingBufferMemory , nullptr ) ;
}
// Создание буфера индексов
void Vulkan : : createIndexBuffer ( )
{
// Индексы, записываемые в буфер
uint16_t indices [ ] = { 0 , 1 , 2 , 2 , 3 , 0 } ;
// Размер буфера в байтах
VkDeviceSize bufferSize = sizeof ( uint16_t ) * 6 ;
// Промежуточный буфер для переноса на устройство
VkBuffer stagingBuffer ;
VkDeviceMemory stagingBufferMemory ;
createBuffer ( bufferSize , VK_BUFFER_USAGE_TRANSFER_SRC_BIT , VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT , stagingBuffer , stagingBufferMemory ) ;
// Отображение памяти буфера
void * data ;
vkMapMemory ( logicalDevice , stagingBufferMemory , 0 , bufferSize , 0 , & data ) ;
// Копирование вершин в промежуточный буфер
memcpy ( data , indices , ( size_t ) bufferSize ) ;
// Прекращение отображения памяти буфера
vkUnmapMemory ( logicalDevice , stagingBufferMemory ) ;
// Создание буфера вершин
createBuffer ( bufferSize , VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT , VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT , indexBuffer , indexBufferMemory ) ;
// Копирование из промежуточного в буфер вершин
copyBuffer ( stagingBuffer , indexBuffer , bufferSize ) ;
// Освобождение памяти и уничтожение буферов
vkDestroyBuffer ( logicalDevice , stagingBuffer , nullptr ) ;
vkFreeMemory ( logicalDevice , stagingBufferMemory , nullptr ) ;
}