Orange/src/Orange/Render/RenderContext_Util.cpp

172 lines
6.3 KiB
C++

#include <Orange/Render/RenderContext.h>
#include <vulkan/vulkan_core.h>
namespace orange
{
VulkanResult<VkFence> RenderContext::CreateFence(bool signalled)
{
VkFenceCreateInfo fenceInfo =
{
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
.flags = signalled ? VK_FENCE_CREATE_SIGNALED_BIT : 0u,
};
VkFence fence = VK_NULL_HANDLE;
VkResult res = VK_SUCCESS;
if ((res = vkCreateFence(m_device, &fenceInfo, nullptr, &fence)) != VK_SUCCESS)
return VulkanResult<VkFence>::Error(res);
return VulkanResult<VkFence>::Success(fence);
}
VulkanResult<VkSemaphore> RenderContext::CreateSemaphore()
{
VkSemaphoreCreateInfo semaphoreInfo =
{
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
};
VkSemaphore semaphore = VK_NULL_HANDLE;
VkResult res = VK_SUCCESS;
if ((res = vkCreateSemaphore(m_device, &semaphoreInfo, nullptr, &semaphore)) != VK_SUCCESS)
return VulkanResult<VkSemaphore>::Error(res);
return VulkanResult<VkSemaphore>::Success(semaphore);
}
VulkanResult<VoidResult> RenderContext::BeginCommandBuffer(VkCommandBuffer buffer)
{
VkCommandBufferBeginInfo beginInfo =
{
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
};
VkResult res = VK_SUCCESS;
if ((res = vkBeginCommandBuffer(buffer, &beginInfo)) != VK_SUCCESS)
return VulkanResult<VoidResult>::Error(res);
return VulkanResult<VoidResult>::Success();
}
VulkanResult<VoidResult> RenderContext::EndCommandBuffer(VkCommandBuffer buffer)
{
VkResult res = VK_SUCCESS;
if ((res = vkEndCommandBuffer(buffer)) != VK_SUCCESS)
return VulkanResult<VoidResult>::Error(res);
return VulkanResult<VoidResult>::Success();
}
VulkanResult<VkShaderModule> RenderContext::CreateShader(Span<const uint32_t> code)
{
VkShaderModuleCreateInfo shaderInfo =
{
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
.codeSize = code.size * sizeof(uint32_t),
.pCode = code.data,
};
VkResult res = VK_SUCCESS;
VkShaderModule module = VK_NULL_HANDLE;
if ((res = vkCreateShaderModule(m_device, &shaderInfo, nullptr, &module)) != VK_SUCCESS)
return VulkanResult<VkShaderModule>::Error(res);
return VulkanResult<VkShaderModule>::Success(module);
}
VulkanResult<GPUMemoryBuffer> RenderContext::CreateBuffer(VkDeviceSize size)
{
VkMemoryAllocateInfo memoryInfo =
{
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
.allocationSize = size,
.memoryTypeIndex = m_memoryTypes.gpuHostVisibleTypeIdx,
};
VkDeviceMemory memory = VK_NULL_HANDLE;
VkResult res = VK_SUCCESS;
if ((res = vkAllocateMemory(m_device, &memoryInfo, nullptr, &memory)) != VK_SUCCESS)
return VulkanResult<GPUMemoryBuffer>::Error(res);
void* data = nullptr;
if ((res = vkMapMemory(m_device, memory, 0, size, 0, &data)) != VK_SUCCESS)
return VulkanResult<GPUMemoryBuffer>::Error(res);
VkBufferCreateInfo bufferInfo =
{
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.size = size,
.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
VK_BUFFER_USAGE_TRANSFER_DST_BIT |
VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT |
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT |
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
};
VkBuffer buffer = VK_NULL_HANDLE;
if ((res = vkCreateBuffer(m_device, &bufferInfo, nullptr, &buffer)) != VK_SUCCESS)
return VulkanResult<GPUMemoryBuffer>::Error(res);
if ((res = vkBindBufferMemory(m_device, buffer, memory, 0)) != VK_SUCCESS)
return VulkanResult<GPUMemoryBuffer>::Error(res);
return VulkanResult<GPUMemoryBuffer>::Success(memory, buffer, size, data);
}
VulkanResult<VkImage> RenderContext::CreateImage(MemoryPool& pool, uint32_t width, uint32_t height, VkFormat format, VkImageUsageFlags usage)
{
VkImageCreateInfo imageInfo =
{
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
.imageType = VK_IMAGE_TYPE_2D,
.format = format,
.extent = VkExtent3D{ width, height, 1u },
.mipLevels = 1u,
.arrayLayers = 1u,
.samples = VK_SAMPLE_COUNT_1_BIT,
.tiling = VK_IMAGE_TILING_OPTIMAL,
.usage = usage,
};
VkImage image = VK_NULL_HANDLE;
VkResult res = VK_SUCCESS;
if ((res = vkCreateImage(m_device, &imageInfo, nullptr, &image)) != VK_SUCCESS)
return VulkanResult<VkImage>::Error(res);
VkMemoryRequirements imageMemRequirements;
vkGetImageMemoryRequirements(m_device, image, &imageMemRequirements);
auto imageSlice = *pool.AllocSlice(imageMemRequirements.size, imageMemRequirements.alignment);
if ((res = vkBindImageMemory(m_device, image, pool.Memory(), imageSlice.offset)) != VK_SUCCESS)
return VulkanResult<VkImage>::Error(res);
return VulkanResult<VkImage>::Success(image);
}
VulkanResult<VkImageView> RenderContext::CreateImageView(VkImage image, VkFormat format, VkImageAspectFlagBits aspect)
{
VkImageViewCreateInfo imageViewInfo =
{
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
.image = image,
.viewType = VK_IMAGE_VIEW_TYPE_2D,
.format = format,
.subresourceRange =
{
.aspectMask = aspect,
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = 1,
},
};
VkImageView imageView = VK_NULL_HANDLE;
VkResult res = VK_SUCCESS;
if ((res = vkCreateImageView(m_device, &imageViewInfo, nullptr, &imageView)) != VK_SUCCESS)
return VulkanResult<VkImageView>::Error(res);
return VulkanResult<VkImageView>::Success(imageView);
}
}