/* * Copyright 2022-2024 Frederico de Oliveira Linhares * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "image.hpp" #include "core.hpp" namespace BluCat::Image { Error::Error(const std::string &m): error(m) { } Error::Error(const char &m): Error{std::string{m}} { } const char* Error::what() const noexcept { return this->error.c_str(); } void create( BluCat::Device *device, VkImage *image, VkDeviceMemory *image_memory, VkFormat format, const VkExtent3D &extent3d, uint32_t mip_levels, VkImageTiling image_tiling, VkImageUsageFlags usage) { VkImageCreateInfo image_info{}; image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; image_info.pNext = nullptr; image_info.flags = 0; image_info.imageType = VK_IMAGE_TYPE_2D; image_info.format = format; image_info.extent = extent3d; image_info.mipLevels = mip_levels; image_info.arrayLayers = 1; image_info.samples = VK_SAMPLE_COUNT_1_BIT; image_info.tiling = image_tiling; image_info.usage = usage; image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; image_info.queueFamilyIndexCount = 0; image_info.pQueueFamilyIndices = nullptr; image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; if(vkCreateImage( device->device, &image_info, nullptr, image) != VK_SUCCESS) throw Error{"Failed to create Vulkan image."}; VkMemoryRequirements memory_requirements; vkGetImageMemoryRequirements(device->device, *image, &memory_requirements); VkMemoryAllocateInfo memory_alloc_info{}; memory_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; memory_alloc_info.allocationSize = memory_requirements.size; device->select_memory_type(&memory_alloc_info.memoryTypeIndex, &memory_requirements, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); if(vkAllocateMemory( device->device, &memory_alloc_info, nullptr, image_memory) != VK_SUCCESS) { vkDestroyImage(device->device, *image, nullptr); throw Error{"Failed to allocate memory for Vulkan image."}; } vkBindImageMemory(device->device, *image, *image_memory, 0); } void move_image_state( VkCommandBuffer vk_command_buffer, VkImage vk_image, VkFormat format, VkAccessFlags src_access_mask, VkAccessFlags dst_access_mask, VkImageLayout old_layout, VkImageLayout new_layout, VkPipelineStageFlags source_stage, VkPipelineStageFlags destination_stage) { VkImageMemoryBarrier barrier{}; barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; barrier.pNext = nullptr; barrier.srcAccessMask = src_access_mask; barrier.dstAccessMask = dst_access_mask; barrier.oldLayout = old_layout; barrier.newLayout = new_layout; barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; barrier.image = vk_image; barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; barrier.subresourceRange.baseMipLevel = 0; barrier.subresourceRange.levelCount = 1; barrier.subresourceRange.baseArrayLayer = 0; barrier.subresourceRange.layerCount = 1; vkCmdPipelineBarrier( vk_command_buffer, source_stage, destination_stage, 0, 0, nullptr, 0, nullptr, 1, &barrier); } void create_view( BluCat::Device *device, VkImageView *image_view, const VkImage &image, VkFormat format, VkImageAspectFlags image_aspect_flags) { VkImageViewCreateInfo image_view_info{}; image_view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; image_view_info.pNext = nullptr; image_view_info.flags = 0; image_view_info.image = image; image_view_info.viewType = VK_IMAGE_VIEW_TYPE_2D; image_view_info.format = format; image_view_info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; image_view_info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; image_view_info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; image_view_info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; image_view_info.subresourceRange.aspectMask = image_aspect_flags; image_view_info.subresourceRange.baseMipLevel = 0; image_view_info.subresourceRange.levelCount = 1; image_view_info.subresourceRange.baseArrayLayer = 0; image_view_info.subresourceRange.layerCount = 1; if(vkCreateImageView(device->device, &image_view_info, nullptr, image_view) != VK_SUCCESS) throw Error{"Failed to create texture view."}; } }