device wide staging buffer
This commit is contained in:
@@ -3,7 +3,11 @@
|
|||||||
#include "output_device/gryphn_output_device.h"
|
#include "output_device/gryphn_output_device.h"
|
||||||
#include "output_device/vulkan_output_devices.h"
|
#include "output_device/vulkan_output_devices.h"
|
||||||
#include "output_device/vulkan_physical_device.h"
|
#include "output_device/vulkan_physical_device.h"
|
||||||
#include "commands/command_buffer/vulkan_command_buffer.h"
|
|
||||||
|
VkDeviceSize min(VkDeviceSize a, VkDeviceSize b) {
|
||||||
|
if (a >= b) return a;
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
VkBufferUsageFlags vkGryphnBufferType(gnBufferType type) {
|
VkBufferUsageFlags vkGryphnBufferType(gnBufferType type) {
|
||||||
VkBufferUsageFlags usageFlags = 0;
|
VkBufferUsageFlags usageFlags = 0;
|
||||||
@@ -58,28 +62,17 @@ gnReturnCode VkCreateBuffer(
|
|||||||
return GN_SUCCESS;
|
return GN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VkCopyBuffer(VkBuffer source, VkBuffer destination, size_t size, VkCommandPool pool, VkDevice device, VkQueue queue) {
|
void VkCopyBuffer(gnDevice device, VkBuffer source, VkBuffer destination, VkBufferCopy copy) {
|
||||||
VkCommandBuffer transferBuffer = VkBeginTransferOperation(device, pool);
|
VkCommandBuffer transferBuffer = gnBeginVulkanTransferOperation(device);
|
||||||
VkBufferCopy copyRegion = {
|
vkCmdCopyBuffer(transferBuffer, source, destination, 1, ©);
|
||||||
.size = size
|
gnEndVulkanTransferOperation(device, transferBuffer);
|
||||||
};
|
|
||||||
vkCmdCopyBuffer(transferBuffer, source, destination, 1, ©Region);
|
|
||||||
VkEndTransferOperation(transferBuffer, pool, queue, device);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gnReturnCode createBuffer(gnBufferHandle buffer, gnOutputDeviceHandle device, gnBufferInfo info) {
|
gnReturnCode createBuffer(gnBufferHandle buffer, gnOutputDeviceHandle device, gnBufferInfo info) {
|
||||||
buffer->buffer = malloc(sizeof(struct gnPlatformBuffer_t));
|
buffer->buffer = malloc(sizeof(struct gnPlatformBuffer_t));
|
||||||
VkBufferUsageFlags usage = vkGryphnBufferType(info.type);
|
VkBufferUsageFlags usage = vkGryphnBufferType(info.type);
|
||||||
buffer->buffer->useStagingBuffer = gnFalse;
|
buffer->buffer->useStagingBuffer = (info.usage == GN_STATIC_DRAW);
|
||||||
if (info.usage == GN_STATIC_DRAW) {
|
if (info.usage == GN_STATIC_DRAW) {
|
||||||
buffer->buffer->useStagingBuffer = gnTrue;
|
|
||||||
VkCreateBuffer(
|
|
||||||
&buffer->buffer->stagingBuffer,
|
|
||||||
info.size, device,
|
|
||||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
|
||||||
VK_BUFFER_USAGE_TRANSFER_SRC_BIT
|
|
||||||
);
|
|
||||||
|
|
||||||
return VkCreateBuffer(
|
return VkCreateBuffer(
|
||||||
&buffer->buffer->buffer,
|
&buffer->buffer->buffer,
|
||||||
info.size, device,
|
info.size, device,
|
||||||
@@ -99,32 +92,31 @@ gnReturnCode createBuffer(gnBufferHandle buffer, gnOutputDeviceHandle device, gn
|
|||||||
|
|
||||||
return GN_SUCCESS;
|
return GN_SUCCESS;
|
||||||
}
|
}
|
||||||
void bufferData(gnBufferHandle buffer, size_t dataSize, void* data) {
|
void bufferData(gnBufferHandle buffer, VkDeviceSize dataSize, void* data) {
|
||||||
void* bufferData;
|
vulkanBufferSubData(buffer, 0, dataSize, data);
|
||||||
if (buffer->buffer->useStagingBuffer) {
|
|
||||||
vkMapMemory(buffer->device->outputDevice->device, buffer->buffer->stagingBuffer.memory, 0, dataSize, 0, &bufferData);
|
|
||||||
memcpy(bufferData, data, dataSize);
|
|
||||||
vkUnmapMemory(buffer->device->outputDevice->device, buffer->buffer->stagingBuffer.memory);
|
|
||||||
VkCopyBuffer(
|
|
||||||
buffer->buffer->stagingBuffer.buffer, buffer->buffer->buffer.buffer, dataSize,
|
|
||||||
buffer->device->outputDevice->transferCommandPool, buffer->device->outputDevice->device,
|
|
||||||
buffer->device->outputDevice->transferQueue);
|
|
||||||
} else {
|
|
||||||
vkMapMemory(buffer->device->outputDevice->device, buffer->buffer->buffer.memory, 0, dataSize, 0, &bufferData);
|
|
||||||
memcpy(bufferData, data, dataSize);
|
|
||||||
vkUnmapMemory(buffer->device->outputDevice->device, buffer->buffer->buffer.memory);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
void vulkanBufferSubData(gnBufferHandle buffer, size_t offset, size_t dataSize, void* data) {
|
void vulkanBufferSubData(gnBufferHandle buffer, size_t offset, size_t dataSize, void* data) {
|
||||||
void* bufferData;
|
void* bufferData;
|
||||||
|
|
||||||
if (buffer->buffer->useStagingBuffer) {
|
if (buffer->buffer->useStagingBuffer) {
|
||||||
vkMapMemory(buffer->device->outputDevice->device, buffer->buffer->stagingBuffer.memory, 0, dataSize, 0, &bufferData);
|
VkGryphnBuffer* stagingBuffer = &buffer->device->outputDevice->stagingBuffer;
|
||||||
memcpy(bufferData + offset, data, dataSize);
|
VkDeviceSize sizeLeft = dataSize;
|
||||||
vkUnmapMemory(buffer->device->outputDevice->device, buffer->buffer->stagingBuffer.memory);
|
int copies = 0;
|
||||||
VkCopyBuffer(
|
while (sizeLeft > 0) {
|
||||||
buffer->buffer->stagingBuffer.buffer, buffer->buffer->buffer.buffer, dataSize,
|
VkDeviceSize chunkSize = (buffer->device->outputDevice->stagingBufferSize < sizeLeft) ? buffer->device->outputDevice->stagingBufferSize : sizeLeft;
|
||||||
buffer->device->outputDevice->transferCommandPool, buffer->device->outputDevice->device,
|
vkMapMemory(buffer->device->outputDevice->device, stagingBuffer->memory, 0, dataSize, 0, &bufferData);
|
||||||
buffer->device->outputDevice->transferQueue);
|
memcpy(bufferData, data + (dataSize - sizeLeft), chunkSize);
|
||||||
|
vkUnmapMemory(buffer->device->outputDevice->device, stagingBuffer->memory);
|
||||||
|
|
||||||
|
VkBufferCopy copyRegion = {
|
||||||
|
.srcOffset = 0,
|
||||||
|
.dstOffset = offset + (dataSize - sizeLeft),
|
||||||
|
.size = chunkSize
|
||||||
|
};
|
||||||
|
VkCopyBuffer(buffer->device, stagingBuffer->buffer, buffer->buffer->buffer.buffer, copyRegion);
|
||||||
|
sizeLeft -= chunkSize;
|
||||||
|
copies++;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
vkMapMemory(buffer->device->outputDevice->device, buffer->buffer->buffer.memory, 0, dataSize, 0, &bufferData);
|
vkMapMemory(buffer->device->outputDevice->device, buffer->buffer->buffer.memory, 0, dataSize, 0, &bufferData);
|
||||||
memcpy(bufferData + offset, data, dataSize);
|
memcpy(bufferData + offset, data, dataSize);
|
||||||
@@ -143,7 +135,7 @@ void gnDestroyVulkanBuffer(VkGryphnBuffer* buffer, VkDevice device) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void destroyBuffer(gnBufferHandle buffer) {
|
void destroyBuffer(gnBufferHandle buffer) {
|
||||||
if (buffer->buffer->useStagingBuffer == gnTrue) gnDestroyVulkanBuffer(&buffer->buffer->stagingBuffer, buffer->device->outputDevice->device);
|
// if (buffer->buffer->useStagingBuffer == gnTrue) gnDestroyVulkanBuffer(&buffer->buffer->stagingBuffer, buffer->device->outputDevice->device);
|
||||||
gnDestroyVulkanBuffer(&buffer->buffer->buffer, buffer->device->outputDevice->device);
|
gnDestroyVulkanBuffer(&buffer->buffer->buffer, buffer->device->outputDevice->device);
|
||||||
free(buffer->buffer);
|
free(buffer->buffer);
|
||||||
}
|
}
|
||||||
|
@@ -11,9 +11,6 @@ void gnDestroyVulkanBuffer(VkGryphnBuffer* buffer, VkDevice device);
|
|||||||
|
|
||||||
struct gnPlatformBuffer_t {
|
struct gnPlatformBuffer_t {
|
||||||
VkGryphnBuffer buffer;
|
VkGryphnBuffer buffer;
|
||||||
|
|
||||||
// for if static draw
|
|
||||||
VkGryphnBuffer stagingBuffer;
|
|
||||||
gnBool useStagingBuffer;
|
gnBool useStagingBuffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -21,6 +18,7 @@ gnReturnCode VkCreateBuffer(
|
|||||||
VkGryphnBuffer* buffer, size_t size, gnDevice device,
|
VkGryphnBuffer* buffer, size_t size, gnDevice device,
|
||||||
VkMemoryPropertyFlags flags, VkBufferUsageFlags usage
|
VkMemoryPropertyFlags flags, VkBufferUsageFlags usage
|
||||||
);
|
);
|
||||||
|
void gnDestroyVulkanBuffer(VkGryphnBuffer* buffer, VkDevice device);
|
||||||
uint32_t VkMemoryIndex(VkPhysicalDevice device, uint32_t memoryType, VkMemoryPropertyFlags flags, gnBool* foundMemory);
|
uint32_t VkMemoryIndex(VkPhysicalDevice device, uint32_t memoryType, VkMemoryPropertyFlags flags, gnBool* foundMemory);
|
||||||
|
|
||||||
gnReturnCode createBuffer(gnBufferHandle buffer, gnOutputDeviceHandle device, gnBufferInfo info);
|
gnReturnCode createBuffer(gnBufferHandle buffer, gnOutputDeviceHandle device, gnBufferInfo info);
|
||||||
|
@@ -85,7 +85,15 @@ gnReturnCode createOutputDevice(gnOutputDeviceHandle outputDevice, gnInstanceHan
|
|||||||
free(queueCreateInfos);
|
free(queueCreateInfos);
|
||||||
free(queueFamilies);
|
free(queueFamilies);
|
||||||
|
|
||||||
return GN_SUCCESS;
|
// create the massive staging buffer
|
||||||
|
outputDevice->outputDevice->stagingBufferSize = 128 * 1024 * 1024;
|
||||||
|
gnReturnCode code = VkCreateBuffer(
|
||||||
|
&outputDevice->outputDevice->stagingBuffer,
|
||||||
|
outputDevice->outputDevice->stagingBufferSize, outputDevice,
|
||||||
|
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
||||||
|
VK_BUFFER_USAGE_TRANSFER_SRC_BIT
|
||||||
|
);
|
||||||
|
return code; // lowkey is a hack
|
||||||
}
|
}
|
||||||
|
|
||||||
void waitForDevice(const gnOutputDeviceHandle device) {
|
void waitForDevice(const gnOutputDeviceHandle device) {
|
||||||
@@ -93,6 +101,7 @@ void waitForDevice(const gnOutputDeviceHandle device) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void destroyOutputDevice(gnOutputDeviceHandle device) {
|
void destroyOutputDevice(gnOutputDeviceHandle device) {
|
||||||
|
gnDestroyVulkanBuffer(&device->outputDevice->stagingBuffer, device->outputDevice->device);
|
||||||
vkDestroyCommandPool(device->outputDevice->device, device->outputDevice->transferCommandPool, NULL);
|
vkDestroyCommandPool(device->outputDevice->device, device->outputDevice->transferCommandPool, NULL);
|
||||||
vkDestroyDevice(device->outputDevice->device, NULL);
|
vkDestroyDevice(device->outputDevice->device, NULL);
|
||||||
free(device->outputDevice);
|
free(device->outputDevice);
|
||||||
|
@@ -12,6 +12,7 @@ typedef struct gnPlatformOutputDevice_t {
|
|||||||
VkCommandPool transferCommandPool;
|
VkCommandPool transferCommandPool;
|
||||||
|
|
||||||
VkGryphnBuffer stagingBuffer;
|
VkGryphnBuffer stagingBuffer;
|
||||||
|
VkDeviceSize stagingBufferSize;
|
||||||
|
|
||||||
gnBool enabledOversizedDescriptorPools;
|
gnBool enabledOversizedDescriptorPools;
|
||||||
} gnPlatformOutputDevice;
|
} gnPlatformOutputDevice;
|
||||||
|
Reference in New Issue
Block a user