Merge branch 'master' of https://github.com/GregoryWells2007/Gryphn
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS on)
|
||||
project(GryphnVulkanImpl)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
add_compile_definitions(GN_REVEAL_IMPL)
|
||||
|
||||
file(GLOB_RECURSE SOURCE_FILES CONFIGURE_DEPENDS "src/*.c" "src/*.h")
|
||||
@@ -9,9 +11,11 @@ if (APPLE)
|
||||
endif()
|
||||
|
||||
find_package(Vulkan REQUIRED)
|
||||
add_library(GryphnVulkanImpl STATIC ${SOURCE_FILES} ${METAL_FILES} ${LOADER_FILES})
|
||||
add_library(GryphnVulkanImpl STATIC ${SOURCE_FILES} ${METAL_FILES} ${LOADER_FILES} depends/memory_allocator/vk_mem_alloc.cpp)
|
||||
target_link_libraries(GryphnVulkanImpl ${Vulkan_LIBRARY})
|
||||
|
||||
target_compile_options(GryphnVulkanImpl PRIVATE -Wno-nullability-completeness)
|
||||
|
||||
target_include_directories(GryphnVulkanImpl PUBLIC
|
||||
${Vulkan_INCLUDE_DIRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/
|
||||
@@ -23,6 +27,7 @@ target_include_directories(GryphnVulkanImpl PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../include/
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../depends/
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/depends/
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
|
@@ -0,0 +1,2 @@
|
||||
#define VMA_IMPLEMENTATION
|
||||
#include "vk_mem_alloc.h"
|
19535
projects/apis/vulkan/depends/memory_allocator/vk_mem_alloc.h
Normal file
19535
projects/apis/vulkan/depends/memory_allocator/vk_mem_alloc.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -37,7 +37,8 @@ gnDeviceFunctions loadVulkanDeviceFunctions(void) {
|
||||
._gnCreateBuffer = createBuffer,
|
||||
._gnBufferData = vulkanBufferData,
|
||||
._gnBufferSubData = vulkanBufferSubData,
|
||||
._gnMapBuffer = mapBuffer,
|
||||
._gnMapBuffer = vulkanMapBuffer,
|
||||
._gnUnmapBuffer = vulkanUnmapBuffer,
|
||||
._gnDestroyBuffer = destroyBuffer,
|
||||
|
||||
._gnCreateUniformPool = createUniformPool,
|
||||
|
@@ -7,57 +7,13 @@
|
||||
|
||||
VkBufferUsageFlags vkGryphnBufferType(gnBufferType type) {
|
||||
VkBufferUsageFlags usageFlags = 0;
|
||||
switch (type) {
|
||||
case GN_VERTEX_BUFFER: usageFlags |= VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; break;
|
||||
case GN_INDEX_BUFFER: usageFlags |= VK_BUFFER_USAGE_INDEX_BUFFER_BIT; break;
|
||||
case GN_UNIFORM_BUFFER: usageFlags |= VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; break;
|
||||
case GN_STORAGE_BUFFER: usageFlags |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; break;
|
||||
}
|
||||
if ((type & GN_VERTEX_BUFFER) == GN_VERTEX_BUFFER) usageFlags |= VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
|
||||
if ((type & GN_INDEX_BUFFER) == GN_INDEX_BUFFER) usageFlags |= VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
|
||||
if ((type & GN_UNIFORM_BUFFER) == GN_UNIFORM_BUFFER) usageFlags |= VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
|
||||
if ((type & GN_STORAGE_BUFFER) == GN_STORAGE_BUFFER) usageFlags |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
|
||||
return usageFlags;
|
||||
}
|
||||
|
||||
uint32_t VkMemoryIndex(VkPhysicalDevice device, uint32_t memoryType, VkMemoryPropertyFlags flags, gnBool* foundMemory) {
|
||||
VkPhysicalDeviceMemoryProperties memoryProperties;
|
||||
vkGetPhysicalDeviceMemoryProperties(device, &memoryProperties);
|
||||
for (uint32_t i = 0; i < memoryProperties.memoryTypeCount; i++) {
|
||||
if ((memoryType & (1 << i)) && (memoryProperties.memoryTypes[i].propertyFlags & flags) == flags) {
|
||||
*foundMemory = GN_TRUE;
|
||||
return i;
|
||||
}
|
||||
} // this whole thing was adapted from vulkan-tutorial.com
|
||||
return 0;
|
||||
}
|
||||
gnReturnCode VkCreateBuffer(
|
||||
VkGryphnBuffer* buffer, size_t size, gnDevice device,
|
||||
VkMemoryPropertyFlags flags, VkBufferUsageFlags usage
|
||||
) {
|
||||
VkBufferCreateInfo bufferInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||
.size = size,
|
||||
.usage = usage,
|
||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE
|
||||
};
|
||||
|
||||
VkResult created_buffer = vkCreateBuffer(device->outputDevice->device, &bufferInfo, NULL, &buffer->buffer);
|
||||
if (created_buffer != VK_SUCCESS)
|
||||
return VkResultToGnReturnCode(created_buffer);
|
||||
|
||||
VkMemoryRequirements bufferRequirements;
|
||||
vkGetBufferMemoryRequirements(device->outputDevice->device, buffer->buffer, &bufferRequirements);
|
||||
|
||||
gnBool foundMemory = GN_FALSE;
|
||||
VkMemoryAllocateInfo memoryAllocateInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
|
||||
.allocationSize = bufferRequirements.size,
|
||||
.memoryTypeIndex = VkMemoryIndex(device->outputDevice->physicalDevice, bufferRequirements.memoryTypeBits, flags, &foundMemory)
|
||||
};
|
||||
if (!foundMemory) return GN_FAILED_TO_ALLOCATE_MEMORY;
|
||||
|
||||
VkResult memoryFound = vkAllocateMemory(device->outputDevice->device, &memoryAllocateInfo, NULL, &buffer->memory);
|
||||
if (memoryFound == VK_SUCCESS) vkBindBufferMemory(device->outputDevice->device, buffer->buffer, buffer->memory, 0);
|
||||
return VkResultToGnReturnCode(memoryFound);
|
||||
}
|
||||
|
||||
void VkCopyBuffer(gnDevice device, VkBuffer source, VkBuffer destination, VkBufferCopy copy) {
|
||||
VkCommandBuffer transferBuffer = gnBeginVulkanTransferOperation(device);
|
||||
vkCmdCopyBuffer(transferBuffer, source, destination, 1, ©);
|
||||
@@ -68,19 +24,41 @@ gnReturnCode createBuffer(gnBufferHandle buffer, gnOutputDeviceHandle device, gn
|
||||
buffer->buffer = malloc(sizeof(struct gnPlatformBuffer_t));
|
||||
buffer->buffer->useStagingBuffer = (info.usage == GN_STATIC_DRAW);
|
||||
if (info.usage == GN_STATIC_DRAW) {
|
||||
return VkCreateBuffer(
|
||||
&buffer->buffer->buffer,
|
||||
info.size, device,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
vkGryphnBufferType(info.type) | VK_BUFFER_USAGE_TRANSFER_DST_BIT
|
||||
);
|
||||
VkBufferCreateInfo bufferCreateInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||
.pNext = NULL,
|
||||
.flags = 0,
|
||||
.queueFamilyIndexCount = 0,
|
||||
.size = info.size,
|
||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||
.usage = vkGryphnBufferType(info.type) | VK_BUFFER_USAGE_TRANSFER_DST_BIT
|
||||
};
|
||||
|
||||
VmaAllocationCreateInfo bufferAllocationInfo = {
|
||||
.usage = VMA_MEMORY_USAGE_AUTO,
|
||||
.flags = 0,
|
||||
.requiredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
};
|
||||
|
||||
return VkResultToGnReturnCode(vmaCreateBuffer(device->outputDevice->allocator, &bufferCreateInfo, &bufferAllocationInfo, &buffer->buffer->buffer.buffer, &buffer->buffer->buffer.allocation, NULL));
|
||||
} else {
|
||||
return VkCreateBuffer(
|
||||
&buffer->buffer->buffer,
|
||||
info.size, device,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
||||
vkGryphnBufferType(info.type)
|
||||
);
|
||||
VkBufferCreateInfo bufferCreateInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||
.pNext = NULL,
|
||||
.flags = 0,
|
||||
.queueFamilyIndexCount = 0,
|
||||
.size = info.size,
|
||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||
.usage = vkGryphnBufferType(info.type)
|
||||
};
|
||||
|
||||
VmaAllocationCreateInfo bufferAllocationInfo = {
|
||||
.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,
|
||||
.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
|
||||
.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
||||
};
|
||||
|
||||
return VkResultToGnReturnCode(vmaCreateBuffer(device->outputDevice->allocator, &bufferCreateInfo, &bufferAllocationInfo, &buffer->buffer->buffer.buffer, &buffer->buffer->buffer.allocation, NULL));
|
||||
}
|
||||
|
||||
return GN_SUCCESS;
|
||||
@@ -95,9 +73,9 @@ void vulkanBufferSubData(gnBufferHandle buffer, size_t offset, size_t dataSize,
|
||||
VkDeviceSize sizeLeft = dataSize;
|
||||
while (sizeLeft > 0) {
|
||||
VkDeviceSize chunkSize = (buffer->device->outputDevice->stagingBufferSize < sizeLeft) ? buffer->device->outputDevice->stagingBufferSize : sizeLeft;
|
||||
vkMapMemory(buffer->device->outputDevice->device, stagingBuffer->memory, 0, chunkSize, 0, &bufferData);
|
||||
vulkanMapBufferInternal(buffer->device, *stagingBuffer, &bufferData);
|
||||
memcpy(bufferData, (char*)data + (dataSize - sizeLeft), chunkSize);
|
||||
vkUnmapMemory(buffer->device->outputDevice->device, stagingBuffer->memory);
|
||||
vulkanUnmapBufferInternal(buffer->device, *stagingBuffer);
|
||||
|
||||
VkBufferCopy copyRegion = {
|
||||
.srcOffset = 0,
|
||||
@@ -108,24 +86,35 @@ void vulkanBufferSubData(gnBufferHandle buffer, size_t offset, size_t dataSize,
|
||||
sizeLeft -= chunkSize;
|
||||
}
|
||||
} else {
|
||||
vkMapMemory(buffer->device->outputDevice->device, buffer->buffer->buffer.memory, 0, dataSize, 0, &bufferData);
|
||||
bufferData = vulkanMapBuffer(buffer);
|
||||
memcpy((char*)bufferData + offset, data, dataSize);
|
||||
vkUnmapMemory(buffer->device->outputDevice->device, buffer->buffer->buffer.memory);
|
||||
vulkanUnmapBuffer(buffer);
|
||||
}
|
||||
}
|
||||
void* mapBuffer(gnBufferHandle buffer) {
|
||||
|
||||
|
||||
void vulkanMapBufferInternal(gnDevice device, VkGryphnBuffer buffer, void* data) {
|
||||
vmaMapMemory(device->outputDevice->allocator, buffer.allocation, data);
|
||||
}
|
||||
void vulkanUnmapBufferInternal(gnDevice device, VkGryphnBuffer buffer) {
|
||||
vmaUnmapMemory(device->outputDevice->allocator, buffer.allocation);
|
||||
}
|
||||
|
||||
void* vulkanMapBuffer(gnBufferHandle buffer) {
|
||||
void* data;
|
||||
vkMapMemory(buffer->device->outputDevice->device, buffer->buffer->buffer.memory, 0, buffer->info.size, 0, &data);
|
||||
vulkanMapBufferInternal(buffer->device, buffer->buffer->buffer, &data);
|
||||
return data;
|
||||
}
|
||||
|
||||
void gnDestroyVulkanBuffer(VkGryphnBuffer* buffer, VkDevice device) {
|
||||
vkDestroyBuffer(device, buffer->buffer, NULL);
|
||||
vkFreeMemory(device, buffer->memory, NULL);
|
||||
void vulkanUnmapBuffer(gnBufferHandle buffer) {
|
||||
vulkanUnmapBufferInternal(buffer->device, buffer->buffer->buffer);
|
||||
}
|
||||
|
||||
void gnDestroyVulkanBuffer(VkGryphnBuffer* buffer, gnDevice device) {
|
||||
vmaDestroyBuffer(device->outputDevice->allocator, buffer->buffer, buffer->allocation);
|
||||
}
|
||||
|
||||
void destroyBuffer(gnBufferHandle buffer) {
|
||||
// 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);
|
||||
free(buffer->buffer);
|
||||
}
|
||||
|
@@ -2,27 +2,32 @@
|
||||
#include <vulkan/vulkan.h>
|
||||
#include "utils/gryphn_bool.h"
|
||||
#include <buffers/gryphn_buffer.h>
|
||||
#include <memory_allocator/vk_mem_alloc.h>
|
||||
|
||||
typedef struct VkGryphnBuffer {
|
||||
VkBuffer buffer;
|
||||
VkDeviceMemory memory;
|
||||
VmaAllocation allocation;
|
||||
} VkGryphnBuffer;
|
||||
void gnDestroyVulkanBuffer(VkGryphnBuffer* buffer, VkDevice device);
|
||||
|
||||
struct gnPlatformBuffer_t {
|
||||
VkGryphnBuffer buffer;
|
||||
gnBool useStagingBuffer;
|
||||
};
|
||||
|
||||
gnReturnCode VkCreateBuffer(
|
||||
VkGryphnBuffer* buffer, size_t size, gnDevice device,
|
||||
VkMemoryPropertyFlags flags, VkBufferUsageFlags usage
|
||||
);
|
||||
void gnDestroyVulkanBuffer(VkGryphnBuffer* buffer, VkDevice device);
|
||||
uint32_t VkMemoryIndex(VkPhysicalDevice device, uint32_t memoryType, VkMemoryPropertyFlags flags, gnBool* foundMemory);
|
||||
// gnReturnCode VkCreateBuffer(
|
||||
// VkGryphnBuffer* buffer, size_t size, gnDevice device,
|
||||
// VkMemoryPropertyFlags flags, VkBufferUsageFlags usage
|
||||
// );
|
||||
// void gnDestroyVulkanBuffer(VkGryphnBuffer* buffer, gnDevice device);
|
||||
// uint32_t VkMemoryIndex(VkPhysicalDevice device, uint32_t memoryType, VkMemoryPropertyFlags flags, gnBool* foundMemory);
|
||||
|
||||
gnReturnCode createBuffer(gnBufferHandle buffer, gnOutputDeviceHandle device, gnBufferInfo info);
|
||||
void vulkanBufferData(gnBufferHandle buffer, size_t dataSize, void* data);
|
||||
void vulkanBufferSubData(gnBufferHandle buffer, size_t offset, size_t dataSize, void* data);
|
||||
void* mapBuffer(gnBufferHandle buffer);
|
||||
|
||||
void vulkanMapBufferInternal(gnDevice device, VkGryphnBuffer buffer, void* data);
|
||||
void vulkanUnmapBufferInternal(gnDevice device, VkGryphnBuffer buffer);
|
||||
void* vulkanMapBuffer(gnBufferHandle buffer);
|
||||
void vulkanUnmapBuffer(gnBufferHandle buffer);
|
||||
|
||||
void destroyBuffer(gnBufferHandle buffer);
|
||||
|
@@ -43,9 +43,9 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL vk_debuggerDebugCallback(
|
||||
return VK_TRUE;
|
||||
}
|
||||
|
||||
gnReturnCode vulkanCreateInstance(gnInstanceHandle instance, gnInstanceCreateInfo* instanceInfo, gryphnInstanceFunctionLayers* next) {
|
||||
gnReturnCode vulkanCreateInstance(gnInstanceHandle instance, gnInstanceCreateInfo* instanceInfo, gryphnInstanceFunctionLayers* next, gnAllocators* alloctors) {
|
||||
if (next != NULL) { return GN_SUCCESS; }
|
||||
instance->instance = malloc(sizeof(gnPlatformInstance));
|
||||
instance->instance = alloctors->malloc(sizeof(gnPlatformInstance), alloctors->userData);
|
||||
|
||||
vkStringArrayList extensions = vkStringArrayListCreate();
|
||||
vkStringArrayListAdd(extensions, "VK_KHR_surface");
|
||||
@@ -109,7 +109,8 @@ gnReturnCode vulkanCreateInstance(gnInstanceHandle instance, gnInstanceCreateInf
|
||||
return VkResultToGnReturnCode(vkCreateInstance(&createInfo, NULL, &instance->instance->vk_instance));
|
||||
}
|
||||
|
||||
void vulkanDestroyInstance(gnInstanceHandle instance, gryphnInstanceFunctionLayers* next) {
|
||||
void vulkanDestroyInstance(gnInstanceHandle instance, gryphnInstanceFunctionLayers* next, gnAllocators* alloctors) {
|
||||
if (next != NULL) { return; }
|
||||
vkDestroyInstance(instance->instance->vk_instance, NULL);
|
||||
alloctors->free(instance->instance, alloctors->userData);
|
||||
}
|
||||
|
@@ -14,8 +14,8 @@ typedef struct gnPlatformInstance_t {
|
||||
vkUserData userData;
|
||||
} gnPlatformInstance;
|
||||
|
||||
gnReturnCode vulkanCreateInstance(gnInstanceHandle instance, gnInstanceCreateInfo* instanceInfo, gryphnInstanceFunctionLayers* next);
|
||||
void vulkanDestroyInstance(gnInstanceHandle instance, gryphnInstanceFunctionLayers* next);
|
||||
gnReturnCode vulkanCreateInstance(gnInstanceHandle instance, gnInstanceCreateInfo* instanceInfo, gryphnInstanceFunctionLayers* next, gnAllocators* alloctors);
|
||||
void vulkanDestroyInstance(gnInstanceHandle instance, gryphnInstanceFunctionLayers* next, gnAllocators* alloctors);
|
||||
|
||||
typedef const char* vkString;
|
||||
GN_ARRAY_LIST_HEADER(vkString);
|
||||
|
@@ -4,6 +4,7 @@
|
||||
#include "vulkan_device_extensions.h"
|
||||
#include "instance/gryphn_instance.h"
|
||||
#include "commands/command_buffer/vulkan_command_buffer.h"
|
||||
#include "instance/vulkan_instance.h"
|
||||
#include "vulkan_result_converter.h"
|
||||
#include "string.h"
|
||||
|
||||
@@ -95,15 +96,34 @@ gnReturnCode createVulkanOutputDevice(gnInstanceHandle instance, gnOutputDeviceH
|
||||
VkResult fence_result = vkCreateFence(device->outputDevice->device, &fenceInfo, NULL, &device->outputDevice->barrierFence);
|
||||
if (fence_result != VK_SUCCESS) VkResultToGnReturnCode(fence_result);
|
||||
|
||||
VmaAllocatorCreateInfo allocatorCreateInfo = {
|
||||
.device = device->outputDevice->device,
|
||||
.physicalDevice = device->outputDevice->physicalDevice,
|
||||
.instance = instance->instance->vk_instance,
|
||||
};
|
||||
if (vmaCreateAllocator(&allocatorCreateInfo, &device->outputDevice->allocator) != VK_SUCCESS)
|
||||
return GN_FAILED_CREATE_ALLOCATOR;
|
||||
|
||||
// create the massive staging buffer
|
||||
device->outputDevice->stagingBufferSize = 128 * 1024 * 1024;
|
||||
gnReturnCode code = VkCreateBuffer(
|
||||
&device->outputDevice->stagingBuffer,
|
||||
device->outputDevice->stagingBufferSize, device,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
||||
VK_BUFFER_USAGE_TRANSFER_SRC_BIT
|
||||
);
|
||||
return code; // lowkey is a hack
|
||||
|
||||
VkBufferCreateInfo bufferCreateInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||
.pNext = NULL,
|
||||
.flags = 0,
|
||||
.queueFamilyIndexCount = 0,
|
||||
.size = device->outputDevice->stagingBufferSize,
|
||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||
.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT
|
||||
};
|
||||
|
||||
VmaAllocationCreateInfo bufferAllocationInfo = {
|
||||
.usage = VMA_MEMORY_USAGE_CPU_ONLY,
|
||||
.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
|
||||
.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
||||
};
|
||||
|
||||
return VkResultToGnReturnCode(vmaCreateBuffer(device->outputDevice->allocator, &bufferCreateInfo, &bufferAllocationInfo, &device->outputDevice->stagingBuffer.buffer, &device->outputDevice->stagingBuffer.allocation, NULL)); // lowkey is a hack
|
||||
}
|
||||
|
||||
void waitForDevice(const gnOutputDeviceHandle device) {
|
||||
@@ -112,8 +132,9 @@ void waitForDevice(const gnOutputDeviceHandle device) {
|
||||
|
||||
void destroyVulkanOutputDevice(gnOutputDeviceHandle device) {
|
||||
vkDestroyFence(device->outputDevice->device, device->outputDevice->barrierFence, NULL);
|
||||
gnDestroyVulkanBuffer(&device->outputDevice->stagingBuffer, device->outputDevice->device);
|
||||
vkDestroyCommandPool(device->outputDevice->device, device->outputDevice->transferCommandPool, NULL);
|
||||
vmaDestroyBuffer(device->outputDevice->allocator, device->outputDevice->stagingBuffer.buffer, device->outputDevice->stagingBuffer.allocation);
|
||||
vmaDestroyAllocator(device->outputDevice->allocator);
|
||||
vkDestroyDevice(device->outputDevice->device, NULL);
|
||||
free(device->outputDevice);
|
||||
}
|
||||
|
@@ -3,6 +3,7 @@
|
||||
#include <output_device/gryphn_output_device.h>
|
||||
#include "buffers/vulkan_buffer.h"
|
||||
#include "vulkan_physical_device.h"
|
||||
#include <memory_allocator/vk_mem_alloc.h>
|
||||
|
||||
typedef struct vulkanQueue {
|
||||
VkQueue queue;
|
||||
@@ -24,6 +25,8 @@ typedef struct gnPlatformOutputDevice_t {
|
||||
|
||||
VkFence barrierFence;
|
||||
gnBool enabledOversizedDescriptorPools;
|
||||
|
||||
VmaAllocator allocator;
|
||||
} gnPlatformOutputDevice;
|
||||
|
||||
VkCommandBuffer gnBeginVulkanTransferOperation(gnDevice device);
|
||||
|
@@ -143,18 +143,10 @@ void VkCopyBufferToImage(VkGryphnBuffer buffer, VkGryphnImage image, gnExtent3D
|
||||
|
||||
gnReturnCode createTexture(gnTexture texture, gnDevice device, const gnTextureInfo info) {
|
||||
texture->texture = malloc(sizeof(struct gnPlatformTexture_t));
|
||||
|
||||
size_t imageSize = info.extent.width * info.extent.height;
|
||||
if (info.format == GN_FORMAT_BGRA8_SRGB) { imageSize *= 4; }
|
||||
if (info.format == GN_FORMAT_RGBA8_SRGB) { imageSize *= 4; }
|
||||
|
||||
gnReturnCode staginBufferCreateCode = VkCreateBuffer(
|
||||
&texture->texture->buffer, imageSize, device,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_BUFFER_USAGE_TRANSFER_SRC_BIT
|
||||
);
|
||||
if (staginBufferCreateCode != GN_SUCCESS) return staginBufferCreateCode;
|
||||
texture->texture->size = imageSize;
|
||||
|
||||
VkImageCreateInfo imageInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||
@@ -172,27 +164,14 @@ gnReturnCode createTexture(gnTexture texture, gnDevice device, const gnTextureIn
|
||||
.imageType = vkGryphnTextureType(info.type),
|
||||
.format = vkGryphnFormatToVulkanFormat(info.format)
|
||||
};
|
||||
|
||||
VkResult res = vkCreateImage(device->outputDevice->device, &imageInfo, NULL, &texture->texture->image.image);
|
||||
if (res != VK_SUCCESS) return VkResultToGnReturnCode(res);
|
||||
|
||||
VkMemoryRequirements memRequirements;
|
||||
vkGetImageMemoryRequirements(device->outputDevice->device, texture->texture->image.image, &memRequirements);
|
||||
|
||||
gnBool foundMemory = GN_FALSE;
|
||||
VkMemoryAllocateInfo allocInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
|
||||
.allocationSize = memRequirements.size,
|
||||
.memoryTypeIndex = VkMemoryIndex(device->outputDevice->physicalDevice, memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &foundMemory)
|
||||
VmaAllocationCreateInfo allocationInfo = {
|
||||
.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,
|
||||
.requiredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
|
||||
};
|
||||
if (!foundMemory) return GN_FAILED_TO_ALLOCATE_MEMORY;
|
||||
|
||||
VkResult allocationRes = vkAllocateMemory(device->outputDevice->device, &allocInfo, NULL, &texture->texture->image.memory);
|
||||
if (allocationRes != VK_SUCCESS) return VkResultToGnReturnCode(allocationRes);
|
||||
vkBindImageMemory(device->outputDevice->device, texture->texture->image.image, texture->texture->image.memory, 0);
|
||||
VkResult imageCreateInfo = vmaCreateImage(device->outputDevice->allocator, &imageInfo, &allocationInfo, &texture->texture->image.image, &texture->texture->image.allocation, NULL);
|
||||
if (imageCreateInfo != VK_SUCCESS) return VkResultToGnReturnCode(imageCreateInfo);
|
||||
|
||||
texture->texture->beenWrittenToo = GN_FALSE;
|
||||
|
||||
VkImageViewCreateInfo viewInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
||||
.image = texture->texture->image.image,
|
||||
@@ -242,28 +221,37 @@ gnReturnCode createTexture(gnTexture texture, gnDevice device, const gnTextureIn
|
||||
}
|
||||
|
||||
void textureData(gnTextureHandle texture, void* pixelData) {
|
||||
void* data;
|
||||
vkMapMemory(texture->device->outputDevice->device, texture->texture->buffer.memory, 0, texture->texture->size, 0, &data);
|
||||
memcpy(data, pixelData, texture->texture->size);
|
||||
vkUnmapMemory(texture->device->outputDevice->device, texture->texture->buffer.memory);
|
||||
|
||||
//gnDevice device, VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout
|
||||
VkTransitionImageLayout(texture->device, texture->texture->image.image, texture->info.format, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
VkCopyBufferToImage(texture->texture->buffer, texture->texture->image, texture->info.extent, texture->device);
|
||||
VkTransitionImageLayout(texture->device, texture->texture->image.image, texture->info.format, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
|
||||
void* textureData;
|
||||
VkGryphnBuffer* stagingBuffer = &texture->device->outputDevice->stagingBuffer;
|
||||
VkDeviceSize sizeLeft = texture->texture->size, dataSize = texture->texture->size;
|
||||
while (sizeLeft > 0) {
|
||||
VkDeviceSize chunkSize = (texture->device->outputDevice->stagingBufferSize < sizeLeft) ? texture->device->outputDevice->stagingBufferSize : sizeLeft;
|
||||
vulkanMapBufferInternal(texture->device, *stagingBuffer, &textureData);
|
||||
memcpy(textureData, (char*)pixelData + (dataSize - sizeLeft), chunkSize);
|
||||
vulkanUnmapBufferInternal(texture->device, *stagingBuffer);
|
||||
|
||||
VkBufferCopy copyRegion = {
|
||||
.srcOffset = 0,
|
||||
.dstOffset = dataSize - sizeLeft,
|
||||
.size = chunkSize
|
||||
};
|
||||
sizeLeft -= chunkSize;
|
||||
|
||||
VkCopyBufferToImage(texture->device->outputDevice->stagingBuffer, texture->texture->image, texture->info.extent, texture->device);
|
||||
}
|
||||
|
||||
VkTransitionImageLayout(texture->device, texture->texture->image.image, texture->info.format, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
texture->texture->beenWrittenToo = GN_TRUE;
|
||||
}
|
||||
|
||||
void gnDestroyVulkanImage(VkGryphnImage* image, VkDevice device) {
|
||||
vkDestroyImage(device, image->image, NULL);
|
||||
vkDestroyImageView(device, image->imageView, NULL);
|
||||
vkFreeMemory(device, image->memory, NULL);
|
||||
void gnDestroyVulkanImage(VkGryphnImage* image, gnDevice device) {
|
||||
vmaDestroyImage(device->outputDevice->allocator, image->image, image->allocation);
|
||||
vkDestroyImageView(device->outputDevice->device, image->imageView, NULL);
|
||||
}
|
||||
|
||||
void destroyTexture(gnTexture texture) {
|
||||
vkDestroySampler(texture->device->outputDevice->device, texture->texture->sampler, NULL);
|
||||
|
||||
gnDestroyVulkanBuffer(&texture->texture->buffer, texture->device->outputDevice->device);
|
||||
gnDestroyVulkanImage(&texture->texture->image, texture->device->outputDevice->device);
|
||||
gnDestroyVulkanImage(&texture->texture->image, texture->device);
|
||||
}
|
||||
|
@@ -2,21 +2,22 @@
|
||||
#include <vulkan/vulkan.h>
|
||||
#include "textures/gryphn_texture.h"
|
||||
#include "buffers/vulkan_buffer.h"
|
||||
#include "memory_allocator/vk_mem_alloc.h"
|
||||
|
||||
typedef struct VkGryphnImage {
|
||||
VkImage image;
|
||||
VkDeviceMemory memory;
|
||||
VmaAllocation allocation;
|
||||
VkImageView imageView;
|
||||
} VkGryphnImage;
|
||||
void gnDestroyVulkanImage(VkGryphnImage* image, VkDevice device);
|
||||
void gnDestroyVulkanImage(VkGryphnImage* image, gnDevice device);
|
||||
|
||||
typedef struct gnPlatformTexture_t {
|
||||
VkGryphnBuffer buffer;
|
||||
VkGryphnImage image;
|
||||
VkSampler sampler;
|
||||
|
||||
size_t size;
|
||||
gnBool beenWrittenToo;
|
||||
|
||||
VkImageLayout currentLayout;
|
||||
} gnPlatformTexture;
|
||||
|
||||
gnReturnCode createTexture(gnTexture texture, gnDevice device, const gnTextureInfo info);
|
||||
|
Reference in New Issue
Block a user