Program Listing for File resourcesCreater.cpp
↰ Return to documentation for file (PrismEngine/src/resourcesCreater.cpp)
#include "resourcesCreater.h"
#include "deviceWrapper.h"
void prism::PGC::L3::ResourcesCreater::createImage(utils::Context* context, uint32_t width, uint32_t height, uint32_t mipLevels, VkSampleCountFlagBits numSamples, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties, VkImage& image, VkDeviceMemory& imageMemory)
{
VkImageCreateInfo imageInfo{};
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
imageInfo.imageType = VK_IMAGE_TYPE_2D;
imageInfo.extent.width = width;
imageInfo.extent.height = height;
imageInfo.extent.depth = 1;
imageInfo.mipLevels = 1;
imageInfo.arrayLayers = 1;
imageInfo.format = format;
imageInfo.tiling = tiling;
imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
imageInfo.usage = usage;
imageInfo.samples = numSamples;
imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
imageInfo.mipLevels = mipLevels;
if (vkCreateImage(context->device, &imageInfo, nullptr, &image) != VK_SUCCESS) {
throw std::runtime_error("failed to create image!");
}
VkMemoryRequirements memRequirements;
vkGetImageMemoryRequirements(context->device, image, &memRequirements);
VkMemoryAllocateInfo allocInfo{};
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
allocInfo.allocationSize = memRequirements.size;
allocInfo.memoryTypeIndex = L3::DeviceWrapper::findMemoryType(context->physicalDevice, memRequirements.memoryTypeBits, properties);
if (vkAllocateMemory(context->device, &allocInfo, nullptr, &imageMemory) != VK_SUCCESS) {
throw std::runtime_error("failed to allocate image memory!");
}
vkBindImageMemory(context->device, image, imageMemory, 0);
}
VkImageView prism::PGC::L3::ResourcesCreater::createImageView(VkDevice device, VkImage image, VkFormat format, VkImageAspectFlags aspectFlags, uint32_t mipLevels)
{
VkImageViewCreateInfo viewInfo{};
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
viewInfo.image = image;
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
viewInfo.format = format;
viewInfo.subresourceRange.aspectMask = aspectFlags;
viewInfo.subresourceRange.baseMipLevel = 0;
viewInfo.subresourceRange.levelCount = 1;
viewInfo.subresourceRange.baseArrayLayer = 0;
viewInfo.subresourceRange.layerCount = 1;
viewInfo.subresourceRange.levelCount = mipLevels;
VkImageView imageView;
if (vkCreateImageView(device, &viewInfo, nullptr, &imageView) != VK_SUCCESS) {
throw std::runtime_error("failed to create image view!");
}
return imageView;
}
void prism::PGC::L3::ResourcesCreater::createFramebuffers(utils::Context* context, utils::Settings* settings)
{
context->swapChainFramebuffers.resize(context->swapChainImageViews.size());
for (size_t i = 0; i < context->swapChainImageViews.size(); i++) {
std::array<VkImageView, 3> attachments = {
context->colorImageView,
context->depthImageView,
context->swapChainImageViews[i]
};
VkFramebufferCreateInfo framebufferInfo{};
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
framebufferInfo.renderPass = context->renderPass;
framebufferInfo.attachmentCount = static_cast<uint32_t>(attachments.size());
framebufferInfo.pAttachments = attachments.data();
framebufferInfo.width = context->swapChainExtent.width;
framebufferInfo.height = context->swapChainExtent.height;
framebufferInfo.layers = 1;
if (vkCreateFramebuffer(context->device, &framebufferInfo, nullptr, &context->swapChainFramebuffers[i]) != VK_SUCCESS) {
throw std::runtime_error("failed to create framebuffer!");
}
}
}
void prism::PGC::L3::ResourcesCreater::createColorResources(utils::Context* context, utils::Settings* settings)
{
VkFormat colorFormat = context->swapChainImageFormat;
createImage(context, context->swapChainExtent.width, context->swapChainExtent.height, 1, context->msaaSamples, colorFormat, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, context->colorImage, context->colorImageMemory);
context->colorImageView = createImageView(context->device ,context->colorImage, colorFormat, VK_IMAGE_ASPECT_COLOR_BIT, 1);
}
void prism::PGC::L3::ResourcesCreater::createDepthResources(utils::Context* context, utils::Settings* settings)
{
VkFormat depthFormat = PGC::L3::DeviceWrapper::findDepthFormat(context->physicalDevice);
PGC::L3::ResourcesCreater::createImage(context, context->swapChainExtent.width, context->swapChainExtent.height, 1, context->msaaSamples, depthFormat, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, context->depthImage, context->depthImageMemory);
context->depthImageView = PGC::L3::ResourcesCreater::createImageView(context->device, context->depthImage, depthFormat, VK_IMAGE_ASPECT_DEPTH_BIT, 1);
}
void prism::PGC::L3::ResourcesCreater::createTextureSampler(utils::Context * context, VkSampler * textureSampler)
{
VkPhysicalDeviceProperties properties{};
vkGetPhysicalDeviceProperties(context->physicalDevice, &properties);
VkSamplerCreateInfo samplerInfo{};
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
samplerInfo.magFilter = VK_FILTER_LINEAR;
samplerInfo.minFilter = VK_FILTER_LINEAR;
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
samplerInfo.anisotropyEnable = VK_TRUE;
samplerInfo.maxAnisotropy = properties.limits.maxSamplerAnisotropy;
samplerInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
samplerInfo.unnormalizedCoordinates = VK_FALSE;
samplerInfo.compareEnable = VK_FALSE;
samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS;
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
samplerInfo.minLod = 0.0f; // Необязательно
samplerInfo.maxLod = VK_LOD_CLAMP_NONE;
samplerInfo.mipLodBias = 0.0f; // Необязательно
if (vkCreateSampler(context->device, &samplerInfo, nullptr, textureSampler) != VK_SUCCESS) {
throw std::runtime_error("failed to create texture sampler!");
}
}
void prism::PGC::L3::ResourcesCreater::createCommandPool(utils::Context* context)
{
PGC::utils::QueueFamilyIndices queueFamilyIndices = PGC::L3::DeviceWrapper::findQueueFamilies(context->physicalDevice, context->surface);
VkCommandPoolCreateInfo poolInfo{};
poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
poolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
poolInfo.queueFamilyIndex = queueFamilyIndices.graphicsFamily.value();
if (vkCreateCommandPool(context->device, &poolInfo, nullptr, &context->commandPool) != VK_SUCCESS) {
throw std::runtime_error("failed to create command pool!");
}
}