summaryrefslogtreecommitdiff
path: root/src/blucat/image.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/blucat/image.cpp')
-rw-r--r--src/blucat/image.cpp149
1 files changed, 149 insertions, 0 deletions
diff --git a/src/blucat/image.cpp b/src/blucat/image.cpp
new file mode 100644
index 0000000..7f8633f
--- /dev/null
+++ b/src/blucat/image.cpp
@@ -0,0 +1,149 @@
+/*
+ * 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."};
+
+}
+
+}