173 lines
6.3 KiB
C++
173 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 |
|
|
VK_BUFFER_USAGE_INDIRECT_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);
|
|
}
|
|
}
|