/
Zamar_Terrier
/
TigorEngine
Обзор
Документация
Войти
/
Zamar_Terrier
/
TigorEngine
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/Core/e_buffer.c
379 строк
12 KB
Zamar_Terrier
Доработка + нововведения
06 июл 2026, 16:26
Верифицирован
06 июл 2026, 16:26
0d4ab95
Код
Авторство
О чём код?
#include "Core/e_memory.h" #include "Core/e_device.h" #include "Core/e_buffer.h" #include "Core/e_blue_print.h" #include <vulkan/vulkan.h> #include "Objects/gameObject2D.h" #include "Data/e_resource_data.h" #include "Data/e_resource_engine.h" extern TEngine engine; void BuffersCreateCommandPool() { QueueFamilyIndices queueFamilyIndices = findQueueFamilies(engine.device.e_physicalDevice); VkCommandPoolCreateInfo poolInfo = {0}; poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; poolInfo.queueFamilyIndex = queueFamilyIndices.graphicsFamily; poolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; if (vkCreateCommandPool(engine.device.e_device, &poolInfo, NULL, &engine.device.commandPool) != VK_SUCCESS) { printf("failed to create command pool!"); exit(1); } } void BuffersCreateCommand() { engine.device.commandBuffers = AllocateMemoryP(engine.imagesCount, sizeof(VkCommandBuffer), &engine.device); VkCommandBufferAllocateInfo allocInfo = {0}; allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; allocInfo.commandPool = (VkCommandPool)engine.device.commandPool; allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; allocInfo.commandBufferCount = (uint32_t)engine.imagesCount; if (vkAllocateCommandBuffers(engine.device.e_device, &allocInfo, engine.device.commandBuffers) != VK_SUCCESS) { printf("failed to allocate command buffers!"); exit(1); } } int BuffersCreateVertex(VertexParam *vert) { VertexParam *vertex = (VertexParam *)vert; // Выделение памяти VkDeviceSize bufferSize; bufferSize = vertex->typeSize * vertex->num_verts; if (bufferSize == 0) return 1; BuffersCreate(bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &vertex->buffer, TIGOR_BUFFER_ALLOCATE_VERTEX); vertex->bufferSize = bufferSize; vertex->extend = false; return 0; } int BuffersCreateVertexInst(VertexParam *vert) { VertexParam *vertex = (VertexParam *)vert; if (vertex->num_verts >= MAX_VERTEX_COUNT) { printf("Очень много вершин!\n"); return 1; } // Выделение памяти VkDeviceSize bufferSize; bufferSize = vertex->typeSize * MAX_VERTEX_COUNT; BuffersCreate(bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &vertex->buffer, TIGOR_BUFFER_ALLOCATE_VERTEX); vertex->bufferSize = bufferSize; vertex->extend = true; return 0; } int BuffersUpdateVertex(VertexParam *vert) { VertexParam *vertex = (VertexParam *)vert; BufferObject stagingBuffer; VkDeviceSize bufferSize = vertex->typeSize * vertex->num_verts; if (!vertex->extend) { if (bufferSize != vertex->bufferSize) return 1; } else { if (vertex->num_verts >= MAX_VERTEX_COUNT) { printf("Очень много вершин!\n"); return 1; } } BuffersCreate(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &stagingBuffer, TIGOR_BUFFER_ALLOCATE_STAGING); void *data; vkMapMemory(engine.device.e_device, stagingBuffer.memory, 0, bufferSize, 0, &data); memset(data, 0, bufferSize); memcpy(data, vertex->vertices, (size_t)bufferSize); vkUnmapMemory(engine.device.e_device, stagingBuffer.memory); BuffersCopy(&stagingBuffer, &vertex->buffer, bufferSize); BuffersDestroyer(&stagingBuffer); if (vertex->extend) vertex->bufferSize = bufferSize; // Обновляем размер, если нужно return 0; } int BuffersCreateIndex(IndexParam *indx) { IndexParam *index = (IndexParam *)indx; VkDeviceSize bufferSize = index->typeSize * index->indexesSize; if (bufferSize == 0) return 1; BuffersCreate(bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &index->buffer, TIGOR_BUFFER_ALLOCATE_INDEX); index->bufferSize = bufferSize; index->extend = false; return 0; } int BuffersCreateIndexInst(IndexParam *indx) { IndexParam *index = (IndexParam *)indx; if (index->typeSize >= MAX_INDEX_COUNT) { printf("Очень много индексов!\n"); return 1; } VkDeviceSize bufferSize = index->typeSize * MAX_INDEX_COUNT; BuffersCreate(bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &index->buffer, TIGOR_BUFFER_ALLOCATE_INDEX); index->bufferSize = bufferSize; index->extend = true; return 0; } int BuffersUpdateIndex(IndexParam *indx) { IndexParam *index = (IndexParam *)indx; BufferObject stagingBuffer; VkDeviceSize bufferSize = index->typeSize * index->indexesSize; if (!index->extend) { if (bufferSize != index->bufferSize) return 1; } else { if (index->indexesSize >= MAX_INDEX_COUNT) { printf("Очень много индексов!\n"); return 1; } } BuffersCreate(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &stagingBuffer, TIGOR_BUFFER_ALLOCATE_STAGING); void *data; vkMapMemory(engine.device.e_device, stagingBuffer.memory, 0, bufferSize, 0, &data); memset(data, 0, bufferSize); memcpy(data, index->indices, (size_t)bufferSize); vkUnmapMemory(engine.device.e_device, stagingBuffer.memory); BuffersCopy(&stagingBuffer, &index->buffer, bufferSize); BuffersDestroyer(&stagingBuffer); if (index->extend) index->bufferSize = bufferSize; return 0; } void BuffersCreateUniform(BufferContainer *uniform) { for (int i = 0; i < uniform->count; i++) { BuffersCreate(uniform->type_size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &uniform->buffers[i], TIGOR_BUFFER_ALLOCATE_UNIFORM); } } void BuffersCreateStorage(BufferContainer *uniform) { for (int i = 0; i < uniform->count; i++) { BuffersCreate(uniform->type_size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &uniform->buffers[i], TIGOR_BUFFER_ALLOCATE_UNIFORM); } } void BuffersCreateStorageVertex(BufferContainer *uniform) { for (int i = 0; i < uniform->count; i++) { BuffersCreate(uniform->type_size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &uniform->buffers[i], TIGOR_BUFFER_ALLOCATE_UNIFORM); } } uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties) { VkPhysicalDeviceMemoryProperties memProperties = {0}; vkGetPhysicalDeviceMemoryProperties(engine.device.e_physicalDevice, &memProperties); for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) { if ((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties) { return i; } } printf("failed to find suitable memory type!\n"); exit(1); } void BuffersCreate(uint64_t size, uint32_t usage, uint32_t properties, BufferObject *buffer, uint32_t type) { VkBufferCreateInfo bufferInfo = {0}; bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; bufferInfo.size = size; bufferInfo.usage = usage; bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; if (vkCreateBuffer(engine.device.e_device, &bufferInfo, NULL, &buffer->buffer) != VK_SUCCESS) { printf("Error : Failed to create buffer!\n"); exit(1); } VkMemoryRequirements memRequirements = {0}; vkGetBufferMemoryRequirements(engine.device.e_device, buffer->buffer, &memRequirements); VkMemoryAllocateInfo allocInfo = {0}; allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; allocInfo.allocationSize = memRequirements.size; allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, properties); if (vkAllocateMemory(engine.device.e_device, &allocInfo, NULL, &buffer->memory) != VK_SUCCESS) { printf("Error : Failed to allocate buffer memory!\n"); exit(1); } vkBindBufferMemory(engine.device.e_device, buffer->buffer, buffer->memory, 0); } void BuffersDestroyer(void *obj) { BufferObject *buffer = (BufferObject *)obj; if (buffer == NULL || buffer->buffer == NULL) return; vkDestroyBuffer(engine.device.e_device, buffer->buffer, NULL); vkFreeMemory(engine.device.e_device, buffer->memory, NULL); buffer->buffer = VK_NULL_HANDLE; buffer->memory = VK_NULL_HANDLE; } void BuffersDestroyContainer(BufferContainer *container) { for (int i = 0; i < container->count; i++) { BuffersDestroyer(&container->buffers[i]); } container->count = 0; } void BuffersCopy(BufferObject *srcBuffer, BufferObject *dstBuffer, uint64_t size) { VkCommandBuffer commandBuffer = beginSingleTimeCommands(); VkBufferCopy copyRegion = {0}; copyRegion.srcOffset = 0; // Optional copyRegion.dstOffset = 0; // Optional copyRegion.size = size; vkCmdCopyBuffer(commandBuffer, srcBuffer->buffer, dstBuffer->buffer, 1, ©Region); endSingleTimeCommands(commandBuffer); } void BuffersFromImage(VkImage image, uint32_t width, uint32_t height, BufferObject *dstBuffer) { VkDeviceSize imageSize = (VkDeviceSize)width * height * 4; VkCommandBuffer commandBuffer = beginSingleTimeCommands(); VkImageMemoryBarrier barrier = { .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, .oldLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, .newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .image = image, .subresourceRange = { .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, .baseMipLevel = 0, .levelCount = 1, .baseArrayLayer = 0, .layerCount = 1}, .srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // зависит от предыдущего использования .dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT}; vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 0, NULL, 1, &barrier); // 3.2. Копирование из изображения в буфер VkBufferImageCopy copyRegion = { .bufferOffset = 0, .bufferRowLength = width, // плотная упаковка строк .bufferImageHeight = height, .imageSubresource = { .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, .mipLevel = 0, .baseArrayLayer = 0, .layerCount = 1}, .imageOffset = {0, 0, 0}, .imageExtent = {width, height, 1}}; vkCmdCopyImageToBuffer(commandBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstBuffer->buffer, 1, ©Region); endSingleTimeCommands(commandBuffer); } void BuffersRecreateUniform(BluePrints *bPrints) { for (int i = 0; i < bPrints->num_blue_print_packs; i++) { BluePrintPack *pack = &bPrints->blue_print_packs[i]; for (int j = 0; j < pack->num_descriptors; j++) { BluePrintDescriptor *descriptor = &pack->descriptors[j]; if (descriptor->descrType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) { descriptor->uniform.count = engine.imagesCount; descriptor->uniform.type_size = descriptor->buffsize; BuffersCreateUniform(&descriptor->uniform); } } } }