staging buffer for GN_STATIC_DRAW
This commit is contained in:
@@ -13,12 +13,12 @@ case GN_VERTEX_BUFFER: return VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
|
||||
gnReturnCode VkCreateBuffer(
|
||||
VkBuffer* buffer, VkDeviceMemory* memory, gnBufferInfo info,
|
||||
VkDevice device, VkPhysicalDevice physcialDevice,
|
||||
VkMemoryPropertyFlags flags
|
||||
VkMemoryPropertyFlags flags, VkBufferUsageFlags usage
|
||||
) {
|
||||
VkBufferCreateInfo bufferInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||
.size = info.size,
|
||||
.usage = vkGryphnBufferType(info.type),
|
||||
.usage = usage,
|
||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE
|
||||
};
|
||||
|
||||
@@ -52,30 +52,77 @@ gnReturnCode VkCreateBuffer(
|
||||
return GN_SUCCESS;
|
||||
}
|
||||
|
||||
void VkCopyBuffer(VkBuffer source, VkBuffer destination, size_t size, VkCommandPool pool, VkDevice device, VkQueue queue) {
|
||||
VkCommandBufferAllocateInfo allocInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
|
||||
.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
|
||||
.commandPool = pool,
|
||||
.commandBufferCount = 1
|
||||
};
|
||||
|
||||
VkCommandBuffer commandBuffer;
|
||||
vkAllocateCommandBuffers(device, &allocInfo, &commandBuffer);
|
||||
|
||||
VkCommandBufferBeginInfo beginInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
||||
.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT
|
||||
};
|
||||
vkBeginCommandBuffer(commandBuffer, &beginInfo);
|
||||
|
||||
|
||||
VkBufferCopy copyRegion = {
|
||||
.size = size
|
||||
};
|
||||
vkCmdCopyBuffer(commandBuffer, source, destination, 1, ©Region);
|
||||
vkEndCommandBuffer(commandBuffer);
|
||||
|
||||
VkSubmitInfo submitInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
||||
.commandBufferCount = 1,
|
||||
.pCommandBuffers = &commandBuffer
|
||||
};
|
||||
|
||||
vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE);
|
||||
vkQueueWaitIdle(queue);
|
||||
}
|
||||
|
||||
gnReturnCode gnCreateBufferFn(gnBufferHandle buffer, gnOutputDeviceHandle device, gnBufferInfo info) {
|
||||
buffer->buffer = malloc(sizeof(struct gnPlatformBuffer_t));
|
||||
gnReturnCode createdBuffer = VkCreateBuffer(
|
||||
&buffer->buffer->buffer, &buffer->buffer->bufferMemory,
|
||||
info, device->outputDevice->device, device->physicalDevice.physicalDevice->device,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
|
||||
);
|
||||
|
||||
VkBufferUsageFlags usage = vkGryphnBufferType(info.type);
|
||||
if (info.usage == GN_STATIC_DRAW) {
|
||||
gnReturnCode createdBuffer = VkCreateBuffer(
|
||||
&buffer->buffer->stagingBuffer, &buffer->buffer->stagingBufferMemory,
|
||||
info, device->outputDevice->device, device->physicalDevice.physicalDevice->device,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_BUFFER_USAGE_TRANSFER_SRC_BIT
|
||||
);
|
||||
usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
||||
buffer->buffer->useStagingBuffer = gnTrue;
|
||||
}
|
||||
|
||||
gnReturnCode createdBuffer = VkCreateBuffer(
|
||||
&buffer->buffer->buffer, &buffer->buffer->bufferMemory,
|
||||
info, device->outputDevice->device, device->physicalDevice.physicalDevice->device,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, usage
|
||||
);
|
||||
|
||||
|
||||
return GN_SUCCESS;
|
||||
}
|
||||
void gnBufferDataFn(gnBufferHandle buffer, size_t dataSize, void* data) {
|
||||
void* bufferData;
|
||||
vkMapMemory(buffer->device->outputDevice->device, buffer->buffer->bufferMemory, 0, dataSize, 0, &bufferData);
|
||||
memcpy(bufferData, data, dataSize);
|
||||
vkUnmapMemory(buffer->device->outputDevice->device, buffer->buffer->bufferMemory);
|
||||
if (buffer->buffer->useStagingBuffer) {
|
||||
vkMapMemory(buffer->device->outputDevice->device, buffer->buffer->stagingBufferMemory, 0, dataSize, 0, &bufferData);
|
||||
memcpy(bufferData, data, dataSize);
|
||||
vkUnmapMemory(buffer->device->outputDevice->device, buffer->buffer->stagingBufferMemory);
|
||||
VkCopyBuffer(
|
||||
buffer->buffer->stagingBuffer, buffer->buffer->buffer, dataSize,
|
||||
buffer->device->outputDevice->transferCommandPool, buffer->device->outputDevice->device,
|
||||
buffer->device->outputDevice->transferQueue);
|
||||
} else {
|
||||
vkMapMemory(buffer->device->outputDevice->device, buffer->buffer->bufferMemory, 0, dataSize, 0, &bufferData);
|
||||
memcpy(bufferData, data, dataSize);
|
||||
vkUnmapMemory(buffer->device->outputDevice->device, buffer->buffer->bufferMemory);
|
||||
}
|
||||
}
|
||||
void gnDestroyBufferFn(gnBufferHandle buffer) {
|
||||
if (buffer->buffer->useStagingBuffer == gnTrue) {
|
||||
|
Reference in New Issue
Block a user