diff options
Diffstat (limited to 'src/vk')
81 files changed, 0 insertions, 9037 deletions
diff --git a/src/vk/animation.cpp b/src/vk/animation.cpp deleted file mode 100644 index fec038e..0000000 --- a/src/vk/animation.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2022-2023 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 "animation.hpp" - -namespace VK -{ - -Bone::Bone(glm::mat4 offset_matrix): - offset_matrix{offset_matrix} -{ -} - -} diff --git a/src/vk/animation.hpp b/src/vk/animation.hpp deleted file mode 100644 index 46dd5bc..0000000 --- a/src/vk/animation.hpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2022-2023 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. - */ - -#ifndef CANDY_GEAR_VK_ANIMATION_H -#define CANDY_GEAR_VK_ANIMATION_H 1 - -#include <vector> - -#include "core.hpp" -#include "animation/frame.hpp" - -namespace VK -{ - -struct Bone -{ - glm::mat4x4 offset_matrix; - - Bone(glm::mat4 offset_matrix); -}; - -struct BoneTransform -{ - uint32_t bone_id; - Channel<glm::vec3> positions; - Channel<glm::quat> rotations; - Channel<glm::vec3> scales; -}; - -struct Animation -{ - std::vector<BoneTransform> bone_transforms; - float final_time; -}; - -} - -#endif /* CANDY_GEAR_VK_ANIMATION_H */ diff --git a/src/vk/animation/frame.hpp b/src/vk/animation/frame.hpp deleted file mode 100644 index 953a6a6..0000000 --- a/src/vk/animation/frame.hpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2022-2023 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. - */ - -#ifndef CANDY_GEAR_VK_FRAME_H -#define CANDY_GEAR_VK_FRAME_H 1 - -#include <vector> - -#include "../core.hpp" - -namespace VK -{ - -template<typename T> -struct Frame -{ - const T value; - const float timestamp; - - Frame(T value, float timestamp): - value{value}, - timestamp{timestamp} - { - } - -}; - -template<typename T> -struct Channel -{ - int current_index{0}; - std::vector<Frame<T>> key_frames; - - inline glm::mat4 - interpolate( - float animation_time, - glm::mat4 (*single_frame)(T frame), - glm::mat4 (*multiple_frames)(T current_frame, T next_frame, float scale)) - { - if(this->key_frames.size() == 1) - return single_frame(this->key_frames[0].value); - else - { - while(animation_time > this->key_frames[current_index].timestamp) - this->current_index++; - - float scale_factor; - Frame<T> *previous_frame; - Frame<T> *next_frame{&(this->key_frames[this->current_index])}; - if(this->current_index == 0) - { - previous_frame = &(this->key_frames[this->key_frames.size() - 1]); - float midway_length{animation_time - 0}; - float frames_diff{next_frame->timestamp - 0}; - scale_factor = midway_length / frames_diff; - } - else - { - previous_frame = &(this->key_frames[this->current_index - 1]); - float midway_length{animation_time - previous_frame->timestamp}; - float frames_diff{next_frame->timestamp - previous_frame->timestamp}; - scale_factor = midway_length / frames_diff; - } - - return multiple_frames( - previous_frame->value, next_frame->value, scale_factor); - } - }; -}; - -} -#endif /* CANDY_GEAR_VK_FRAME_H */ diff --git a/src/vk/base_buffer.cpp b/src/vk/base_buffer.cpp deleted file mode 100644 index 0846b20..0000000 --- a/src/vk/base_buffer.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2022 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 "base_buffer.hpp" - -namespace VK -{ - -const CommandChain BaseBuffer::loader{ - {&BaseBuffer::load_buffer, &BaseBuffer::unload_buffer}, - {&BaseBuffer::load_memory, &BaseBuffer::unload_memory} -}; - -void -BaseBuffer::load_buffer(void *obj) -{ - auto self = static_cast<BaseBuffer*>(obj); - - VkBufferCreateInfo buffer_info = {}; - buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; - buffer_info.pNext = nullptr; - buffer_info.flags = 0; - buffer_info.size = self->device_size; - buffer_info.usage = self->buffer_usage; - buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - buffer_info.queueFamilyIndexCount = 0; - buffer_info.pQueueFamilyIndices = nullptr; - - if(vkCreateBuffer( - self->device->device, &buffer_info, nullptr, &self->buffer) - != VK_SUCCESS) - throw CommandError{"Failed to create vertex buffer."}; -} - -void -BaseBuffer::unload_buffer(void *obj) -{ - auto self = static_cast<BaseBuffer*>(obj); - - if(self->buffer != VK_NULL_HANDLE) - vkDestroyBuffer(self->device->device, self->buffer, nullptr); -} - -void -BaseBuffer::load_memory(void *obj) -{ - auto self = static_cast<BaseBuffer*>(obj); - - VkMemoryRequirements memory_requirements; - vkGetBufferMemoryRequirements( - self->device->device, self->buffer, &memory_requirements); - - VkPhysicalDeviceMemoryProperties memory_properties; - vkGetPhysicalDeviceMemoryProperties( - self->device->physical_device, &memory_properties); - - VkMemoryAllocateInfo alloc_info = {}; - alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - alloc_info.pNext = nullptr; - alloc_info.allocationSize = memory_requirements.size; - if(!self->device->select_memory_type( - &alloc_info.memoryTypeIndex, &memory_requirements, - self->memory_properties)) - throw CommandError{"Could not allocate memory for Vulkan vertex buffer."}; - - if(vkAllocateMemory(self->device->device, &alloc_info, nullptr, - &self->device_memory) != VK_SUCCESS) - throw CommandError{"Could not allocate memory for Vulkan vertex buffer."}; - - vkBindBufferMemory( - self->device->device, self->buffer, self->device_memory, 0); -} - -void -BaseBuffer::unload_memory(void *obj) -{ - auto self = static_cast<BaseBuffer*>(obj); - - if(self->device_memory != VK_NULL_HANDLE) - vkFreeMemory(self->device->device, self->device_memory, nullptr); -} - -} diff --git a/src/vk/base_buffer.hpp b/src/vk/base_buffer.hpp deleted file mode 100644 index 0f3e513..0000000 --- a/src/vk/base_buffer.hpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2022 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. - */ - -#ifndef CANDY_GEAR_VK_BASE_BUFFER_H -#define CANDY_GEAR_VK_BASE_BUFFER_H 1 - -#include "../command.hpp" -#include "core.hpp" -#include "device.hpp" - -namespace VK -{ - -class BaseBuffer -{ - public: - virtual ~BaseBuffer(){}; - - VkBuffer buffer; - VkDeviceMemory device_memory; - VkDeviceSize device_size; - VkBufferUsageFlags buffer_usage; - VkMemoryPropertyFlags memory_properties; - - protected: - static const CommandChain loader; - - Device *device; - - static void - load_buffer(void *obj); - static void - unload_buffer(void *obj); - - static void - load_memory(void *obj); - static void - unload_memory(void *obj); -}; - -} - -#endif /* CANDY_GEAR_VK_BASE_BUFFER_H */ diff --git a/src/vk/character.cpp b/src/vk/character.cpp deleted file mode 100644 index e5eb87f..0000000 --- a/src/vk/character.cpp +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Copyright 2022-2023 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 "character.hpp" - -#include "../command.hpp" -#include "../core.hpp" -#include "font.hpp" -#include "image.hpp" -#include "source_buffer.hpp" - -namespace -{ - -struct CharacterBuilder -{ - VK::Character *character; - FT_Face face; - uint32_t character_code; - - CharacterBuilder( - VK::Character *character, FT_Face face, uint32_t character_code); -}; - -CharacterBuilder::CharacterBuilder( - VK::Character *character, FT_Face face, uint32_t character_code): - character{character}, - face{face}, - character_code{character_code} -{ -} - -// TODO: creating one image with one device memory for each character is -// ineficient -void -load_image(void *obj) -{ - auto self = static_cast<CharacterBuilder*>(obj); - - FT_Error error; - std::vector<uint8_t> source_image_raw; - const int num_channels = 4; // all images are converted to RGBA - auto glyph_index{FT_Get_Char_Index(self->face, self->character_code)}; - - error = FT_Load_Glyph(self->face, glyph_index, FT_LOAD_DEFAULT); - if(error) throw CommandError{"failed to load glyph"}; - - error = FT_Render_Glyph(self->face->glyph, FT_RENDER_MODE_NORMAL); - if(error) throw CommandError{"failed to render glyph"}; - - self->character->bearing_x = self->face->glyph->bitmap_left; - self->character->bearing_y = self->face->glyph->bitmap_top; - self->character->advance = (self->face->glyph->advance.x >> 6); - self->character->width = self->face->glyph->bitmap.width; - self->character->height = self->face->glyph->bitmap.rows; - self->character->mip_levels = 1; - - // Character is a white-space. - if(self->character->width <= 0) - { - self->character->image = VK_NULL_HANDLE; - self->character->device_memory = VK_NULL_HANDLE; - - return; - } - - auto image_size{static_cast<size_t>( - self->face->glyph->bitmap.width * - self->face->glyph->bitmap.rows * num_channels)}; - - { // Create the data for the image buffer - source_image_raw.resize(image_size, 0); - - for(auto y{0}; y < self->face->glyph->bitmap.width; y++) - { - for(auto x{0}; x < self->face->glyph->bitmap.rows; x++) - { - auto image_coord = y * self->face->glyph->bitmap.rows * num_channels + - x * num_channels; - auto glyph_coord = y * self->face->glyph->bitmap.rows + x; - // Red - source_image_raw[image_coord] = 255; - // Green - source_image_raw[image_coord + 1] = 255; - // Blue - source_image_raw[image_coord + 2] = 255; - // Alpha - source_image_raw[image_coord + 3] = - self->face->glyph->bitmap.buffer[glyph_coord]; - } - } - } - - VK::SourceBuffer source_image_buffer{ - cg_core.vk_device_with_swapchain, source_image_raw.data(), - image_size}; - - { // Create Vulkan image. - try - { - VkExtent3D vk_extent3d; - vk_extent3d.width = self->face->glyph->bitmap.width; - vk_extent3d.height = self->face->glyph->bitmap.rows; - vk_extent3d.depth = 1; - - VK::Image::create( - cg_core.vk_device_with_swapchain, - &self->character->image, - &self->character->device_memory, - VK_FORMAT_R8G8B8A8_UNORM, - vk_extent3d, - self->character->mip_levels, - VK_IMAGE_TILING_OPTIMAL, - VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); - } - catch(VK::Image::Error error) - { - throw CommandError{error.what()}; - } - } - - { // Copy image from buffer into image. - auto queue_family{cg_core.vk_device_with_swapchain-> - get_queue_family_with_presentation()}; - auto queue{queue_family->get_queue()}; - VK::CommandPool command_pool{queue_family, 1}; - VkCommandBuffer vk_command_buffer{command_pool.command_buffers[0]}; - - queue.submit_one_time_command(vk_command_buffer, [&](){ - VK::Image::move_image_state( - vk_command_buffer, self->character->image, VK_FORMAT_R8G8B8A8_UNORM, - 0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_HOST_BIT, - VK_PIPELINE_STAGE_TRANSFER_BIT); - - VkBufferImageCopy image_copy; - image_copy.bufferOffset = 0; - image_copy.bufferRowLength = 0; - image_copy.bufferImageHeight = 0; - image_copy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - image_copy.imageSubresource.mipLevel = 0; - image_copy.imageSubresource.baseArrayLayer = 0; - image_copy.imageSubresource.layerCount = 1; - image_copy.imageOffset = {0, 0, 0}; - image_copy.imageExtent = { - self->character->width, self->character->height, 1}; - - vkCmdCopyBufferToImage( - vk_command_buffer, source_image_buffer.buffer, self->character->image, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &image_copy); - - VK::Image::move_image_state( - vk_command_buffer, self->character->image, VK_FORMAT_R8G8B8A8_UNORM, - VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); - }); - } -} - -void -unload_image(void *obj) -{ - auto self = static_cast<CharacterBuilder*>(obj); - - vkDestroyImage( - cg_core.vk_device_with_swapchain->device, self->character->image, nullptr); - vkFreeMemory( - cg_core.vk_device_with_swapchain->device, self->character->device_memory, - nullptr); -} - -const CommandChain loader{ - {&load_image, &unload_image} -}; - -} - -namespace VK -{ - -Character::Character(FT_Face face, uint32_t character_code) -{ - CharacterBuilder character_builder(this, face, character_code); - loader.execute(&character_builder); -} - -Character::~Character() -{ - CharacterBuilder character_builder(this, nullptr, 0); - loader.revert(&character_builder); -} - -std::vector<uint32_t> -Character::str_to_unicode(const char* str) -{ - std::vector<uint32_t> unicode_text; - int text_width{0}; - int text_height{0}; - - { // Reserve memory - int size{0}; - for(auto i{0}; str[i] != '\0'; i++) - if((str[i] & 0b11000000) != 0b10000000) size++; - unicode_text.reserve(size); - } - - for(auto i{0}; str[i] != '\0'; i++) - { - int num_bytes; - uint32_t codepoint{0}; - - if(str[i] >= 0 && str[i] < 127) - { // Normal ASCI character, 1-byte. - num_bytes = 1; - codepoint = str[i]; - } - else if((str[i] & 0xE0) == 0xC0) - { // 2-byte character. - num_bytes = 2; - codepoint += ((str[i] & 0b00011111) << 6); - } - else if((str[i] & 0xF0) == 0xE0) - { // 3-byte character. - num_bytes = 3; - codepoint += ((str[i] & 0b00001111) << 12); - } - else if((str[i] & 0xF8) == 0xF0) - { // 4-byte character. - num_bytes = 4; - codepoint += ((str[i] & 0b00000111) << 18); - } - else - { // FIXME: Add support to 5-byte and 6-byte characters. - } - - switch (num_bytes) - { - case 4: - i++; - codepoint += ((str[i] & 0b00111111) << 12); - case 3: - i++; - codepoint += ((str[i] & 0b00111111) << 6); - case 2: - i++; - codepoint += (str[i] & 0b00111111); - case 1: - default: - break; - } - - unicode_text.push_back(codepoint); - } - - return unicode_text; -} - -} diff --git a/src/vk/character.hpp b/src/vk/character.hpp deleted file mode 100644 index 82ada49..0000000 --- a/src/vk/character.hpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2022-2023 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. - */ - -#ifndef CANDY_GEAR_VK_CHARACTER_H -#define CANDY_GEAR_VK_CHARACTER_H 1 - -#include <ft2build.h> -#include FT_FREETYPE_H - -#include "core.hpp" - -#include <vector> - -namespace VK -{ - -struct Character -{ - VkImage image; - VkDeviceMemory device_memory; - int32_t bearing_y, bearing_x; - uint32_t width, height, advance, mip_levels; - - Character(FT_Face face, uint32_t character_code); - ~Character(); - - Character(Character const&) = delete; - Character& operator=(Character const&) = delete; - - static std::vector<uint32_t> - str_to_unicode(const char* str); -}; - -} - -#endif /* CANDY_GEAR_VK_CHARACTER_H */ diff --git a/src/vk/command_pool.cpp b/src/vk/command_pool.cpp deleted file mode 100644 index 3af62c1..0000000 --- a/src/vk/command_pool.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2022 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 "command_pool.hpp" - -namespace VK -{ - -const CommandChain CommandPool::loader{ - {&CommandPool::load_command_pool, &CommandPool::unload_command_pool}, - {&CommandPool::load_command_buffers, nullptr} -}; - -CommandPool::CommandPool(QueueFamily *queue_family, uint32_t buffers_quantity): - queue_family{queue_family} -{ - this->command_buffers.resize(buffers_quantity); - - CommandPool::loader.execute(this); -} - -CommandPool::~CommandPool() -{ - CommandPool::loader.revert(this); -} - -void -CommandPool::load_command_pool(void *obj) -{ - auto *self = static_cast<CommandPool*>(obj); - - VkCommandPoolCreateInfo command_pool_create_info; - - command_pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; - command_pool_create_info.pNext = nullptr; - command_pool_create_info.flags = - VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; - command_pool_create_info.queueFamilyIndex = self->queue_family->family_index; - - if(vkCreateCommandPool( - self->queue_family->device->device, &command_pool_create_info, - nullptr, &self->command_pool) != VK_SUCCESS) - throw CommandError{"Vulkan command pool could not be created."}; -} - -void -CommandPool::unload_command_pool(void *obj) -{ - auto *self = static_cast<CommandPool*>(obj); - - vkDestroyCommandPool( - self->queue_family->device->device, self->command_pool, nullptr); -} - -void -CommandPool::load_command_buffers(void *obj) -{ - auto *self = static_cast<CommandPool*>(obj); - - VkCommandBufferAllocateInfo command_buffer_info; - command_buffer_info.sType = - VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; - command_buffer_info.pNext = nullptr; - command_buffer_info.commandPool = self->command_pool; - command_buffer_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; - command_buffer_info.commandBufferCount = self->command_buffers.size(); - - if(vkAllocateCommandBuffers( - self->queue_family->device->device, - &command_buffer_info, self->command_buffers.data()) != VK_SUCCESS) - throw CommandError{"Vulkan command buffers could not be allocated."}; -} - -} diff --git a/src/vk/command_pool.hpp b/src/vk/command_pool.hpp deleted file mode 100644 index 68ab7a6..0000000 --- a/src/vk/command_pool.hpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2022 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. - */ - -#ifndef CANDY_GEAR_VK_COMMAND_POOL_H -#define CANDY_GEAR_VK_COMMAND_POOL_H 1 - -#include <vector> - -#include "../command.hpp" -#include "core.hpp" -#include "device.hpp" - -namespace VK -{ - -class CommandPool -{ - CommandPool(const CommandPool &t) = delete; - CommandPool& operator=(const CommandPool &t) = delete; - CommandPool(const CommandPool &&t) = delete; - CommandPool& operator=(const CommandPool &&t) = delete; - -public: - std::vector<VkCommandBuffer> command_buffers; - - CommandPool(QueueFamily *queue_family, uint32_t buffers_quantity); - ~CommandPool(); - -private: - static const CommandChain loader; - - QueueFamily *queue_family; - VkCommandPool command_pool; - - static void - load_command_pool(void *obj); - static void - unload_command_pool(void *obj); - - static void - load_command_buffers(void *obj); -}; - -} - -#endif /* CANDY_GEAR_VK_COMMAND_POOL_H */ diff --git a/src/vk/core.hpp b/src/vk/core.hpp deleted file mode 100644 index 736b8bb..0000000 --- a/src/vk/core.hpp +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2022-2023 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. - */ - -#ifndef CANDY_GEAR_VK_CORE_H -#define CANDY_GEAR_VK_CORE_H 1 - -// GLM uses some definitions to control their behavior, so you should not -// include it directly. Instead, use this header. -#define GLM_ENABLE_EXPERIMENTAL -#define GLM_FORCE_RADIANS -#define GLM_FORCE_DEPTH_ZERO_TO_ONE - -#include <glm/ext/vector_float3.hpp> -#include <glm/ext.hpp> -#include <glm/gtc/matrix_transform.hpp> -#include <glm/gtx/quaternion.hpp> -#include <glm/vec3.hpp> - -#include <vulkan/vulkan.h> - -#endif /* CANDY_GEAR_VK_CORE_H */ diff --git a/src/vk/descriptor_set_layout.cpp b/src/vk/descriptor_set_layout.cpp deleted file mode 100644 index 8a2f4ef..0000000 --- a/src/vk/descriptor_set_layout.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright 2022-2023 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 "descriptor_set_layout.hpp" - -#include <array> - -#include "../core.hpp" - -namespace -{ - -void -load_world(void *obj) -{ - auto self = static_cast<VK::DescriptorSetLayout*>(obj); - - std::array<VkDescriptorSetLayoutBinding, 2> set_layouts{}; - set_layouts[0].binding = 0; - set_layouts[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - set_layouts[0].descriptorCount = 1; - set_layouts[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; - set_layouts[0].pImmutableSamplers = nullptr; - - set_layouts[1].binding = 1; - set_layouts[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - set_layouts[1].descriptorCount = 1; - set_layouts[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; - set_layouts[1].pImmutableSamplers = nullptr; - - VkDescriptorSetLayoutCreateInfo layout_info{}; - layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - layout_info.pNext = nullptr; - layout_info.flags = 0; - layout_info.bindingCount = set_layouts.size(); - layout_info.pBindings = set_layouts.data(); - - if(vkCreateDescriptorSetLayout( - cg_core.vk_device_with_swapchain->device, &layout_info, nullptr, - &self->world) != VK_SUCCESS) - throw CommandError{ - "Failed to create Vulkan descriptor set layout for world view."}; -} - -void -unload_world(void *obj) -{ - auto self = static_cast<VK::DescriptorSetLayout*>(obj); - - vkDestroyDescriptorSetLayout( - cg_core.vk_device_with_swapchain->device, self->world, nullptr); -} - -void -load_view(void *obj) -{ - auto self = static_cast<VK::DescriptorSetLayout*>(obj); - - std::array<VkDescriptorSetLayoutBinding, 1> layout_bindings{}; - - layout_bindings[0].binding = 0; - layout_bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - layout_bindings[0].descriptorCount = 1; - layout_bindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; - layout_bindings[0].pImmutableSamplers = nullptr; - - VkDescriptorSetLayoutCreateInfo layout_info{}; - layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - layout_info.pNext = nullptr; - layout_info.flags = 0; - layout_info.bindingCount = static_cast<uint32_t>(layout_bindings.size()); - layout_info.pBindings = layout_bindings.data(); - - if(vkCreateDescriptorSetLayout( - cg_core.vk_device_with_swapchain->device, &layout_info, nullptr, - &self->view) != VK_SUCCESS) - throw CommandError{ - "Failed to create Vulkan descriptor set layout for view."}; -} - -void -unload_view(void *obj) -{ - auto self = static_cast<VK::DescriptorSetLayout*>(obj); - - vkDestroyDescriptorSetLayout( - cg_core.vk_device_with_swapchain->device, self->view, nullptr); -} - -void -load_texture(void *obj) -{ - auto self = static_cast<VK::DescriptorSetLayout*>(obj); - - std::array<VkDescriptorSetLayoutBinding, 1> layout_bindings{}; - - layout_bindings[0].binding = 0; - layout_bindings[0].descriptorType = - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - layout_bindings[0].descriptorCount = 1; - layout_bindings[0].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; - layout_bindings[0].pImmutableSamplers = nullptr; - - VkDescriptorSetLayoutCreateInfo layout_info{}; - layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - layout_info.pNext = nullptr; - layout_info.flags = 0; - layout_info.bindingCount = static_cast<uint32_t>(layout_bindings.size()); - layout_info.pBindings = layout_bindings.data(); - - if(vkCreateDescriptorSetLayout( - cg_core.vk_device_with_swapchain->device, &layout_info, nullptr, - &self->texture) != VK_SUCCESS) - throw CommandError{ - "Failed to create Vulkan descriptor set layout for textures."}; -} - -void -unload_texture(void *obj) -{ - auto self = static_cast<VK::DescriptorSetLayout*>(obj); - - vkDestroyDescriptorSetLayout( - cg_core.vk_device_with_swapchain->device, self->texture, nullptr); -} - -void -load_model(void *obj) -{ - auto self = static_cast<VK::DescriptorSetLayout*>(obj); - - std::array<VkDescriptorSetLayoutBinding, 1> layout_bindings; - layout_bindings[0].binding = 0; - layout_bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - layout_bindings[0].descriptorCount = 1; - layout_bindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; - layout_bindings[0].pImmutableSamplers = nullptr; - - VkDescriptorSetLayoutCreateInfo layout_info{}; - layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - layout_info.pNext = nullptr; - layout_info.flags = 0; - layout_info.bindingCount = static_cast<uint32_t>(layout_bindings.size()); - layout_info.pBindings = layout_bindings.data(); - - if(vkCreateDescriptorSetLayout( - cg_core.vk_device_with_swapchain->device, &layout_info, nullptr, - &self->model) != VK_SUCCESS) - throw CommandError{ - "Failed to create Vulkan descriptor set layout for model instance."}; -} - -void -unload_model(void *obj) -{ - auto self = static_cast<VK::DescriptorSetLayout*>(obj); - - vkDestroyDescriptorSetLayout( - cg_core.vk_device_with_swapchain->device, self->model, nullptr); -} - -const CommandChain loader{ - {&load_world, &unload_world}, - {&load_view, &unload_view}, - {&load_texture, &unload_texture}, - {&load_model, &unload_model}, -}; - -} - -namespace VK -{ - -DescriptorSetLayout::DescriptorSetLayout() -{ - loader.execute(this); -} - -DescriptorSetLayout::~DescriptorSetLayout() -{ - loader.revert(this); -} - -} diff --git a/src/vk/descriptor_set_layout.hpp b/src/vk/descriptor_set_layout.hpp deleted file mode 100644 index 242d2fa..0000000 --- a/src/vk/descriptor_set_layout.hpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2022-2023 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. - */ - -#ifndef CANDY_GEAR_VK_DESCRIPTOR_SET_LAYOUT_H -#define CANDY_GEAR_VK_DESCRIPTOR_SET_LAYOUT_H 1 - -#include "core.hpp" - -namespace VK -{ - -struct DescriptorSetLayout -{ - VkDescriptorSetLayout world; - VkDescriptorSetLayout view; - VkDescriptorSetLayout texture; - VkDescriptorSetLayout model; - - DescriptorSetLayout(); - ~DescriptorSetLayout(); -}; - -} - -#endif /* CANDY_GEAR_VK_DESCRIPTOR_SET_LAYOUT_H */ diff --git a/src/vk/destination_buffer.cpp b/src/vk/destination_buffer.cpp deleted file mode 100644 index 5c55fd2..0000000 --- a/src/vk/destination_buffer.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2022 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 "destination_buffer.hpp" - -#include "command_pool.hpp" - -namespace VK -{ - -DestinationBuffer::DestinationBuffer( - QueueFamily *queue_family, SourceBuffer *source_buffer, - VkBufferUsageFlags buffer_usage) -{ - this->device = queue_family->device; - this->device_size = source_buffer->device_size; - this->buffer_usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | buffer_usage; - this->memory_properties = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; - this->queue_family = queue_family; - this->source_buffer = source_buffer; - - BaseBuffer::loader.execute(dynamic_cast<BaseBuffer*>(this)); - - this->copy_data(); -} - -DestinationBuffer::DestinationBuffer( - DestinationBuffer &&that) -{ - this->buffer = that.buffer; - this->device_memory = that.device_memory; - this->device_size = that.device_size; - this->buffer_usage = that.buffer_usage; - this->memory_properties = that.memory_properties; - - that.buffer = VK_NULL_HANDLE; - that.device_memory = VK_NULL_HANDLE; -} - -DestinationBuffer& -DestinationBuffer::operator=(DestinationBuffer &&that) -{ - this->buffer = that.buffer; - this->device_memory = that.device_memory; - this->device_size = that.device_size; - this->buffer_usage = that.buffer_usage; - this->memory_properties = that.memory_properties; - - that.buffer = VK_NULL_HANDLE; - that.device_memory = VK_NULL_HANDLE; - - return *this; -} - -DestinationBuffer::~DestinationBuffer() -{ - BaseBuffer::loader.revert(dynamic_cast<BaseBuffer*>(this)); -} - -void -DestinationBuffer::copy_data() -{ - CommandPool command_pool(this->queue_family, 1); - Queue transfer_queue{this->queue_family->get_queue()}; - this->device_size = source_buffer->device_size; - - this->vk_command_buffer = command_pool.command_buffers[0]; - - VkCommandBufferBeginInfo begin_info = {}; - begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - - VkBufferCopy copy_region = {}; - copy_region.srcOffset = 0; - copy_region.dstOffset = 0; - copy_region.size = this->device_size; - - vkBeginCommandBuffer(this->vk_command_buffer, &begin_info); - - vkCmdCopyBuffer( - this->vk_command_buffer, this->source_buffer->buffer, this->buffer, 1, - ©_region); - - vkEndCommandBuffer(this->vk_command_buffer); - - VkSubmitInfo submit_info = {}; - submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submit_info.commandBufferCount = 1; - submit_info.pCommandBuffers = &this->vk_command_buffer; - - vkQueueSubmit(transfer_queue.queue, 1, &submit_info, VK_NULL_HANDLE); - - vkQueueWaitIdle(transfer_queue.queue); -} - -} diff --git a/src/vk/destination_buffer.hpp b/src/vk/destination_buffer.hpp deleted file mode 100644 index 9b42af3..0000000 --- a/src/vk/destination_buffer.hpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2022 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. - */ - -#ifndef CANDY_GEAR_VK_DESTINATION_BUFFER_H -#define CANDY_GEAR_VK_DESTINATION_BUFFER_H 1 - -#include "base_buffer.hpp" -#include "core.hpp" -#include "source_buffer.hpp" -#include "queue_family.hpp" - -namespace VK -{ - -struct DestinationBuffer: public BaseBuffer -{ - DestinationBuffer(const DestinationBuffer &t) = delete; - DestinationBuffer& - operator=(const DestinationBuffer &t) = delete; - - QueueFamily *queue_family; - SourceBuffer *source_buffer; - VkCommandBuffer vk_command_buffer; - - DestinationBuffer( - QueueFamily *queue_family, SourceBuffer *source_buffer, - VkBufferUsageFlags buffer_usage); - - DestinationBuffer(DestinationBuffer &&that); - DestinationBuffer& - operator=(DestinationBuffer &&that); - - ~DestinationBuffer(); - - void - copy_data(); -}; - -} - -#endif /* CANDY_GEAR_VK_DESTINATION_BUFFER_H */ diff --git a/src/vk/device.cpp b/src/vk/device.cpp deleted file mode 100644 index 78baa53..0000000 --- a/src/vk/device.cpp +++ /dev/null @@ -1,392 +0,0 @@ -/* - * 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 "device.hpp" - -#include <fstream> -#include <new> -#include <vector> -#ifdef DEBUG -#include <sstream> -#endif - -#include "../core.hpp" - -namespace -{ -VkShaderModule -create_shader_module(VkDevice vk_device, const char *filename) -{ - std::ifstream file(filename, std::ios::ate | std::ios::binary); - - if (!file.is_open()) - { - throw std::runtime_error("Failed to open shader module file."); - } - - size_t file_size = (size_t) file.tellg(); - std::vector<char> code(file_size); - - file.seekg(0); - file.read(code.data(), file_size); - - file.close(); - - VkShaderModuleCreateInfo create_info = {}; - create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - create_info.codeSize = code.size(); - create_info.pCode = reinterpret_cast<const uint32_t*>(code.data()); - - VkShaderModule shader_module; - if (vkCreateShaderModule(vk_device, &create_info, nullptr, - &shader_module) != VK_SUCCESS) - { - throw std::runtime_error("Failed to create shader module."); - } - - return shader_module; -} -} - -namespace VK -{ - -Device::Device(VkPhysicalDevice vk_physical_device, bool with_swapchain) -{ - this->physical_device = vk_physical_device; - - std::vector<VkQueueFamilyProperties> queue_family_properties; - - // Get queue families. - { - vkGetPhysicalDeviceQueueFamilyProperties( - vk_physical_device, &this->queue_families_count, nullptr); - queue_family_properties.resize(this->queue_families_count); - vkGetPhysicalDeviceQueueFamilyProperties( - vk_physical_device, &this->queue_families_count, - queue_family_properties.data()); - } - - // Get information from physical device. - { - VkPhysicalDeviceProperties physical_properties = {}; - vkGetPhysicalDeviceProperties(vk_physical_device, &physical_properties); - VkPhysicalDeviceFeatures supported_features = {}; - vkGetPhysicalDeviceFeatures(vk_physical_device, &supported_features); - -#ifdef DEBUG - std::stringstream message{}; - message << "Name: " << physical_properties.deviceName << std::endl; - message << "API version: " << physical_properties.apiVersion << - std::endl; - message << "Driver version: " << physical_properties.driverVersion << - std::endl; - message << "Vendor ID: " << physical_properties.vendorID << std::endl; - message << "Device ID: " << physical_properties.deviceID << std::endl; - message << "Device type: " << physical_properties.deviceType << - std::endl; - cg_core.log.message(Log::Level::Trace, message.str()); -#endif - - std::vector<VkDeviceQueueCreateInfo> device_queue_create_infos; - std::vector<std::vector<float>> queue_priorities( - queue_family_properties.size()); - device_queue_create_infos.resize(queue_family_properties.size()); - for(auto i{0}; i < queue_family_properties.size(); i++) - { - // Give different priorities to queues. - int queue_count = queue_family_properties[i].queueCount; - queue_priorities[i].resize(queue_count); - float priority_unity = 1.0f/queue_count; - for(auto ii{0}; ii < queue_count; ii++) - queue_priorities[i][ii] = priority_unity * (queue_count - ii); - - device_queue_create_infos[i].sType = - VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - device_queue_create_infos[i].pNext = nullptr; - device_queue_create_infos[i].flags = 0; - device_queue_create_infos[i].queueFamilyIndex = i; - device_queue_create_infos[i].queueCount = queue_priorities[i].size(); - device_queue_create_infos[i].pQueuePriorities = - queue_priorities[i].data(); - } - - VkPhysicalDeviceFeatures required_features = {}; - required_features.multiDrawIndirect = supported_features.multiDrawIndirect; - required_features.fillModeNonSolid = VK_TRUE; - required_features.geometryShader = VK_TRUE; - required_features.tessellationShader = VK_TRUE; - required_features.samplerAnisotropy = VK_TRUE; - - std::vector<const char*> device_extensions; - if(with_swapchain) - device_extensions.emplace_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - - VkDeviceCreateInfo device_create_info = {}; - device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; - device_create_info.pNext = nullptr; - device_create_info.flags = 0; - device_create_info.queueCreateInfoCount = device_queue_create_infos.size(); - device_create_info.pQueueCreateInfos = device_queue_create_infos.data(); - device_create_info.enabledLayerCount = 0; - device_create_info.ppEnabledLayerNames = nullptr; - device_create_info.enabledExtensionCount = device_extensions.size(); - if(device_extensions.size() == 0) - device_create_info.ppEnabledExtensionNames = nullptr; - else - device_create_info.ppEnabledExtensionNames = device_extensions.data(); - - device_create_info.pEnabledFeatures = &required_features; - - if(vkCreateDevice(this->physical_device, &device_create_info, nullptr, - &this->device) != VK_SUCCESS) - throw std::runtime_error("Failed to create Vulkan physical device."); - } - - // Load Shaders - { - std::string data_dir{""}; -#ifdef _WIN64 - HKEY hKey; - LPCSTR lpSubKey = "SOFTWARE\\CandyGear"; - LPCSTR lpValueName = "InstallLocation"; - DWORD dwType = REG_SZ; - DWORD dwSize = 0; - LPBYTE lpData = NULL; - - if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpSubKey, 0, KEY_READ, &hKey) == - ERROR_SUCCESS) - { - if(RegQueryValueEx(hKey, lpValueName, NULL, &dwType, NULL, &dwSize) == - ERROR_SUCCESS) - { - lpData = new BYTE[dwSize]; - if(RegQueryValueEx( - hKey, lpValueName, NULL, &dwType, lpData, &dwSize) == - ERROR_SUCCESS) - { - data_dir = reinterpret_cast<char const*>(lpData); - } - delete[] lpData; - } - RegCloseKey(hKey); - } - - if(data_dir == "") - throw std::runtime_error("Failed to read CandyGear registry."); - - std::string vert_sprite_3d_shader_module{data_dir}; - vert_sprite_3d_shader_module.append("\\glsl\\shader_sprite_3d.vert.spv"); - this->vert_sprite_3d_shader_module = create_shader_module( - this->device, vert_sprite_3d_shader_module.c_str()); - - std::string frag_sprite_3d_shader_module{data_dir}; - frag_sprite_3d_shader_module.append("\\glsl\\shader_sprite_3d.frag.spv"); - this->frag_sprite_3d_shader_module = create_shader_module( - this->device, frag_sprite_3d_shader_module.c_str()); - - std::string vert3d_shader_module{data_dir}; - vert3d_shader_module.append("\\glsl\\shader_3d.vert.spv"); - this->vert3d_shader_module = create_shader_module( - this->device, vert3d_shader_module.c_str()); - - std::string vert3d_skeletal_shader_module{data_dir}; - vert3d_skeletal_shader_module.append( - "\\glsl\\shader_3d_skeletal.vert.spv"); - this->vert3d_skeletal_shader_module = create_shader_module( - this->device, vert3d_skeletal_shader_module.c_str()); - - std::string frag3d_shader_module{data_dir}; - frag3d_shader_module.append("\\glsl\\shader_3d.frag.spv"); - this->frag3d_shader_module = create_shader_module( - this->device, frag3d_shader_module.c_str()); - - std::string vert2d_solid_shader_module{data_dir}; - vert2d_solid_shader_module.append("\\glsl\\shader_2d_solid.vert.spv"); - this->vert2d_solid_shader_module = create_shader_module( - this->device, vert2d_solid_shader_module.c_str()); - - std::string frag2d_solid_shader_module{data_dir}; - frag2d_solid_shader_module.append("\\glsl\\shader_2d_solid.frag.spv"); - this->frag2d_solid_shader_module = create_shader_module( - this->device, frag2d_solid_shader_module.c_str()); - - std::string vert2d_wired_shader_module{data_dir}; - vert2d_wired_shader_module.append("\\glsl\\shader_2d_wired.vert.spv"); - this->vert2d_wired_shader_module = create_shader_module( - this->device, vert2d_wired_shader_module.c_str()); - - std::string frag2d_wired_shader_module{data_dir}; - frag2d_wired_shader_module.append("\\glsl\\shader_2d_wired.frag.spv"); - this->frag2d_wired_shader_module = create_shader_module( - this->device, frag2d_wired_shader_module.c_str()); -#else - data_dir = "/usr/local/share/candy_gear"; - - std::string vert_sprite_3d_shader_module{data_dir}; - vert_sprite_3d_shader_module.append("/glsl/shader_sprite_3d.vert.spv"); - this->vert_sprite_3d_shader_module = create_shader_module( - this->device, vert_sprite_3d_shader_module.c_str()); - - std::string frag_sprite_3d_shader_module{data_dir}; - frag_sprite_3d_shader_module.append("/glsl/shader_sprite_3d.frag.spv"); - this->frag_sprite_3d_shader_module = create_shader_module( - this->device, frag_sprite_3d_shader_module.c_str()); - - std::string vert3d_shader_module{data_dir}; - vert3d_shader_module.append("/glsl/shader_3d.vert.spv"); - this->vert3d_shader_module = create_shader_module( - this->device, vert3d_shader_module.c_str()); - - std::string vert3d_skeletal_shader_module{data_dir}; - vert3d_skeletal_shader_module.append("/glsl/shader_3d_skeletal.vert.spv"); - this->vert3d_skeletal_shader_module = create_shader_module( - this->device, vert3d_skeletal_shader_module.c_str()); - - std::string frag3d_shader_module{data_dir}; - frag3d_shader_module.append("/glsl/shader_3d.frag.spv"); - this->frag3d_shader_module = create_shader_module( - this->device, frag3d_shader_module.c_str()); - - std::string vert2d_solid_shader_module{data_dir}; - vert2d_solid_shader_module.append("/glsl/shader_2d_solid.vert.spv"); - this->vert2d_solid_shader_module = create_shader_module( - this->device, vert2d_solid_shader_module.c_str()); - - std::string frag2d_solid_shader_module{data_dir}; - frag2d_solid_shader_module.append("/glsl/shader_2d_solid.frag.spv"); - this->frag2d_solid_shader_module = create_shader_module( - this->device, frag2d_solid_shader_module.c_str()); - - std::string vert2d_wired_shader_module{data_dir}; - vert2d_wired_shader_module.append("/glsl/shader_2d_wired.vert.spv"); - this->vert2d_wired_shader_module = create_shader_module( - this->device, vert2d_wired_shader_module.c_str()); - - std::string frag2d_wired_shader_module{data_dir}; - frag2d_wired_shader_module.append("/glsl/shader_2d_wired.frag.spv"); - this->frag2d_wired_shader_module = create_shader_module( - this->device, frag2d_wired_shader_module.c_str()); -#endif - } - - this->queue_families = static_cast<QueueFamily*>( - std::malloc(this->queue_families_count * sizeof(QueueFamily))); - for(auto i{0}; i < this->queue_families_count; i++) - { - new(&this->queue_families[i])QueueFamily( - this, i, queue_family_properties[i]); - - // Select families with graphics support. - auto &family_properties = this->queue_families[i].family_properties; - if(family_properties.queueCount > 0 && - family_properties.queueFlags & VK_QUEUE_GRAPHICS_BIT) - this->queue_families_with_graphics.push_back( - &this->queue_families[i]); - - // Select families with presentation support. - VkBool32 present_supported; - vkGetPhysicalDeviceSurfaceSupportKHR( - vk_physical_device, i, cg_core.window_surface, &present_supported); - if(present_supported) - this->queue_families_with_presentation.push_back( - &this->queue_families[i]); - } -} - -Device::~Device() -{ - for(auto i{0}; i < this->queue_families_count; i++) - this->queue_families[i].~QueueFamily(); - std::free(this->queue_families); - - // Destroy shaders - vkDestroyShaderModule( - this->device, this->vert_sprite_3d_shader_module, nullptr); - vkDestroyShaderModule( - this->device, this->frag_sprite_3d_shader_module, nullptr); - vkDestroyShaderModule(this->device, this->vert3d_shader_module, nullptr); - vkDestroyShaderModule( - this->device, this->vert3d_skeletal_shader_module, nullptr); - vkDestroyShaderModule(this->device, this->frag3d_shader_module, nullptr); - vkDestroyShaderModule( - this->device, this->vert2d_solid_shader_module, nullptr); - vkDestroyShaderModule( - this->device, this->frag2d_solid_shader_module, nullptr); - vkDestroyShaderModule( - this->device, this->vert2d_wired_shader_module, nullptr); - vkDestroyShaderModule( - this->device, this->frag2d_wired_shader_module, nullptr); - - vkDeviceWaitIdle(this->device); - vkDestroyDevice(this->device, nullptr); -} - -bool -Device::select_memory_type( - uint32_t *memory_type_index, VkMemoryRequirements *vk_memory_requirements, - VkMemoryPropertyFlags vk_property_flags) -{ - VkPhysicalDeviceMemoryProperties vk_memory_properties; - vkGetPhysicalDeviceMemoryProperties( - this->physical_device, &vk_memory_properties); - - for (auto i{0}; i < vk_memory_properties.memoryTypeCount; i++) - { - if(vk_memory_requirements->memoryTypeBits & (1 << i)) - { - const VkMemoryType& type = vk_memory_properties.memoryTypes[i]; - - if ((type.propertyFlags & vk_property_flags) == vk_property_flags) - { - *memory_type_index = i; - return true; - } - } - } - - return false; -} - -QueueFamily* -Device::get_queue_family_with_graphics() const -{ - /* - Returns a random queue family, so not all commands in the engine use the - same queue. - TODO: There must be a better way of doing this. - */ - std::uniform_int_distribution<std::size_t> random_distribution{ - 0, this->queue_families_with_graphics.size() -1}; - auto random = random_distribution(random_number_generator); - return this->queue_families_with_graphics[0]; -} - -QueueFamily* -Device::get_queue_family_with_presentation() const -{ - /* - Returns a random queue family, so not all commands in the engine use the - same queue. - TODO: There must be a better way of doing this. - */ - std::uniform_int_distribution<std::size_t> random_distribution{ - 0, this->queue_families_with_presentation.size() -1}; - auto random = random_distribution(random_number_generator); - return this->queue_families_with_presentation[0]; -} - -} diff --git a/src/vk/device.hpp b/src/vk/device.hpp deleted file mode 100644 index e52a143..0000000 --- a/src/vk/device.hpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2022-2023 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. - */ - -#ifndef CANDY_GEAR_VK_DEVICE_H -#define CANDY_GEAR_VK_DEVICE_H 1 - -#include <cstdlib> -#include <vector> - -#include "core.hpp" -#include "queue_family.hpp" - -namespace VK -{ - -struct Device -{ - uint32_t queue_families_count; - QueueFamily *queue_families; - std::vector<QueueFamily*> queue_families_with_graphics; - std::vector<QueueFamily*> queue_families_with_presentation; - -public: - VkDevice device; - VkPhysicalDevice physical_device; - - VkShaderModule vert_sprite_3d_shader_module; - VkShaderModule frag_sprite_3d_shader_module; - VkShaderModule vert3d_shader_module; - VkShaderModule vert3d_skeletal_shader_module; - VkShaderModule frag3d_shader_module; - VkShaderModule vert2d_solid_shader_module; - VkShaderModule frag2d_solid_shader_module; - VkShaderModule vert2d_wired_shader_module; - VkShaderModule frag2d_wired_shader_module; - - bool with_swapchain; - - Device(VkPhysicalDevice vk_physical_device, bool with_swapchain); - ~Device(); - - bool - select_memory_type( - uint32_t *memoryTypeIndex, VkMemoryRequirements *vk_memory_requirements, - VkMemoryPropertyFlags vk_property_flags); - - QueueFamily* - get_queue_family_with_graphics() const; - - QueueFamily* - get_queue_family_with_presentation() const; -}; - -} - -#endif /* CANDY_GEAR_VK_DEVICE_H */ diff --git a/src/vk/font.cpp b/src/vk/font.cpp deleted file mode 100644 index cb01a51..0000000 --- a/src/vk/font.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2022-2023 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 "font.hpp" - -#include "../core.hpp" - -namespace VK -{ - -Font::Font(const char* font_path, int font_size) -{ - FT_Error error; - error = FT_New_Face(cg_core.font_library, font_path, 0, &this->face); - if(error == FT_Err_Unknown_File_Format) throw std::invalid_argument( - "The font file could be opened and read, but it appears that its font " - "format is unsupported."); - else if(error) throw std::invalid_argument( - "The font file could not be opened or read, or it is broken."); - - error = FT_Set_Pixel_Sizes(this->face, 0, font_size); - if(error) throw std::invalid_argument("Failed to load font size."); -} - -Font::~Font() -{ - FT_Done_Face(this->face); -} - -std::shared_ptr<Character> -Font::character(uint32_t character_code) -{ - if(!this->characters.contains(character_code)) - this->characters.emplace( - character_code, std::make_shared<Character>(this->face, character_code)); - - return this->characters.at(character_code); -} - -} diff --git a/src/vk/font.hpp b/src/vk/font.hpp deleted file mode 100644 index b654183..0000000 --- a/src/vk/font.hpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2022-2023 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. - */ - -#ifndef CANDY_GEAR_VK_FONT_H -#define CANDY_GEAR_VK_FONT_H 1 - -#include <memory> -#include <unordered_map> - -#include "character.hpp" - -namespace VK -{ - -struct Font -{ - FT_Face face; - std::unordered_map<uint32_t, std::shared_ptr<Character>> characters; - - Font(const char* font_path, int font_size); - ~Font(); - - std::shared_ptr<Character> - character(uint32_t character_code); -}; - -} - -#endif /* CANDY_GEAR_VK_FONT_H */ diff --git a/src/vk/framebuffer.cpp b/src/vk/framebuffer.cpp deleted file mode 100644 index 4104554..0000000 --- a/src/vk/framebuffer.cpp +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright 2022-2023 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 "framebuffer.hpp" - -#include "../core.hpp" -#include "image.hpp" - -namespace -{ -void -load_depth_image(void *obj) -{ - auto self = static_cast<VK::Framebuffer*>(obj); - - VkExtent3D extent3d{}; - extent3d.width = cg_core.display_width; - extent3d.height = cg_core.display_height; - extent3d.depth = 1; - - try - { - VK::Image::create( - cg_core.vk_device_with_swapchain, - &self->depth_image, - &self->depth_image_memory, - VK_FORMAT_D32_SFLOAT, - extent3d, - 1, - VK_IMAGE_TILING_OPTIMAL, - VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT - ); - } - catch(VK::Image::Error error) - { - std::string error_message{"Failed to create depth image → "}; - error_message += error.what(); - throw CommandError{error_message}; - } -} - -void -unload_depth_image(void *obj) -{ - auto self = static_cast<VK::Framebuffer*>(obj); - - vkDestroyImage( - cg_core.vk_device_with_swapchain->device, self->depth_image, - nullptr); - vkFreeMemory( - cg_core.vk_device_with_swapchain->device, - self->depth_image_memory, nullptr); -} - -void -load_depth_image_view(void *obj) -{ - auto self = static_cast<VK::Framebuffer*>(obj); - - try - { - VK::Image::create_view( - cg_core.vk_device_with_swapchain, &self->depth_image_view, - self->depth_image, - VK_FORMAT_D32_SFLOAT, VK_IMAGE_ASPECT_DEPTH_BIT); - } - catch(VK::Image::Error error) - { - std::string error_message{"Failed to create depth image view → "}; - error_message += error.what(); - throw CommandError{error_message}; - } -} - -void -unload_depth_image_view(void *obj) -{ - auto self = static_cast<VK::Framebuffer*>(obj); - - vkDestroyImageView( - cg_core.vk_device_with_swapchain->device, self->depth_image_view, nullptr); -} - -void -load_3d(void *obj) -{ - auto self = static_cast<VK::Framebuffer*>(obj); - - self->pipeline_3d.resize(cg_core.vk_swapchain->images_count); - for (auto i{0}; i < cg_core.vk_swapchain->images_count; i++) - { - std::array<VkImageView, 2> attachments = { - cg_core.vk_swapchain->image_views[i], - self->depth_image_view - }; - - VkFramebufferCreateInfo framebuffer_info{}; - framebuffer_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - framebuffer_info.renderPass = cg_core.vk_render_pass->pipeline_3d; - framebuffer_info.attachmentCount = attachments.size(); - framebuffer_info.pAttachments = attachments.data(); - framebuffer_info.width = cg_core.display_width; - framebuffer_info.height = cg_core.display_height; - - framebuffer_info.layers = 1; - - if(vkCreateFramebuffer( - cg_core.vk_device_with_swapchain->device, &framebuffer_info, nullptr, - &self->pipeline_3d[i]) != VK_SUCCESS) - throw CommandError{"Failed to create Vulkan Framebuffer."}; - } -} - -void -unload_3d(void *obj) -{ - auto self = static_cast<VK::Framebuffer*>(obj); - - for(auto framebuffer: self->pipeline_3d) - vkDestroyFramebuffer( - cg_core.vk_device_with_swapchain->device, framebuffer, nullptr); -} - -void -load_2d(void *obj) -{ - auto self = static_cast<VK::Framebuffer*>(obj); - - self->pipeline_2d.resize(cg_core.vk_swapchain->images_count); - for (auto i{0}; i < cg_core.vk_swapchain->images_count; i++) - { - std::array<VkImageView, 1> attachments = { - cg_core.vk_swapchain->image_views[i] - }; - - VkFramebufferCreateInfo framebuffer_info{}; - framebuffer_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - framebuffer_info.renderPass = cg_core.vk_render_pass->pipeline_2d; - framebuffer_info.attachmentCount = attachments.size(); - framebuffer_info.pAttachments = attachments.data(); - framebuffer_info.width = cg_core.display_width; - framebuffer_info.height = cg_core.display_height; - framebuffer_info.layers = 1; - - if(vkCreateFramebuffer( - cg_core.vk_device_with_swapchain->device, &framebuffer_info, nullptr, - &self->pipeline_2d[i]) - != VK_SUCCESS) - throw CommandError{"Failed to create Vulkan Framebuffer."}; - } -} - -void -unload_2d(void *obj) -{ - auto self = static_cast<VK::Framebuffer*>(obj); - - for(auto framebuffer: self->pipeline_2d) - vkDestroyFramebuffer( - cg_core.vk_device_with_swapchain->device, framebuffer, nullptr); -} - -const CommandChain loader{ - {&load_depth_image, &unload_depth_image}, - {&load_depth_image_view, &unload_depth_image_view}, - {&load_3d, &unload_3d}, - {&load_2d, &unload_2d} -}; - -} - -namespace VK -{ - -Framebuffer::Framebuffer() -{ - loader.execute(this); -} - -Framebuffer::~Framebuffer() -{ - loader.revert(this); -} - -} diff --git a/src/vk/framebuffer.hpp b/src/vk/framebuffer.hpp deleted file mode 100644 index 2867fa1..0000000 --- a/src/vk/framebuffer.hpp +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2022-2023 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. - */ - -#ifndef CANDY_GEAR_VK_FRAMEBUFFER_H -#define CANDY_GEAR_VK_FRAMEBUFFER_H 1 - -#include <vector> - -#include "core.hpp" - -namespace VK -{ - -struct Framebuffer -{ - // Depth image. - VkImage depth_image; - VkDeviceMemory depth_image_memory; - VkImageView depth_image_view; - - std::vector<VkFramebuffer> pipeline_3d; - std::vector<VkFramebuffer> pipeline_2d; - - Framebuffer(); - ~Framebuffer(); -}; - -} - -#endif /* CANDY_GEAR_VK_FRAMEBUFFER_H */ diff --git a/src/vk/graphics_pipeline_2d_solid.cpp b/src/vk/graphics_pipeline_2d_solid.cpp deleted file mode 100644 index f914594..0000000 --- a/src/vk/graphics_pipeline_2d_solid.cpp +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright 2022-2023 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 "graphics_pipeline_2d_solid.hpp" - -#include <array> - -#include "../core.hpp" -#include "sprite.hpp" -#include "uniform_data_object.hpp" - -namespace -{ - -void -load_pipeline(void *obj) -{ - auto self = static_cast<VK::GraphicsPipeline2DSolid*>(obj); - - VkPipelineShaderStageCreateInfo vert_shader_stage_info{}; - vert_shader_stage_info.sType = - VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - vert_shader_stage_info.pNext = nullptr; - vert_shader_stage_info.flags = 0; - vert_shader_stage_info.stage = VK_SHADER_STAGE_VERTEX_BIT; - vert_shader_stage_info.module = - cg_core.vk_device_with_swapchain->vert2d_solid_shader_module; - vert_shader_stage_info.pName = "main"; - vert_shader_stage_info.pSpecializationInfo = nullptr; - - VkPipelineShaderStageCreateInfo frag_shader_stage_info{}; - frag_shader_stage_info.sType = - VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - frag_shader_stage_info.pNext = nullptr; - frag_shader_stage_info.flags = 0; - frag_shader_stage_info.stage = VK_SHADER_STAGE_FRAGMENT_BIT; - frag_shader_stage_info.module = - cg_core.vk_device_with_swapchain->frag2d_solid_shader_module; - frag_shader_stage_info.pName = "main"; - frag_shader_stage_info.pSpecializationInfo = nullptr; - - VkPipelineShaderStageCreateInfo shader_stages[] = { - vert_shader_stage_info, - frag_shader_stage_info - }; - - VkVertexInputBindingDescription vertex_input_binding{}; - vertex_input_binding.binding = 0; - vertex_input_binding.stride = sizeof(glm::vec2); - vertex_input_binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; - - std::array<VkVertexInputAttributeDescription, 1> vertex_attribute{}; - // Texture coordinate. - vertex_attribute[0].location = 0; - vertex_attribute[0].binding = 0; - vertex_attribute[0].format = VK_FORMAT_R32G32_SFLOAT; - vertex_attribute[0].offset = 0; - - VkPipelineVertexInputStateCreateInfo vertex_input_info = {}; - vertex_input_info.sType = - VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; - vertex_input_info.pNext = nullptr; - vertex_input_info.flags = 0; - vertex_input_info.vertexBindingDescriptionCount = 1; - vertex_input_info.pVertexBindingDescriptions = &vertex_input_binding; - vertex_input_info.vertexAttributeDescriptionCount = - static_cast<uint32_t>(vertex_attribute.size()); - vertex_input_info.pVertexAttributeDescriptions = vertex_attribute.data(); - - VkPipelineInputAssemblyStateCreateInfo input_assembly = {}; - input_assembly.sType = - VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; - input_assembly.pNext = nullptr; - input_assembly.flags = 0; - input_assembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; - input_assembly.primitiveRestartEnable = VK_FALSE; - - VkViewport viewport = {}; - viewport.x = 0; - viewport.y = 0; - viewport.width = cg_core.display_width; - viewport.height = cg_core.display_height; - viewport.minDepth = 0.0f; - viewport.maxDepth = 1.0f; - - VkRect2D scissor = {}; - scissor.offset = {0, 0}; - scissor.extent = {cg_core.display_width, cg_core.display_height}; - - VkPipelineViewportStateCreateInfo viewport_state = {}; - viewport_state.sType = - VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; - viewport_state.pNext = nullptr; - viewport_state.flags = 0; - viewport_state.viewportCount = 1; - viewport_state.pViewports = &viewport; - viewport_state.scissorCount = 1; - viewport_state.pScissors = &scissor; - - VkPipelineRasterizationStateCreateInfo rasterizer = {}; - rasterizer.sType = - VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; - rasterizer.pNext = nullptr; - rasterizer.flags = 0; - rasterizer.depthClampEnable = VK_FALSE; - rasterizer.rasterizerDiscardEnable = VK_FALSE; - rasterizer.polygonMode = VK_POLYGON_MODE_FILL; - rasterizer.cullMode = VK_CULL_MODE_NONE; - rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; - rasterizer.depthBiasEnable = VK_FALSE; - rasterizer.depthBiasConstantFactor = 0.0f; - rasterizer.depthBiasClamp = 0.0f; - rasterizer.depthBiasSlopeFactor = 0.0f; - rasterizer.lineWidth = 1.0f; - - VkPipelineMultisampleStateCreateInfo multisampling = {}; - multisampling.sType = - VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; - multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; - multisampling.sampleShadingEnable = VK_FALSE; - multisampling.minSampleShading = 1.0f; - multisampling.pSampleMask = nullptr; - multisampling.alphaToCoverageEnable = VK_FALSE; - multisampling.alphaToOneEnable = VK_FALSE; - - VkPipelineColorBlendAttachmentState color_blend_attachment = {}; - color_blend_attachment.blendEnable = VK_TRUE; - color_blend_attachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; - color_blend_attachment.dstColorBlendFactor = - VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; - color_blend_attachment.colorBlendOp = VK_BLEND_OP_ADD; - color_blend_attachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; - color_blend_attachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; - color_blend_attachment.alphaBlendOp = VK_BLEND_OP_ADD; - color_blend_attachment.colorWriteMask = - VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | - VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; - - VkPipelineColorBlendStateCreateInfo color_blending = {}; - color_blending.sType = - VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; - color_blending.pNext = nullptr; - color_blending.flags = 0; - color_blending.logicOpEnable = VK_FALSE; - color_blending.logicOp = VK_LOGIC_OP_COPY; - color_blending.attachmentCount = 1; - color_blending.pAttachments = &color_blend_attachment; - color_blending.blendConstants[0] = 0.0f; - color_blending.blendConstants[1] = 0.0f; - color_blending.blendConstants[2] = 0.0f; - color_blending.blendConstants[3] = 0.0f; - - std::array<VkDynamicState, 3> dynamic_states{ - VK_DYNAMIC_STATE_VIEWPORT, - VK_DYNAMIC_STATE_LINE_WIDTH, - VK_DYNAMIC_STATE_BLEND_CONSTANTS - }; - - VkPipelineDynamicStateCreateInfo dynamic_state_info = {}; - dynamic_state_info.sType = - VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; - dynamic_state_info.dynamicStateCount = dynamic_states.size(); - dynamic_state_info.pDynamicStates = dynamic_states.data(); - - VkGraphicsPipelineCreateInfo pipeline_info{}; - pipeline_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; - pipeline_info.pNext = nullptr; - pipeline_info.flags = 0; - pipeline_info.stageCount = 2; - pipeline_info.pStages = shader_stages; - pipeline_info.pVertexInputState = &vertex_input_info; - pipeline_info.pInputAssemblyState = &input_assembly; - pipeline_info.pTessellationState = nullptr; - pipeline_info.pViewportState = &viewport_state; - pipeline_info.pRasterizationState = &rasterizer; - pipeline_info.pMultisampleState = &multisampling; - pipeline_info.pDepthStencilState = nullptr; - pipeline_info.pColorBlendState = &color_blending; - pipeline_info.pDynamicState = &dynamic_state_info; - pipeline_info.layout = - cg_core.vk_graphics_pipeline_2d_solid_layout->pipeline; - pipeline_info.renderPass = cg_core.vk_render_pass->pipeline_2d; - pipeline_info.subpass = 0; - pipeline_info.basePipelineHandle = VK_NULL_HANDLE; - pipeline_info.basePipelineIndex = -1; - - if(vkCreateGraphicsPipelines( - cg_core.vk_device_with_swapchain->device, VK_NULL_HANDLE, 1, - &pipeline_info, nullptr, &self->graphic_pipeline) - != VK_SUCCESS) - throw CommandError{"Failed to create graphics pipeline."}; -} - -void -unload_pipeline(void *obj) -{ - auto self = static_cast<VK::GraphicsPipeline2DSolid*>(obj); - - vkDestroyPipeline( - cg_core.vk_device_with_swapchain->device, self->graphic_pipeline, nullptr); -} - -const CommandChain loader{ - {&load_pipeline, &unload_pipeline} -}; - -} - -namespace VK -{ - -GraphicsPipeline2DSolid::GraphicsPipeline2DSolid() -{ - loader.execute(this); -} - -GraphicsPipeline2DSolid::~GraphicsPipeline2DSolid() -{ - loader.revert(this); -} - -void -GraphicsPipeline2DSolid::draw( - std::shared_ptr<View2D> view, const VkCommandBuffer draw_command_buffer, - const size_t current_frame, const size_t next_frame, - const uint32_t image_index) -{ - // TODO set viewport just once per view, not once per pipeline. - { // Set viewport - VkViewport vk_viewport{}; - vk_viewport.x = view->region.x; - vk_viewport.y = view->region.y; - vk_viewport.width = view->region.z; - vk_viewport.height = view->region.w; - vk_viewport.minDepth = 0.0f; - vk_viewport.maxDepth = 1.0f; - vkCmdSetViewport(draw_command_buffer, 0, 1, &vk_viewport); - - VkRect2D vk_scissor{}; - vk_scissor.offset.x = static_cast<int32_t>(view->region.x); - vk_scissor.offset.y = static_cast<int32_t>(view->region.y); - vk_scissor.extent.width = static_cast<uint32_t>(view->region.z); - vk_scissor.extent.height = static_cast<uint32_t>(view->region.w); - vkCmdSetScissor(draw_command_buffer, 0, 1, &vk_scissor); - } - - vkCmdBindPipeline( - draw_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - this->graphic_pipeline); - - // FIXME: I know sorting is expensive, but I need to figure out better what - // to do here. - std::sort(view->sprites_to_draw[current_frame].begin(), - view->sprites_to_draw[current_frame].end()); - - // Draw sprites - for(auto& sprite_to_draw: view->sprites_to_draw[current_frame]) - { - std::array<VkDescriptorSet, 2> vk_descriptor_sets{ - view->descriptor_sets_2d[image_index], - sprite_to_draw.sprite->texture->descriptor_sets[image_index]}; - VkDeviceSize offsets[]{0}; - - vkCmdBindDescriptorSets( - draw_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - cg_core.vk_graphics_pipeline_2d_solid_layout->pipeline, 0, - vk_descriptor_sets.size(), vk_descriptor_sets.data(), 0, nullptr); - vkCmdBindVertexBuffers( - draw_command_buffer, 0, 1, &sprite_to_draw.sprite->vertex_buffer->buffer, - offsets); - - UDOVector4D position{sprite_to_draw.position}; - vkCmdPushConstants( - draw_command_buffer, - cg_core.vk_graphics_pipeline_2d_solid_layout->pipeline, - VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(UDOVector4D), &position); - vkCmdDraw(draw_command_buffer, Sprite::vertex_count, 1, 0, 0); - } - - // Prepare for the next frame. - view->sprites_to_draw[next_frame].clear(); -} - -} diff --git a/src/vk/graphics_pipeline_2d_solid.hpp b/src/vk/graphics_pipeline_2d_solid.hpp deleted file mode 100644 index eac825f..0000000 --- a/src/vk/graphics_pipeline_2d_solid.hpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2022-2023 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. - */ - -#ifndef CANDY_GEAR_VK_GRAPHICS_PIPELINE_2D_SOLID_H -#define CANDY_GEAR_VK_GRAPHICS_PIPELINE_2D_SOLID_H 1 - -#include <memory> - -#include "core.hpp" -#include "command_pool.hpp" -#include "view_2d.hpp" - -namespace VK -{ - -struct GraphicsPipeline2DSolid -{ - VkPipeline graphic_pipeline; - - GraphicsPipeline2DSolid(); - ~GraphicsPipeline2DSolid(); - - void - draw(std::shared_ptr<View2D> view, const VkCommandBuffer draw_command_buffer, - const size_t current_frame, const size_t next_frame, - const uint32_t image_index); -}; - -} - -#endif /* CANDY_GEAR_VK_GRAPHICS_PIPELINE_2D_SOLID_H */ diff --git a/src/vk/graphics_pipeline_2d_solid_layout.cpp b/src/vk/graphics_pipeline_2d_solid_layout.cpp deleted file mode 100644 index 11d080b..0000000 --- a/src/vk/graphics_pipeline_2d_solid_layout.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2022-2023 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 "graphics_pipeline_2d_solid_layout.hpp" - -#include <array> - -#include "../core.hpp" -#include "uniform_data_object.hpp" - -namespace -{ - -void -load_pipeline(void *obj) -{ - auto self = static_cast<VK::GraphicsPipeline2DSolidLayout*>(obj); - - std::array<VkDescriptorSetLayout, 2> set_layouts{ - cg_core.vk_descriptor_set_layout->view, - cg_core.vk_descriptor_set_layout->texture - }; - - std::array<VkPushConstantRange, 1> push_constants; - push_constants[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; - push_constants[0].offset = 0; - push_constants[0].size = sizeof(VK::UDOVector4D); - - VkPipelineLayoutCreateInfo pipeline_layout_info{}; - pipeline_layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - pipeline_layout_info.setLayoutCount = set_layouts.size(); - pipeline_layout_info.pSetLayouts = set_layouts.data(); - pipeline_layout_info.pushConstantRangeCount = push_constants.size(); - pipeline_layout_info.pPushConstantRanges = push_constants.data(); - - if(vkCreatePipelineLayout( - cg_core.vk_device_with_swapchain->device, &pipeline_layout_info, - nullptr, &self->pipeline) != VK_SUCCESS) - throw CommandError{"Failed to create Vulkan pipeline layout."}; -} - -void -unload_pipeline(void *obj) -{ - auto self = static_cast<VK::GraphicsPipeline2DSolidLayout*>(obj); - - vkDestroyPipelineLayout( - cg_core.vk_device_with_swapchain->device, self->pipeline, nullptr); -} - -const CommandChain loader{ - {&load_pipeline, &unload_pipeline} -}; - -} - -namespace VK -{ - -GraphicsPipeline2DSolidLayout::GraphicsPipeline2DSolidLayout() -{ - loader.execute(this); -} - -GraphicsPipeline2DSolidLayout::~GraphicsPipeline2DSolidLayout() -{ - loader.revert(this); -} - -} diff --git a/src/vk/graphics_pipeline_2d_solid_layout.hpp b/src/vk/graphics_pipeline_2d_solid_layout.hpp deleted file mode 100644 index 0bb9de8..0000000 --- a/src/vk/graphics_pipeline_2d_solid_layout.hpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2022-2023 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. - */ - -#ifndef CANDY_GEAR_VK_GRAPHICS_PIPELINE_2D_LAYOUT_H -#define CANDY_GEAR_VK_GRAPHICS_PIPELINE_2D_LAYOUT_H 1 - -#include "core.hpp" - -namespace VK -{ - -struct GraphicsPipeline2DSolidLayout -{ - VkPipelineLayout pipeline; - - GraphicsPipeline2DSolidLayout(); - ~GraphicsPipeline2DSolidLayout(); -}; - -} - -#endif /* CANDY_GEAR_VK_GRAPHICS_PIPELINE_2D_LAYOUT_H */ diff --git a/src/vk/graphics_pipeline_2d_wired.cpp b/src/vk/graphics_pipeline_2d_wired.cpp deleted file mode 100644 index ef43cd1..0000000 --- a/src/vk/graphics_pipeline_2d_wired.cpp +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Copyright 2022-2023 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 "graphics_pipeline_2d_wired.hpp" - -#include <array> - -#include "../core.hpp" -#include "rectangle.hpp" -#include "sprite.hpp" -#include "uniform_data_object.hpp" - -namespace -{ - -void -load_indexes(void *obj) -{ - auto self = static_cast<VK::GraphicsPipeline2DWired*>(obj); - - self->queue_family = - cg_core.vk_device_with_swapchain->get_queue_family_with_graphics(); - - std::array<uint32_t, 4> indexes{0, 1, 2, 3}; - void *indexes_data{indexes.data()}; - size_t indexes_size{sizeof(indexes[0]) * indexes.size()}; - VK::SourceBuffer source_index_buffer{ - self->queue_family->device, indexes_data, indexes_size}; - self->index_buffer = new VK::DestinationBuffer{ - self->queue_family, &source_index_buffer, - VK_BUFFER_USAGE_INDEX_BUFFER_BIT}; -} - -void -unload_indexes(void *obj) -{ - auto self = static_cast<VK::GraphicsPipeline2DWired*>(obj); - - delete self->index_buffer; -} - -void -load_pipeline(void *obj) -{ - auto self = static_cast<VK::GraphicsPipeline2DWired*>(obj); - - VkPipelineShaderStageCreateInfo vert_shader_stage_info{}; - vert_shader_stage_info.sType = - VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - vert_shader_stage_info.pNext = nullptr; - vert_shader_stage_info.flags = 0; - vert_shader_stage_info.stage = VK_SHADER_STAGE_VERTEX_BIT; - vert_shader_stage_info.module = - cg_core.vk_device_with_swapchain->vert2d_wired_shader_module; - vert_shader_stage_info.pName = "main"; - vert_shader_stage_info.pSpecializationInfo = nullptr; - - VkPipelineShaderStageCreateInfo frag_shader_stage_info{}; - frag_shader_stage_info.sType = - VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - frag_shader_stage_info.pNext = nullptr; - frag_shader_stage_info.flags = 0; - frag_shader_stage_info.stage = VK_SHADER_STAGE_FRAGMENT_BIT; - frag_shader_stage_info.module = - cg_core.vk_device_with_swapchain->frag2d_wired_shader_module; - frag_shader_stage_info.pName = "main"; - frag_shader_stage_info.pSpecializationInfo = nullptr; - - VkPipelineShaderStageCreateInfo shader_stages[] = { - vert_shader_stage_info, - frag_shader_stage_info - }; - - VkPipelineVertexInputStateCreateInfo vertex_input_info = {}; - vertex_input_info.sType = - VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; - vertex_input_info.pNext = nullptr; - vertex_input_info.flags = 0; - vertex_input_info.vertexBindingDescriptionCount = 0; - vertex_input_info.pVertexBindingDescriptions = nullptr; - vertex_input_info.vertexAttributeDescriptionCount = 0; - vertex_input_info.pVertexAttributeDescriptions = nullptr; - - VkPipelineInputAssemblyStateCreateInfo input_assembly = {}; - input_assembly.sType = - VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; - input_assembly.pNext = nullptr; - input_assembly.flags = 0; - input_assembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; - input_assembly.primitiveRestartEnable = VK_FALSE; - - VkViewport viewport = {}; - viewport.x = 0; - viewport.y = 0; - viewport.width = cg_core.display_width; - viewport.height = cg_core.display_height; - viewport.minDepth = 0.0f; - viewport.maxDepth = 1.0f; - - VkRect2D scissor = {}; - scissor.offset = {0, 0}; - scissor.extent = {cg_core.display_width, cg_core.display_height}; - - VkPipelineViewportStateCreateInfo viewport_state = {}; - viewport_state.sType = - VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; - viewport_state.pNext = nullptr; - viewport_state.flags = 0; - viewport_state.viewportCount = 1; - viewport_state.pViewports = &viewport; - viewport_state.scissorCount = 1; - viewport_state.pScissors = &scissor; - - VkPipelineRasterizationStateCreateInfo rasterizer = {}; - rasterizer.sType = - VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; - rasterizer.pNext = nullptr; - rasterizer.flags = 0; - rasterizer.depthClampEnable = VK_FALSE; - rasterizer.rasterizerDiscardEnable = VK_FALSE; - rasterizer.polygonMode = VK_POLYGON_MODE_LINE; - rasterizer.cullMode = VK_CULL_MODE_NONE; - rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; - rasterizer.depthBiasEnable = VK_FALSE; - rasterizer.depthBiasConstantFactor = 0.0f; - rasterizer.depthBiasClamp = 0.0f; - rasterizer.depthBiasSlopeFactor = 0.0f; - rasterizer.lineWidth = 1.0f; - - VkPipelineMultisampleStateCreateInfo multisampling = {}; - multisampling.sType = - VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; - multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; - multisampling.sampleShadingEnable = VK_FALSE; - multisampling.minSampleShading = 1.0f; - multisampling.pSampleMask = nullptr; - multisampling.alphaToCoverageEnable = VK_FALSE; - multisampling.alphaToOneEnable = VK_FALSE; - - VkPipelineColorBlendAttachmentState color_blend_attachment = {}; - color_blend_attachment.blendEnable = VK_FALSE; - color_blend_attachment.srcColorBlendFactor = VK_BLEND_FACTOR_ONE; - color_blend_attachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; - color_blend_attachment.colorBlendOp = VK_BLEND_OP_ADD; - color_blend_attachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; - color_blend_attachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; - color_blend_attachment.alphaBlendOp = VK_BLEND_OP_ADD; - color_blend_attachment.colorWriteMask = - VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | - VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; - - VkPipelineColorBlendStateCreateInfo color_blending = {}; - color_blending.sType = - VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; - color_blending.pNext = nullptr; - color_blending.flags = 0; - color_blending.logicOpEnable = VK_FALSE; - color_blending.logicOp = VK_LOGIC_OP_COPY; - color_blending.attachmentCount = 1; - color_blending.pAttachments = &color_blend_attachment; - color_blending.blendConstants[0] = 0.0f; - color_blending.blendConstants[1] = 0.0f; - color_blending.blendConstants[2] = 0.0f; - color_blending.blendConstants[3] = 0.0f; - - VkDynamicState dynamic_states[] = { - VK_DYNAMIC_STATE_VIEWPORT, - VK_DYNAMIC_STATE_LINE_WIDTH - }; - - VkPipelineDynamicStateCreateInfo dynamic_state_info = {}; - dynamic_state_info.sType = - VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; - dynamic_state_info.dynamicStateCount = 2; - dynamic_state_info.pDynamicStates = dynamic_states; - - VkGraphicsPipelineCreateInfo pipeline_info{}; - pipeline_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; - pipeline_info.pNext = nullptr; - pipeline_info.flags = 0; - pipeline_info.stageCount = 2; - pipeline_info.pStages = shader_stages; - pipeline_info.pVertexInputState = &vertex_input_info; - pipeline_info.pInputAssemblyState = &input_assembly; - pipeline_info.pTessellationState = nullptr; - pipeline_info.pViewportState = &viewport_state; - pipeline_info.pRasterizationState = &rasterizer; - pipeline_info.pMultisampleState = &multisampling; - pipeline_info.pDepthStencilState = nullptr; - pipeline_info.pColorBlendState = &color_blending; - pipeline_info.pDynamicState = &dynamic_state_info; - pipeline_info.layout = - cg_core.vk_graphics_pipeline_2d_wired_layout->pipeline; - pipeline_info.renderPass = cg_core.vk_render_pass->pipeline_2d; - pipeline_info.subpass = 0; - pipeline_info.basePipelineHandle = VK_NULL_HANDLE; - pipeline_info.basePipelineIndex = -1; - - if(vkCreateGraphicsPipelines( - cg_core.vk_device_with_swapchain->device, VK_NULL_HANDLE, 1, - &pipeline_info, nullptr, &self->graphic_pipeline) != VK_SUCCESS) - throw CommandError{"Failed to create graphics pipeline."}; -} - -void -unload_pipeline(void *obj) -{ - auto self = static_cast<VK::GraphicsPipeline2DWired*>(obj); - - vkDestroyPipeline( - cg_core.vk_device_with_swapchain->device, self->graphic_pipeline, nullptr); -} - -const CommandChain loader{ - {&load_indexes, &unload_indexes}, - {&load_pipeline, &unload_pipeline} -}; - -} - -namespace VK -{ - -GraphicsPipeline2DWired::GraphicsPipeline2DWired() -{ - loader.execute(this); -} - -GraphicsPipeline2DWired::~GraphicsPipeline2DWired() -{ - loader.revert(this); -} - -void -GraphicsPipeline2DWired::draw( - std::shared_ptr<View2D> view, const VkCommandBuffer draw_command_buffer, - const size_t current_frame, const size_t next_frame, - const uint32_t image_index) -{ - // Set viewport - { - VkViewport vk_viewport{}; - vk_viewport.x = view->region.x; - vk_viewport.y = view->region.y; - vk_viewport.width = view->region.z; - vk_viewport.height = view->region.w; - vk_viewport.minDepth = 0.0f; - vk_viewport.maxDepth = 1.0f; - vkCmdSetViewport(draw_command_buffer, 0, 1, &vk_viewport); - - VkRect2D vk_scissor{}; - vk_scissor.offset.x = static_cast<int32_t>(view->region.x); - vk_scissor.offset.y = static_cast<int32_t>(view->region.y); - vk_scissor.extent.width = static_cast<uint32_t>(view->region.z); - vk_scissor.extent.height = static_cast<uint32_t>(view->region.w); - vkCmdSetScissor(draw_command_buffer, 0, 1, &vk_scissor); - } - - // Draw rectangles - { - std::array<VkDescriptorSet, 1> vk_descriptor_sets{ - view->descriptor_sets_2d[image_index]}; - VkDeviceSize offsets[]{0}; - - vkCmdBindDescriptorSets( - draw_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - cg_core.vk_graphics_pipeline_2d_wired_layout->pipeline, 0, - vk_descriptor_sets.size(), vk_descriptor_sets.data(), 0, nullptr); - vkCmdBindPipeline( - draw_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - this->graphic_pipeline); - vkCmdBindIndexBuffer( - draw_command_buffer, this->index_buffer->buffer, 0, - VK_INDEX_TYPE_UINT32); - - for(auto i{0}; i < view->rectangles_to_draw[current_frame].size(); i++) - { - auto &rect{view->rectangles_to_draw[current_frame][i]}; - - UDOVector4D position{rect.position}; - UDOVector3D color{rect.color}; - vkCmdPushConstants( - draw_command_buffer, - cg_core.vk_graphics_pipeline_2d_wired_layout->pipeline, - VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(UDOVector4D), &position); - vkCmdPushConstants( - draw_command_buffer, - cg_core.vk_graphics_pipeline_2d_wired_layout->pipeline, - VK_SHADER_STAGE_FRAGMENT_BIT, sizeof(UDOVector4D), sizeof(UDOVector3D), - &color); - vkCmdDrawIndexed( - draw_command_buffer, Rectangle::VertexCount, 1, 0, 0, 0); - } - } - - // Prepare for the next frame. - view->rectangles_to_draw[next_frame].clear(); -} - -} diff --git a/src/vk/graphics_pipeline_2d_wired.hpp b/src/vk/graphics_pipeline_2d_wired.hpp deleted file mode 100644 index 932ed61..0000000 --- a/src/vk/graphics_pipeline_2d_wired.hpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2022 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. - */ - -#ifndef CANDY_GEAR_VK_GRAPHICS_PIPELINE_2D_WIRED_H -#define CANDY_GEAR_VK_GRAPHICS_PIPELINE_2D_WIRED_H 1 - -#include <memory> - -#include "core.hpp" -#include "view_2d.hpp" - -namespace VK -{ - -struct GraphicsPipeline2DWired -{ - QueueFamily *queue_family; - - VkPipeline graphic_pipeline; - - DestinationBuffer *index_buffer; - - GraphicsPipeline2DWired(); - ~GraphicsPipeline2DWired(); - - void - draw(std::shared_ptr<View2D> view, const VkCommandBuffer draw_command_buffer, - const size_t current_frame, const size_t next_frame, - const uint32_t image_index); -}; - -} - -#endif /* CANDY_GEAR_VK_GRAPHICS_PIPELINE_2D_WIRED_H */ diff --git a/src/vk/graphics_pipeline_2d_wired_layout.cpp b/src/vk/graphics_pipeline_2d_wired_layout.cpp deleted file mode 100644 index 10e2b50..0000000 --- a/src/vk/graphics_pipeline_2d_wired_layout.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2022-2023 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 "graphics_pipeline_2d_wired_layout.hpp" - -#include <array> - -#include "../core.hpp" -#include "graphics_pipeline_2d_solid_layout.hpp" -#include "uniform_data_object.hpp" - -namespace -{ - -void -load_pipeline(void *obj) -{ - auto self = static_cast<VK::GraphicsPipeline2DWiredLayout*>(obj); - - std::array<VkDescriptorSetLayout, 1> set_layouts{ - cg_core.vk_descriptor_set_layout->view - }; - - std::array<VkPushConstantRange, 2> push_constants; - push_constants[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; - push_constants[0].offset = 0; - push_constants[0].size = sizeof(VK::UDOVector4D); - - push_constants[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; - push_constants[1].offset = sizeof(VK::UDOVector4D); - push_constants[1].size = sizeof(VK::UDOVector3D); - - VkPipelineLayoutCreateInfo pipeline_layout_info{}; - pipeline_layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - pipeline_layout_info.setLayoutCount = set_layouts.size(); - pipeline_layout_info.pSetLayouts = set_layouts.data(); - pipeline_layout_info.pushConstantRangeCount = push_constants.size(); - pipeline_layout_info.pPushConstantRanges = push_constants.data(); - - if(vkCreatePipelineLayout( - cg_core.vk_device_with_swapchain->device, &pipeline_layout_info, - nullptr, &self->pipeline) != VK_SUCCESS) - throw CommandError{"Failed to create Vulkan pipeline layout."}; -} - -void -unload_pipeline(void *obj) -{ - auto self = static_cast<VK::GraphicsPipeline2DWiredLayout*>(obj); - - vkDestroyPipelineLayout( - cg_core.vk_device_with_swapchain->device, self->pipeline, nullptr); -} - -const CommandChain loader{ - {&load_pipeline, &unload_pipeline} -}; - -} - -namespace VK -{ - -GraphicsPipeline2DWiredLayout::GraphicsPipeline2DWiredLayout() -{ - loader.execute(this); -} - -GraphicsPipeline2DWiredLayout::~GraphicsPipeline2DWiredLayout() -{ - loader.revert(this); -} - -} diff --git a/src/vk/graphics_pipeline_2d_wired_layout.hpp b/src/vk/graphics_pipeline_2d_wired_layout.hpp deleted file mode 100644 index 004f009..0000000 --- a/src/vk/graphics_pipeline_2d_wired_layout.hpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2022-2023 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. - */ - -#ifndef CANDY_GEAR_VK_GRAPHICS_PIPELINE_2D_WIRED_LAYOUT_H -#define CANDY_GEAR_VK_GRAPHICS_PIPELINE_2D_WIRED_LAYOUT_H 1 - -#include "core.hpp" - -namespace VK -{ - -struct GraphicsPipeline2DWiredLayout -{ - VkPipelineLayout pipeline; - - GraphicsPipeline2DWiredLayout(); - ~GraphicsPipeline2DWiredLayout(); -}; - -} - -#endif /* CANDY_GEAR_VK_GRAPHICS_PIPELINE_2D_LAYOUT_H */ diff --git a/src/vk/graphics_pipeline_3d.cpp b/src/vk/graphics_pipeline_3d.cpp deleted file mode 100644 index 2a1fec1..0000000 --- a/src/vk/graphics_pipeline_3d.cpp +++ /dev/null @@ -1,307 +0,0 @@ -/* - * 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 "graphics_pipeline_3d.hpp" - -#include <array> -#include <stdexcept> - -#include "../core.hpp" -#include "core.hpp" -#include "static_mesh_vertex.hpp" -#include "uniform_data_object.hpp" - -namespace -{ - -void -load_pipeline(void *obj) -{ - auto self = static_cast<VK::GraphicsPipeline3D*>(obj); - - VkPipelineShaderStageCreateInfo vert_shader_stage_info = {}; - vert_shader_stage_info.sType = - VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - vert_shader_stage_info.pNext = nullptr; - vert_shader_stage_info.flags = 0; - vert_shader_stage_info.stage = VK_SHADER_STAGE_VERTEX_BIT; - vert_shader_stage_info.module = - cg_core.vk_device_with_swapchain->vert3d_shader_module; - vert_shader_stage_info.pName = "main"; - vert_shader_stage_info.pSpecializationInfo = nullptr; - - VkPipelineShaderStageCreateInfo frag_shader_stage_info = {}; - frag_shader_stage_info.sType = - VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - frag_shader_stage_info.pNext = nullptr; - frag_shader_stage_info.flags = 0; - frag_shader_stage_info.stage = VK_SHADER_STAGE_FRAGMENT_BIT; - frag_shader_stage_info.module = - cg_core.vk_device_with_swapchain->frag3d_shader_module; - frag_shader_stage_info.pName = "main"; - frag_shader_stage_info.pSpecializationInfo = nullptr; - - VkPipelineShaderStageCreateInfo shader_stages[] = { - vert_shader_stage_info, - frag_shader_stage_info - }; - - VkVertexInputBindingDescription vertex_input_binding{}; - vertex_input_binding.binding = 0; - vertex_input_binding.stride = sizeof(VK::StaticMeshVertex); - vertex_input_binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; - - std::array<VkVertexInputAttributeDescription, 3> vertex_attribute{}; - // Position. - vertex_attribute[0].location = 0; - vertex_attribute[0].binding = 0; - vertex_attribute[0].format = VK_FORMAT_R32G32B32_SFLOAT; - vertex_attribute[0].offset = offsetof(VK::StaticMeshVertex, position); - // Normal. - vertex_attribute[1].location = 1; - vertex_attribute[1].binding = 0; - vertex_attribute[1].format = VK_FORMAT_R32G32B32_SFLOAT; - vertex_attribute[1].offset = offsetof(VK::StaticMeshVertex, normal); - // Texture coordinate. - vertex_attribute[2].location = 2; - vertex_attribute[2].binding = 0; - vertex_attribute[2].format = VK_FORMAT_R32G32_SFLOAT; - vertex_attribute[2].offset = offsetof(VK::StaticMeshVertex, texture_coord); - - VkPipelineVertexInputStateCreateInfo vertex_input_info = {}; - vertex_input_info.sType = - VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; - vertex_input_info.pNext = nullptr; - vertex_input_info.flags = 0; - vertex_input_info.vertexBindingDescriptionCount = 1; - vertex_input_info.pVertexBindingDescriptions = &vertex_input_binding; - vertex_input_info.vertexAttributeDescriptionCount = - static_cast<uint32_t>(vertex_attribute.size()); - vertex_input_info.pVertexAttributeDescriptions = vertex_attribute.data(); - - VkPipelineInputAssemblyStateCreateInfo input_assembly = {}; - input_assembly.sType = - VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; - input_assembly.pNext = nullptr; - input_assembly.flags = 0; - input_assembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; - input_assembly.primitiveRestartEnable = VK_FALSE; - - VkViewport viewport = {}; - viewport.x = 0; - viewport.y = 0; - viewport.width = cg_core.display_width; - viewport.height = cg_core.display_height; - viewport.minDepth = 0.0f; - viewport.maxDepth = 1.0f; - - VkRect2D scissor = {}; - scissor.offset = {0, 0}; - scissor.extent = {cg_core.display_width, cg_core.display_height}; - - VkPipelineViewportStateCreateInfo viewport_state = {}; - viewport_state.sType = - VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; - viewport_state.pNext = nullptr; - viewport_state.flags = 0; - viewport_state.viewportCount = 1; - viewport_state.pViewports = &viewport; - viewport_state.scissorCount = 1; - viewport_state.pScissors = &scissor; - - VkPipelineRasterizationStateCreateInfo rasterizer = {}; - rasterizer.sType = - VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; - rasterizer.pNext = nullptr; - rasterizer.flags = 0; - rasterizer.depthClampEnable = VK_FALSE; - rasterizer.rasterizerDiscardEnable = VK_FALSE; - rasterizer.polygonMode = VK_POLYGON_MODE_FILL; - rasterizer.cullMode = VK_CULL_MODE_NONE; - rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; - rasterizer.depthBiasEnable = VK_FALSE; - rasterizer.depthBiasConstantFactor = 0.0f; - rasterizer.depthBiasClamp = 0.0f; - rasterizer.depthBiasSlopeFactor = 0.0f; - rasterizer.lineWidth = 1.0f; - - VkPipelineMultisampleStateCreateInfo multisampling = {}; - multisampling.sType = - VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; - multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; - multisampling.sampleShadingEnable = VK_FALSE; - multisampling.minSampleShading = 1.0f; - multisampling.pSampleMask = nullptr; - multisampling.alphaToCoverageEnable = VK_FALSE; - multisampling.alphaToOneEnable = VK_FALSE; - - VkPipelineDepthStencilStateCreateInfo depth_stencil = {}; - depth_stencil.sType = - VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; - depth_stencil.depthTestEnable = VK_TRUE; - depth_stencil.depthWriteEnable = VK_TRUE; - depth_stencil.depthCompareOp = VK_COMPARE_OP_LESS; - depth_stencil.depthBoundsTestEnable = VK_FALSE; - depth_stencil.minDepthBounds = 0.0f; - depth_stencil.maxDepthBounds = 1.0f; - depth_stencil.stencilTestEnable = VK_FALSE; - depth_stencil.front = {}; - depth_stencil.back = {}; - - VkPipelineColorBlendAttachmentState color_blend_attachment = {}; - color_blend_attachment.blendEnable = VK_FALSE; - color_blend_attachment.srcColorBlendFactor = VK_BLEND_FACTOR_ONE; - color_blend_attachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; - color_blend_attachment.colorBlendOp = VK_BLEND_OP_ADD; - color_blend_attachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; - color_blend_attachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; - color_blend_attachment.alphaBlendOp = VK_BLEND_OP_ADD; - color_blend_attachment.colorWriteMask = - VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | - VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; - - VkPipelineColorBlendStateCreateInfo color_blending = {}; - color_blending.sType = - VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; - color_blending.pNext = nullptr; - color_blending.flags = 0; - color_blending.logicOpEnable = VK_FALSE; - color_blending.logicOp = VK_LOGIC_OP_COPY; - color_blending.attachmentCount = 1; - color_blending.pAttachments = &color_blend_attachment; - color_blending.blendConstants[0] = 0.0f; - color_blending.blendConstants[1] = 0.0f; - color_blending.blendConstants[2] = 0.0f; - color_blending.blendConstants[3] = 0.0f; - - VkDynamicState dynamic_states[] = { - VK_DYNAMIC_STATE_VIEWPORT, - VK_DYNAMIC_STATE_LINE_WIDTH - }; - - VkPipelineDynamicStateCreateInfo dynamic_state_info = {}; - dynamic_state_info.sType = - VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; - dynamic_state_info.dynamicStateCount = 2; - dynamic_state_info.pDynamicStates = dynamic_states; - - VkGraphicsPipelineCreateInfo pipeline_info{}; - pipeline_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; - pipeline_info.pNext = nullptr; - pipeline_info.flags = 0; - pipeline_info.stageCount = 2; - pipeline_info.pStages = shader_stages; - pipeline_info.pVertexInputState = &vertex_input_info; - pipeline_info.pInputAssemblyState = &input_assembly; - pipeline_info.pTessellationState = nullptr; - pipeline_info.pViewportState = &viewport_state; - pipeline_info.pRasterizationState = &rasterizer; - pipeline_info.pMultisampleState = &multisampling; - pipeline_info.pDepthStencilState = &depth_stencil; - pipeline_info.pColorBlendState = &color_blending; - pipeline_info.pDynamicState = &dynamic_state_info; - pipeline_info.layout = cg_core.vk_graphics_pipeline_3d_layout->pipeline; - pipeline_info.renderPass = cg_core.vk_render_pass->pipeline_3d; - pipeline_info.subpass = 0; - pipeline_info.basePipelineHandle = VK_NULL_HANDLE; - pipeline_info.basePipelineIndex = -1; - - if(vkCreateGraphicsPipelines( - cg_core.vk_device_with_swapchain->device, VK_NULL_HANDLE, 1, - &pipeline_info, nullptr, &self->graphic_pipeline) - != VK_SUCCESS) - throw CommandError{"Failed to create graphics pipeline."}; -} - -void -unload_pipeline(void *obj) -{ - auto self = static_cast<VK::GraphicsPipeline3D*>(obj); - - vkDestroyPipeline( - cg_core.vk_device_with_swapchain->device, self->graphic_pipeline, nullptr); -} - -const CommandChain loader{ - {&load_pipeline, &unload_pipeline} -}; - -} - -namespace VK -{ - -GraphicsPipeline3D::GraphicsPipeline3D() -{ - loader.execute(this); -} - -GraphicsPipeline3D::~GraphicsPipeline3D() -{ - loader.revert(this); -} - -void -GraphicsPipeline3D::draw( - std::shared_ptr<View3D> view, const VkCommandBuffer draw_command_buffer, - const size_t current_frame, const uint32_t image_index) -{ - vkCmdBindPipeline( - draw_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - this->graphic_pipeline); - - // Draw models - for(auto& [static_mesh, instances]: - cg_core.vk_renderer->static_models_to_draw[current_frame]) - { - VkBuffer vertex_buffers[]{static_mesh->vertex_buffer->buffer}; - VkDeviceSize offsets[]{0}; - - vkCmdBindVertexBuffers( - draw_command_buffer, 0, 1, vertex_buffers, offsets); - vkCmdBindIndexBuffer( - draw_command_buffer, static_mesh->index_buffer->buffer, 0, - VK_INDEX_TYPE_UINT32); - - for(auto &instance: instances) - { // Object matrix. - glm::mat4 translation_matrix{1.0f}; - translation_matrix = glm::translate( - translation_matrix, *instance->position); - glm::mat4 rotation_matrix{glm::toMat4(*instance->orientation)}; - - std::array<VkDescriptorSet, 4> vk_descriptor_sets{ - cg_core.vk_light->descriptor_sets_world[image_index], - view->descriptor_sets_3d[image_index], - instance->descriptor_sets[image_index], - instance->texture->descriptor_sets[image_index]}; - - vkCmdBindDescriptorSets( - draw_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - cg_core.vk_graphics_pipeline_3d_layout->pipeline, 0, - vk_descriptor_sets.size(), vk_descriptor_sets.data(), 0, nullptr); - - vkCmdDrawIndexed( - draw_command_buffer, static_mesh->index_count, 1, 0, 0, 0); - - VK::UDOStaticModel udo_static_model{}; - udo_static_model.base_matrix = translation_matrix * rotation_matrix; - instance->uniform_buffers[image_index].copy_data(&udo_static_model); - } - } -} - -} diff --git a/src/vk/graphics_pipeline_3d.hpp b/src/vk/graphics_pipeline_3d.hpp deleted file mode 100644 index bfe034d..0000000 --- a/src/vk/graphics_pipeline_3d.hpp +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2022-2023 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. - */ - -#ifndef CANDY_GEAR_VK_GRAPHICS_PIPELINE_3D_H -#define CANDY_GEAR_VK_GRAPHICS_PIPELINE_3D_H 1 - -#include <memory> - -#include "core.hpp" -#include "command_pool.hpp" -#include "view_3d.hpp" - -namespace VK -{ - -struct GraphicsPipeline3D -{ - VkPipeline graphic_pipeline; - - GraphicsPipeline3D(); - ~GraphicsPipeline3D(); - - void - draw(std::shared_ptr<View3D> view, const VkCommandBuffer draw_command_buffer, - const size_t current_frame, const uint32_t image_index); -}; - -} - -#endif /* CANDY_GEAR_VK_GRAPHICS_PIPELINE_3D_H */ diff --git a/src/vk/graphics_pipeline_3d_layout.cpp b/src/vk/graphics_pipeline_3d_layout.cpp deleted file mode 100644 index c316518..0000000 --- a/src/vk/graphics_pipeline_3d_layout.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2022-2023 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 "graphics_pipeline_3d_layout.hpp" - -#include <array> - -#include "../core.hpp" -#include "uniform_data_object.hpp" - -namespace -{ - -void -load_pipeline(void *obj) -{ - auto self = static_cast<VK::GraphicsPipeline3DLayout*>(obj); - - std::array<VkDescriptorSetLayout, 4> set_layouts{ - cg_core.vk_descriptor_set_layout->world, - cg_core.vk_descriptor_set_layout->view, - cg_core.vk_descriptor_set_layout->model, - cg_core.vk_descriptor_set_layout->texture}; - - VkPipelineLayoutCreateInfo pipeline_layout_info{}; - pipeline_layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - pipeline_layout_info.setLayoutCount = set_layouts.size(); - pipeline_layout_info.pSetLayouts = set_layouts.data(); - pipeline_layout_info.pushConstantRangeCount = 0; - pipeline_layout_info.pPushConstantRanges = nullptr; - - if(vkCreatePipelineLayout( - cg_core.vk_device_with_swapchain->device, - &pipeline_layout_info, nullptr, &self->pipeline) != VK_SUCCESS) - throw CommandError{"Failed to create Vulkan pipeline layout."}; -} - -void -unload_pipeline(void *obj) -{ - auto self = static_cast<VK::GraphicsPipeline3DLayout*>(obj); - - vkDestroyPipelineLayout( - cg_core.vk_device_with_swapchain->device, self->pipeline, nullptr); -} - -const CommandChain loader{ - {&load_pipeline, &unload_pipeline} -}; - -} - -namespace VK -{ - -GraphicsPipeline3DLayout::GraphicsPipeline3DLayout() -{ - loader.execute(this); -} - -GraphicsPipeline3DLayout::~GraphicsPipeline3DLayout() -{ - loader.revert(this); -} - -} diff --git a/src/vk/graphics_pipeline_3d_layout.hpp b/src/vk/graphics_pipeline_3d_layout.hpp deleted file mode 100644 index 4b2b9b9..0000000 --- a/src/vk/graphics_pipeline_3d_layout.hpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2022-2023 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. - */ - -#ifndef CANDY_GEAR_VK_GRAPHICS_PIPELINE_3D_LAYOUT_H -#define CANDY_GEAR_VK_GRAPHICS_PIPELINE_3D_LAYOUT_H 1 - -#include "core.hpp" - -namespace VK -{ - -struct GraphicsPipeline3DLayout -{ - VkPipelineLayout pipeline; - - GraphicsPipeline3DLayout(); - ~GraphicsPipeline3DLayout(); -}; - -} - -#endif /* CANDY_GEAR_VK_GRAPHICS_PIPELINE_3D_LAYOUT_H */ diff --git a/src/vk/graphics_pipeline_3d_skeletal.cpp b/src/vk/graphics_pipeline_3d_skeletal.cpp deleted file mode 100644 index 6bd1713..0000000 --- a/src/vk/graphics_pipeline_3d_skeletal.cpp +++ /dev/null @@ -1,322 +0,0 @@ -/* - * 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 "graphics_pipeline_3d.hpp" - -#include <array> -#include <stdexcept> - -#include "../core.hpp" -#include "core.hpp" -#include "skeletal_mesh_vertex.hpp" -#include "uniform_data_object.hpp" - -namespace -{ - -void -load_pipeline(void *obj) -{ - auto self = static_cast<VK::GraphicsPipeline3DSkeletal*>(obj); - - VkPipelineShaderStageCreateInfo vert_shader_stage_info = {}; - vert_shader_stage_info.sType = - VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - vert_shader_stage_info.pNext = nullptr; - vert_shader_stage_info.flags = 0; - vert_shader_stage_info.stage = VK_SHADER_STAGE_VERTEX_BIT; - vert_shader_stage_info.module = - cg_core.vk_device_with_swapchain->vert3d_skeletal_shader_module; - vert_shader_stage_info.pName = "main"; - vert_shader_stage_info.pSpecializationInfo = nullptr; - - VkPipelineShaderStageCreateInfo frag_shader_stage_info = {}; - frag_shader_stage_info.sType = - VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - frag_shader_stage_info.pNext = nullptr; - frag_shader_stage_info.flags = 0; - frag_shader_stage_info.stage = VK_SHADER_STAGE_FRAGMENT_BIT; - frag_shader_stage_info.module = - cg_core.vk_device_with_swapchain->frag3d_shader_module; - frag_shader_stage_info.pName = "main"; - frag_shader_stage_info.pSpecializationInfo = nullptr; - - VkPipelineShaderStageCreateInfo shader_stages[] = { - vert_shader_stage_info, - frag_shader_stage_info - }; - - VkVertexInputBindingDescription vertex_input_binding{}; - vertex_input_binding.binding = 0; - vertex_input_binding.stride = sizeof(VK::SkeletalMeshVertex); - vertex_input_binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; - - std::array<VkVertexInputAttributeDescription, 5> vertex_attribute{}; - // Position. - vertex_attribute[0].location = 0; - vertex_attribute[0].binding = 0; - vertex_attribute[0].format = VK_FORMAT_R32G32B32_SFLOAT; - vertex_attribute[0].offset = offsetof(VK::SkeletalMeshVertex, position); - // Normal. - vertex_attribute[1].location = 1; - vertex_attribute[1].binding = 0; - vertex_attribute[1].format = VK_FORMAT_R32G32B32_SFLOAT; - vertex_attribute[1].offset = offsetof(VK::SkeletalMeshVertex, normal); - // Texture coordinate. - vertex_attribute[2].location = 2; - vertex_attribute[2].binding = 0; - vertex_attribute[2].format = VK_FORMAT_R32G32_SFLOAT; - vertex_attribute[2].offset = offsetof(VK::SkeletalMeshVertex, texture_coord); - // Bones ids. - vertex_attribute[3].location = 3; - vertex_attribute[3].binding = 0; - vertex_attribute[3].format = VK_FORMAT_R32G32B32A32_SINT; - vertex_attribute[3].offset = offsetof(VK::SkeletalMeshVertex, bone_ids); - // Bones weights. - vertex_attribute[4].location = 4; - vertex_attribute[4].binding = 0; - vertex_attribute[4].format = VK_FORMAT_R32G32B32A32_SFLOAT; - vertex_attribute[4].offset = offsetof(VK::SkeletalMeshVertex, bone_weights); - - VkPipelineVertexInputStateCreateInfo vertex_input_info = {}; - vertex_input_info.sType = - VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; - vertex_input_info.pNext = nullptr; - vertex_input_info.flags = 0; - vertex_input_info.vertexBindingDescriptionCount = 1; - vertex_input_info.pVertexBindingDescriptions = &vertex_input_binding; - vertex_input_info.vertexAttributeDescriptionCount = - static_cast<uint32_t>(vertex_attribute.size()); - vertex_input_info.pVertexAttributeDescriptions = vertex_attribute.data(); - - VkPipelineInputAssemblyStateCreateInfo input_assembly = {}; - input_assembly.sType = - VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; - input_assembly.pNext = nullptr; - input_assembly.flags = 0; - input_assembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; - input_assembly.primitiveRestartEnable = VK_FALSE; - - VkViewport viewport = {}; - viewport.x = 0; - viewport.y = 0; - viewport.width = cg_core.display_width; - viewport.height = cg_core.display_height; - viewport.minDepth = 0.0f; - viewport.maxDepth = 1.0f; - - VkRect2D scissor = {}; - scissor.offset = {0, 0}; - scissor.extent = {cg_core.display_width, cg_core.display_height}; - - VkPipelineViewportStateCreateInfo viewport_state = {}; - viewport_state.sType = - VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; - viewport_state.pNext = nullptr; - viewport_state.flags = 0; - viewport_state.viewportCount = 1; - viewport_state.pViewports = &viewport; - viewport_state.scissorCount = 1; - viewport_state.pScissors = &scissor; - - VkPipelineRasterizationStateCreateInfo rasterizer = {}; - rasterizer.sType = - VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; - rasterizer.pNext = nullptr; - rasterizer.flags = 0; - rasterizer.depthClampEnable = VK_FALSE; - rasterizer.rasterizerDiscardEnable = VK_FALSE; - rasterizer.polygonMode = VK_POLYGON_MODE_FILL; - rasterizer.cullMode = VK_CULL_MODE_NONE; - rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; - rasterizer.depthBiasEnable = VK_FALSE; - rasterizer.depthBiasConstantFactor = 0.0f; - rasterizer.depthBiasClamp = 0.0f; - rasterizer.depthBiasSlopeFactor = 0.0f; - rasterizer.lineWidth = 1.0f; - - VkPipelineMultisampleStateCreateInfo multisampling = {}; - multisampling.sType = - VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; - multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; - multisampling.sampleShadingEnable = VK_FALSE; - multisampling.minSampleShading = 1.0f; - multisampling.pSampleMask = nullptr; - multisampling.alphaToCoverageEnable = VK_FALSE; - multisampling.alphaToOneEnable = VK_FALSE; - - VkPipelineDepthStencilStateCreateInfo depth_stencil = {}; - depth_stencil.sType = - VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; - depth_stencil.depthTestEnable = VK_TRUE; - depth_stencil.depthWriteEnable = VK_TRUE; - depth_stencil.depthCompareOp = VK_COMPARE_OP_LESS; - depth_stencil.depthBoundsTestEnable = VK_FALSE; - depth_stencil.minDepthBounds = 0.0f; - depth_stencil.maxDepthBounds = 1.0f; - depth_stencil.stencilTestEnable = VK_FALSE; - depth_stencil.front = {}; - depth_stencil.back = {}; - - VkPipelineColorBlendAttachmentState color_blend_attachment = {}; - color_blend_attachment.blendEnable = VK_FALSE; - color_blend_attachment.srcColorBlendFactor = VK_BLEND_FACTOR_ONE; - color_blend_attachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; - color_blend_attachment.colorBlendOp = VK_BLEND_OP_ADD; - color_blend_attachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; - color_blend_attachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; - color_blend_attachment.alphaBlendOp = VK_BLEND_OP_ADD; - color_blend_attachment.colorWriteMask = - VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | - VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; - - VkPipelineColorBlendStateCreateInfo color_blending = {}; - color_blending.sType = - VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; - color_blending.pNext = nullptr; - color_blending.flags = 0; - color_blending.logicOpEnable = VK_FALSE; - color_blending.logicOp = VK_LOGIC_OP_COPY; - color_blending.attachmentCount = 1; - color_blending.pAttachments = &color_blend_attachment; - color_blending.blendConstants[0] = 0.0f; - color_blending.blendConstants[1] = 0.0f; - color_blending.blendConstants[2] = 0.0f; - color_blending.blendConstants[3] = 0.0f; - - VkDynamicState dynamic_states[] = { - VK_DYNAMIC_STATE_VIEWPORT, - VK_DYNAMIC_STATE_LINE_WIDTH - }; - - VkPipelineDynamicStateCreateInfo dynamic_state_info = {}; - dynamic_state_info.sType = - VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; - dynamic_state_info.dynamicStateCount = 2; - dynamic_state_info.pDynamicStates = dynamic_states; - - VkGraphicsPipelineCreateInfo pipeline_info{}; - pipeline_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; - pipeline_info.pNext = nullptr; - pipeline_info.flags = 0; - pipeline_info.stageCount = 2; - pipeline_info.pStages = shader_stages; - pipeline_info.pVertexInputState = &vertex_input_info; - pipeline_info.pInputAssemblyState = &input_assembly; - pipeline_info.pTessellationState = nullptr; - pipeline_info.pViewportState = &viewport_state; - pipeline_info.pRasterizationState = &rasterizer; - pipeline_info.pMultisampleState = &multisampling; - pipeline_info.pDepthStencilState = &depth_stencil; - pipeline_info.pColorBlendState = &color_blending; - pipeline_info.pDynamicState = &dynamic_state_info; - pipeline_info.layout = cg_core.vk_graphics_pipeline_3d_layout->pipeline; - pipeline_info.renderPass = cg_core.vk_render_pass->pipeline_3d; - pipeline_info.subpass = 0; - pipeline_info.basePipelineHandle = VK_NULL_HANDLE; - pipeline_info.basePipelineIndex = -1; - - if(vkCreateGraphicsPipelines( - cg_core.vk_device_with_swapchain->device, VK_NULL_HANDLE, 1, - &pipeline_info, nullptr, &self->graphic_pipeline) - != VK_SUCCESS) - throw CommandError{"Failed to create graphics pipeline."}; -} - -void -unload_pipeline(void *obj) -{ - auto self = static_cast<VK::GraphicsPipeline3DSkeletal*>(obj); - - vkDestroyPipeline( - cg_core.vk_device_with_swapchain->device, self->graphic_pipeline, nullptr); -} - -const CommandChain loader{ - {&load_pipeline, &unload_pipeline} -}; - -} - -namespace VK -{ - -GraphicsPipeline3DSkeletal::GraphicsPipeline3DSkeletal() -{ - loader.execute(this); -} - -GraphicsPipeline3DSkeletal::~GraphicsPipeline3DSkeletal() -{ - loader.revert(this); -} - -void -GraphicsPipeline3DSkeletal::draw( - std::shared_ptr<View3D> view, const VkCommandBuffer draw_command_buffer, - const size_t current_frame, const uint32_t image_index) -{ - vkCmdBindPipeline( - draw_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - this->graphic_pipeline); - - // Draw models - for(auto& [skeletal_mesh, instances]: - cg_core.vk_renderer->skeletal_models_to_draw[current_frame]) - { - VkBuffer vertex_buffers[]{skeletal_mesh->vertex_buffer->buffer}; - VkDeviceSize offsets[]{0}; - - vkCmdBindVertexBuffers( - draw_command_buffer, 0, 1, vertex_buffers, offsets); - vkCmdBindIndexBuffer( - draw_command_buffer, skeletal_mesh->index_buffer->buffer, 0, - VK_INDEX_TYPE_UINT32); - - for(auto &instance: instances) - { // Object matrix. - glm::mat4 translation_matrix{1.0f}; - translation_matrix = glm::translate( - translation_matrix, *instance->position); - glm::mat4 rotation_matrix{glm::toMat4(*instance->orientation)}; - - std::array<VkDescriptorSet, 4> vk_descriptor_sets{ - cg_core.vk_light->descriptor_sets_world[image_index], - view->descriptor_sets_3d[image_index], - instance->descriptor_sets[image_index], - instance->texture->descriptor_sets[image_index]}; - - vkCmdBindDescriptorSets( - draw_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - cg_core.vk_graphics_pipeline_3d_layout->pipeline, 0, - vk_descriptor_sets.size(), vk_descriptor_sets.data(), 0, nullptr); - - vkCmdDrawIndexed( - draw_command_buffer, skeletal_mesh->index_count, 1, 0, 0, 0); - - VK::UDOSkeletalModel udo_skeletal_model{}; - instance->tick(cg_core.delta_time); - udo_skeletal_model.base_matrix = translation_matrix * rotation_matrix; - std::copy(instance->bone_transforms.begin(), - instance->bone_transforms.end(), - udo_skeletal_model.bone_matrices); - instance->uniform_buffers[image_index].copy_data(&udo_skeletal_model); - } - } - -} - -} diff --git a/src/vk/graphics_pipeline_3d_skeletal.hpp b/src/vk/graphics_pipeline_3d_skeletal.hpp deleted file mode 100644 index 027b42e..0000000 --- a/src/vk/graphics_pipeline_3d_skeletal.hpp +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2022-2023 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. - */ - -#ifndef CANDY_GEAR_VK_GRAPHICS_PIPELINE_3D_SKELETAL_H -#define CANDY_GEAR_VK_GRAPHICS_PIPELINE_3D_SKELETAL_H 1 - -#include <memory> - -#include "core.hpp" -#include "command_pool.hpp" -#include "view_3d.hpp" - -namespace VK -{ - -struct GraphicsPipeline3DSkeletal -{ - VkPipeline graphic_pipeline; - - GraphicsPipeline3DSkeletal(); - ~GraphicsPipeline3DSkeletal(); - - void - draw(std::shared_ptr<View3D> view, const VkCommandBuffer draw_command_buffer, - const size_t current_frame, const uint32_t image_index); -}; - -} - -#endif /* CANDY_GEAR_VK_GRAPHICS_PIPELINE_SKELETAL_3D_H */ diff --git a/src/vk/graphics_pipeline_sprite_3d.cpp b/src/vk/graphics_pipeline_sprite_3d.cpp deleted file mode 100644 index 0a4d520..0000000 --- a/src/vk/graphics_pipeline_sprite_3d.cpp +++ /dev/null @@ -1,315 +0,0 @@ -/* - * Copyright 2022-2023 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 "graphics_pipeline_sprite_3d.hpp" - -#include <array> - -#include "../core.hpp" -#include "core.hpp" -#include "sprite.hpp" -#include "uniform_data_object.hpp" - -namespace -{ - -struct Sprite3DOrder -{ - std::shared_ptr<VK::Sprite3D> sprite_3d; - float distance; -}; - -bool -operator<(const Sprite3DOrder &a, const Sprite3DOrder &b) -{ - return a.distance < b.distance; -} - -bool -operator>(const Sprite3DOrder &a, const Sprite3DOrder &b) -{ - return a.distance > b.distance; -} - -void -load_pipeline(void *obj) -{ - auto self = static_cast<VK::GraphicsPipelineSprite3D*>(obj); - - VkPipelineShaderStageCreateInfo vert_shader_stage_info{}; - vert_shader_stage_info.sType = - VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - vert_shader_stage_info.pNext = nullptr; - vert_shader_stage_info.flags = 0; - vert_shader_stage_info.stage = VK_SHADER_STAGE_VERTEX_BIT; - vert_shader_stage_info.module = - cg_core.vk_device_with_swapchain->vert_sprite_3d_shader_module; - vert_shader_stage_info.pName = "main"; - vert_shader_stage_info.pSpecializationInfo = nullptr; - - VkPipelineShaderStageCreateInfo frag_shader_stage_info{}; - frag_shader_stage_info.sType = - VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - frag_shader_stage_info.pNext = nullptr; - frag_shader_stage_info.flags = 0; - frag_shader_stage_info.stage = VK_SHADER_STAGE_FRAGMENT_BIT; - frag_shader_stage_info.module = - cg_core.vk_device_with_swapchain->frag_sprite_3d_shader_module; - frag_shader_stage_info.pName = "main"; - frag_shader_stage_info.pSpecializationInfo = nullptr; - - VkPipelineShaderStageCreateInfo shader_stages[] = { - vert_shader_stage_info, - frag_shader_stage_info - }; - - VkVertexInputBindingDescription vertex_input_binding{}; - vertex_input_binding.binding = 0; - vertex_input_binding.stride = sizeof(glm::vec2); - vertex_input_binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; - - std::array<VkVertexInputAttributeDescription, 1> vertex_attribute{}; - // Texture coordinate. - vertex_attribute[0].location = 0; - vertex_attribute[0].binding = 0; - vertex_attribute[0].format = VK_FORMAT_R32G32_SFLOAT; - vertex_attribute[0].offset = 0; - - VkPipelineVertexInputStateCreateInfo vertex_input_info = {}; - vertex_input_info.sType = - VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; - vertex_input_info.pNext = nullptr; - vertex_input_info.flags = 0; - vertex_input_info.vertexBindingDescriptionCount = 1; - vertex_input_info.pVertexBindingDescriptions = &vertex_input_binding; - vertex_input_info.vertexAttributeDescriptionCount = - static_cast<uint32_t>(vertex_attribute.size()); - vertex_input_info.pVertexAttributeDescriptions = vertex_attribute.data(); - - VkPipelineInputAssemblyStateCreateInfo input_assembly = {}; - input_assembly.sType = - VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; - input_assembly.pNext = nullptr; - input_assembly.flags = 0; - input_assembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; - input_assembly.primitiveRestartEnable = VK_FALSE; - - VkViewport viewport = {}; - viewport.x = 0; - viewport.y = 0; - viewport.width = cg_core.display_width; - viewport.height = cg_core.display_height; - viewport.minDepth = 0.0f; - viewport.maxDepth = 1.0f; - - VkRect2D scissor = {}; - scissor.offset = {0, 0}; - scissor.extent = {cg_core.display_width, cg_core.display_height}; - - VkPipelineViewportStateCreateInfo viewport_state = {}; - viewport_state.sType = - VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; - viewport_state.pNext = nullptr; - viewport_state.flags = 0; - viewport_state.viewportCount = 1; - viewport_state.pViewports = &viewport; - viewport_state.scissorCount = 1; - viewport_state.pScissors = &scissor; - - VkPipelineRasterizationStateCreateInfo rasterizer = {}; - rasterizer.sType = - VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; - rasterizer.pNext = nullptr; - rasterizer.flags = 0; - rasterizer.depthClampEnable = VK_FALSE; - rasterizer.rasterizerDiscardEnable = VK_FALSE; - rasterizer.polygonMode = VK_POLYGON_MODE_FILL; - rasterizer.cullMode = VK_CULL_MODE_NONE; - rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; - rasterizer.depthBiasEnable = VK_FALSE; - rasterizer.depthBiasConstantFactor = 0.0f; - rasterizer.depthBiasClamp = 0.0f; - rasterizer.depthBiasSlopeFactor = 0.0f; - rasterizer.lineWidth = 1.0f; - - VkPipelineMultisampleStateCreateInfo multisampling = {}; - multisampling.sType = - VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; - multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; - multisampling.sampleShadingEnable = VK_FALSE; - multisampling.minSampleShading = 1.0f; - multisampling.pSampleMask = nullptr; - multisampling.alphaToCoverageEnable = VK_FALSE; - multisampling.alphaToOneEnable = VK_FALSE; - - VkPipelineDepthStencilStateCreateInfo depth_stencil = {}; - depth_stencil.sType = - VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; - depth_stencil.depthTestEnable = VK_TRUE; - depth_stencil.depthWriteEnable = VK_TRUE; - depth_stencil.depthCompareOp = VK_COMPARE_OP_LESS; - depth_stencil.depthBoundsTestEnable = VK_FALSE; - depth_stencil.minDepthBounds = 0.0f; - depth_stencil.maxDepthBounds = 1.0f; - depth_stencil.stencilTestEnable = VK_FALSE; - depth_stencil.front = {}; - depth_stencil.back = {}; - - VkPipelineColorBlendAttachmentState color_blend_attachment = {}; - color_blend_attachment.blendEnable = VK_TRUE; - color_blend_attachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; - color_blend_attachment.dstColorBlendFactor = - VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; - color_blend_attachment.colorBlendOp = VK_BLEND_OP_ADD; - color_blend_attachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; - color_blend_attachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; - color_blend_attachment.alphaBlendOp = VK_BLEND_OP_ADD; - color_blend_attachment.colorWriteMask = - VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | - VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; - - VkPipelineColorBlendStateCreateInfo color_blending = {}; - color_blending.sType = - VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; - color_blending.pNext = nullptr; - color_blending.flags = 0; - color_blending.logicOpEnable = VK_FALSE; - color_blending.logicOp = VK_LOGIC_OP_COPY; - color_blending.attachmentCount = 1; - color_blending.pAttachments = &color_blend_attachment; - color_blending.blendConstants[0] = 0.0f; - color_blending.blendConstants[1] = 0.0f; - color_blending.blendConstants[2] = 0.0f; - color_blending.blendConstants[3] = 0.0f; - - std::array<VkDynamicState, 3> dynamic_states{ - VK_DYNAMIC_STATE_VIEWPORT, - VK_DYNAMIC_STATE_LINE_WIDTH, - VK_DYNAMIC_STATE_BLEND_CONSTANTS - }; - - VkPipelineDynamicStateCreateInfo dynamic_state_info = {}; - dynamic_state_info.sType = - VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; - dynamic_state_info.dynamicStateCount = dynamic_states.size(); - dynamic_state_info.pDynamicStates = dynamic_states.data(); - - VkGraphicsPipelineCreateInfo pipeline_info{}; - pipeline_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; - pipeline_info.pNext = nullptr; - pipeline_info.flags = 0; - pipeline_info.stageCount = 2; - pipeline_info.pStages = shader_stages; - pipeline_info.pVertexInputState = &vertex_input_info; - pipeline_info.pInputAssemblyState = &input_assembly; - pipeline_info.pTessellationState = nullptr; - pipeline_info.pViewportState = &viewport_state; - pipeline_info.pRasterizationState = &rasterizer; - pipeline_info.pMultisampleState = &multisampling; - pipeline_info.pDepthStencilState = &depth_stencil; - pipeline_info.pColorBlendState = &color_blending; - pipeline_info.pDynamicState = &dynamic_state_info; - pipeline_info.layout = cg_core.vk_graphics_pipeline_3d_layout->pipeline; - pipeline_info.renderPass = cg_core.vk_render_pass->pipeline_3d; - pipeline_info.subpass = 0; - pipeline_info.basePipelineHandle = VK_NULL_HANDLE; - pipeline_info.basePipelineIndex = -1; - - if(vkCreateGraphicsPipelines( - cg_core.vk_device_with_swapchain->device, VK_NULL_HANDLE, 1, - &pipeline_info, nullptr, &self->graphic_pipeline) - != VK_SUCCESS) - throw CommandError{"Failed to create graphics pipeline sprite 3d."}; -} - -void -unload_pipeline(void *obj) -{ - auto self = static_cast<VK::GraphicsPipelineSprite3D*>(obj); - - vkDestroyPipeline( - cg_core.vk_device_with_swapchain->device, self->graphic_pipeline, nullptr); -} - -const CommandChain loader{ - {&load_pipeline, &unload_pipeline} -}; - -} - -namespace VK -{ - -GraphicsPipelineSprite3D::GraphicsPipelineSprite3D() -{ - loader.execute(this); -} - -GraphicsPipelineSprite3D::~GraphicsPipelineSprite3D() -{ - loader.revert(this); -} - -void -GraphicsPipelineSprite3D::draw( - std::shared_ptr<View3D> view, const VkCommandBuffer draw_command_buffer, - const size_t current_frame, const uint32_t image_index) -{ - vkCmdBindPipeline( - draw_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - this->graphic_pipeline); - - std::vector<Sprite3DOrder> sprite_3d_order; - { // Sort sprites 3D - sprite_3d_order.reserve( - cg_core.vk_renderer->sprites_3d_to_draw[current_frame].size()); - - for(std::shared_ptr<VK::Sprite3D> sprite: - cg_core.vk_renderer->sprites_3d_to_draw[current_frame]) - sprite_3d_order.emplace_back( - sprite, glm::distance(*view->camera_position, *sprite->position)); - - std::sort(sprite_3d_order.rbegin(), sprite_3d_order.rend()); - } - - // Draw sprites - for(auto& sprite: sprite_3d_order) - { - std::array<VkDescriptorSet, 4> vk_descriptor_sets{ - cg_core.vk_light->descriptor_sets_world[image_index], - view->descriptor_sets_3d[image_index], - sprite.sprite_3d->descriptor_sets[image_index], - sprite.sprite_3d->sprite->texture->descriptor_sets[image_index]}; - VkDeviceSize offsets[]{0}; - - vkCmdBindVertexBuffers( - draw_command_buffer, 0, 1, - &sprite.sprite_3d->sprite->vertex_buffer->buffer, offsets); - vkCmdBindDescriptorSets( - draw_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - cg_core.vk_graphics_pipeline_3d_layout->pipeline, 0, - vk_descriptor_sets.size(), vk_descriptor_sets.data(), 0, nullptr); - - UDOSprite3D ubo_sprite_3d{}; - ubo_sprite_3d.position = *sprite.sprite_3d->position; - ubo_sprite_3d.size = sprite.sprite_3d->size; - sprite.sprite_3d->uniform_buffers[image_index].copy_data(&ubo_sprite_3d); - - vkCmdDraw(draw_command_buffer, Sprite::vertex_count, 1, 0, 0); - } -} - -} diff --git a/src/vk/graphics_pipeline_sprite_3d.hpp b/src/vk/graphics_pipeline_sprite_3d.hpp deleted file mode 100644 index eb7aa34..0000000 --- a/src/vk/graphics_pipeline_sprite_3d.hpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2022-2023 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. - */ - -#ifndef CANDY_GEAR_VK_GRAPHICS_PIPELINE_SPRITE_3D_H -#define CANDY_GEAR_VK_GRAPHICS_PIPELINE_SPRITE_3D_H 1 - -#include <memory> - -#include "core.hpp" -#include "command_pool.hpp" -#include "sprite_3d.hpp" -#include "view_3d.hpp" - -namespace VK -{ - -struct GraphicsPipelineSprite3D -{ - VkPipeline graphic_pipeline; - - GraphicsPipelineSprite3D(); - ~GraphicsPipelineSprite3D(); - - void - draw(std::shared_ptr<View3D> view, const VkCommandBuffer draw_command_buffer, - const size_t current_frame, const uint32_t image_index); -}; - -} - -#endif /* CANDY_GEAR_VK_GRAPHICS_PIPELINE_SPRITE_3D_H */ diff --git a/src/vk/image.cpp b/src/vk/image.cpp deleted file mode 100644 index 7d751c8..0000000 --- a/src/vk/image.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright 2022-2023 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 VK::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( - VK::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( - VK::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."}; - -} - -} diff --git a/src/vk/image.hpp b/src/vk/image.hpp deleted file mode 100644 index 4849038..0000000 --- a/src/vk/image.hpp +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2022-2023 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. - */ - -#ifndef BLUE_KITTY_VK_IMAGE_H -#define BLUE_KITTY_VK_IMAGE_H 1 - -#include <memory> -#include <string> - -#include "core.hpp" -#include "device.hpp" - -namespace VK::Image -{ - -struct Error: public std::exception -{ - Error(const std::string &m); - Error(const char &m); - - const char* - what() const noexcept; - -private: - std::string error; -}; - -void -create( - VK::Device *device, - VkImage *image, - VkDeviceMemory *image_memory, - VkFormat format, - const VkExtent3D &extent3d, - uint32_t mip_levels, - VkImageTiling image_tiling, - VkImageUsageFlags usage); - -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); - -void -create_view( - VK::Device *device, - VkImageView *image_view, - const VkImage &image, - VkFormat format, - VkImageAspectFlags image_aspect_flags); -} - -#endif /* CANDY_GEAR_VK_IMAGE_H */ diff --git a/src/vk/light.cpp b/src/vk/light.cpp deleted file mode 100644 index 5ed07ee..0000000 --- a/src/vk/light.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright 2022-2023 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 "light.hpp" - -#include <array> - -#include "../core.hpp" -#include "uniform_data_object.hpp" - -namespace -{ - -void -load_world_vert_uniform_buffer(void *obj) -{ - auto self = static_cast<VK::Light*>(obj); - - try - { - self->ub_world_vert.reserve(cg_core.vk_swapchain->images_count); - for(auto i{0}; i < cg_core.vk_swapchain->images_count; i++) - self->ub_world_vert.emplace_back( - cg_core.vk_device_with_swapchain, sizeof(VK::UDOWorld3D_Vert)); - } - catch(const std::exception& e) - { - throw CommandError{e.what()}; - } -} - -void -unload_world_vert_uniform_buffer(void *obj) -{ - auto self = static_cast<VK::Light*>(obj); - - self->ub_world_vert.clear(); -} - -void -load_world_frag_uniform_buffer(void *obj) -{ - auto self = static_cast<VK::Light*>(obj); - - try - { - self->ub_world_frag.reserve(cg_core.vk_swapchain->images_count); - for(auto i{0}; i < cg_core.vk_swapchain->images_count; i++) - self->ub_world_frag.emplace_back( - cg_core.vk_device_with_swapchain, sizeof(VK::UDOWorld3D_Frag)); - } - catch(const std::exception& e) - { - throw CommandError{e.what()}; - } -} - -void -unload_world_frag_uniform_buffer(void *obj) -{ - auto self = static_cast<VK::Light*>(obj); - - self->ub_world_frag.clear(); -} - -void -load_descriptor_pool(void *obj) -{ - auto self = static_cast<VK::Light*>(obj); - - uint32_t uniform_buffers_count = - self->ub_world_vert.size() + self->ub_world_vert.size(); - - VkDescriptorPoolSize descriptor_pool_size{}; - descriptor_pool_size.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - descriptor_pool_size.descriptorCount = uniform_buffers_count; - - VkDescriptorPoolCreateInfo pool_info{}; - pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - pool_info.pNext = nullptr; - pool_info.flags = 0; - pool_info.maxSets = uniform_buffers_count; - pool_info.poolSizeCount = 1; - pool_info.pPoolSizes = &descriptor_pool_size; - - if(vkCreateDescriptorPool( - cg_core.vk_device_with_swapchain->device, &pool_info, nullptr, - &self->descriptor_pool) != VK_SUCCESS) - throw CommandError{"Failed to create a Vulkan descriptor pool."}; -} - -void -unload_descriptor_pool(void *obj) -{ - auto self = static_cast<VK::Light*>(obj); - - vkDestroyDescriptorPool( - cg_core.vk_device_with_swapchain->device, self->descriptor_pool, - nullptr); -} - -void -load_descriptor_sets_world(void *obj) -{ - auto self = static_cast<VK::Light*>(obj); - - std::vector<VkDescriptorSetLayout> layouts( - cg_core.vk_swapchain->images_count, - cg_core.vk_descriptor_set_layout->world); - - VkDescriptorSetAllocateInfo alloc_info{}; - alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; - alloc_info.descriptorPool = self->descriptor_pool; - alloc_info.descriptorSetCount = layouts.size(); - alloc_info.pSetLayouts = layouts.data(); - - self->descriptor_sets_world.resize(layouts.size()); - if(vkAllocateDescriptorSets( - cg_core.vk_device_with_swapchain->device, &alloc_info, - self->descriptor_sets_world.data()) != VK_SUCCESS) - throw CommandError{"Failed to create Vulkan world descriptor set."}; -} - -void -load_resources_to_descriptor_sets(void *obj) -{ - auto self = static_cast<VK::Light*>(obj); - - for(auto i{0}; i < cg_core.vk_swapchain->images_count; i++) - { - VkDescriptorBufferInfo world_vert_info{}; - world_vert_info.buffer = self->ub_world_vert[i].buffer; - world_vert_info.offset = 0; - world_vert_info.range = sizeof(VK::UDOWorld3D_Vert); - - VkDescriptorBufferInfo world_frag_info{}; - world_frag_info.buffer = self->ub_world_frag[i].buffer; - world_frag_info.offset = 0; - world_frag_info.range = sizeof(VK::UDOWorld3D_Frag); - - std::array<VkWriteDescriptorSet, 2> write_descriptors{}; - write_descriptors[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - write_descriptors[0].dstSet = self->descriptor_sets_world[i]; - write_descriptors[0].dstBinding = 0; - write_descriptors[0].dstArrayElement = 0; - write_descriptors[0].descriptorCount = 1; - write_descriptors[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - write_descriptors[0].pBufferInfo = &world_vert_info; - write_descriptors[0].pImageInfo = nullptr; - write_descriptors[0].pTexelBufferView = nullptr; - - write_descriptors[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - write_descriptors[1].dstSet = self->descriptor_sets_world[i]; - write_descriptors[1].dstBinding = 1; - write_descriptors[1].dstArrayElement = 0; - write_descriptors[1].descriptorCount = 1; - write_descriptors[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - write_descriptors[1].pBufferInfo = &world_frag_info; - write_descriptors[1].pImageInfo = nullptr; - write_descriptors[1].pTexelBufferView = nullptr; - - vkUpdateDescriptorSets( - cg_core.vk_device_with_swapchain->device, write_descriptors.size(), - write_descriptors.data(), 0, nullptr); - } -} - -const CommandChain loader{ - {&load_world_vert_uniform_buffer, &unload_world_vert_uniform_buffer}, - {&load_world_frag_uniform_buffer, &unload_world_frag_uniform_buffer}, - {&load_descriptor_pool, &unload_descriptor_pool}, - // By destroying the pool the sets are also destroyed. - {&load_descriptor_sets_world, nullptr}, - {&load_resources_to_descriptor_sets, nullptr} -}; - -} - -namespace VK -{ - -Light::Light() -{ - loader.execute(this); -} - -Light::~Light() -{ - loader.revert(this); -} - -} diff --git a/src/vk/light.hpp b/src/vk/light.hpp deleted file mode 100644 index 80e44c7..0000000 --- a/src/vk/light.hpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2022-2023 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. - */ - -#ifndef CANDY_GEAR_VK_LIGHT_H -#define CANDY_GEAR_VK_LIGHT_H 1 - -#include "core.hpp" -#include "uniform_buffer.hpp" - -namespace VK -{ - -struct Light -{ - // FIXME: if this vector get resized, it will cause a segmentation fault! - std::vector<UniformBuffer> ub_world_vert; - std::vector<UniformBuffer> ub_world_frag; - - VkDescriptorPool descriptor_pool; - std::vector<VkDescriptorSet> descriptor_sets_world; - - Light(); - ~Light(); -}; - -} - -#endif /* CANDY_GEAR_VK_LIGHT_H */ diff --git a/src/vk/qoi.cpp b/src/vk/qoi.cpp deleted file mode 100644 index bc0caab..0000000 --- a/src/vk/qoi.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright 2022-2023 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 "qoi.hpp" - -#include <array> -#include <fstream> - -#include "../binary_reader.hpp" - -namespace -{ - -const char MAGIC[]{"qoif"}; -const int HEADER_SIZE{14}; -const uint8_t PADDING[8]{0,0,0,0,0,0,0,1}; -const unsigned int PIXELS_MAX{400000000}; - -const int OP_INDEX{0b00000000}; -const int OP_DIFF {0b01000000}; -const int OP_LUMA {0b10000000}; -const int OP_RUN {0b11000000}; -const int OP_RGB {0b11111110}; -const int OP_RGBA {0b11111111}; - -const int MASK_2_BITS{0b11000000}; - -struct RGBA -{ - uint8_t red, green, blue, alpha; - - RGBA(); - RGBA(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha); -}; - -RGBA::RGBA(): - red{0}, - green{0}, - blue{0}, - alpha{0} -{ -} - -RGBA::RGBA(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha): - red{red}, - green{green}, - blue{blue}, - alpha{alpha} -{ -} - -struct Pixel -{ - union - { - RGBA colors; - uint32_t value; - }; - - Pixel(); - Pixel(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha); -}; - -Pixel::Pixel(): - colors{} -{ -} - -Pixel::Pixel(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha): - colors(red, green, blue, alpha) -{ -} - -inline int -color_hash(const RGBA &colors) -{ - return colors.red*3 + colors.green*5 + colors.blue*7 + colors.alpha*11; -} - -} - -namespace VK::QOI -{ - -Image::Image(const char *file_path, uint8_t channels): - channels{channels} -{ - if(this->channels != 0 && this->channels != 3 && this->channels != 4) - { - throw std::invalid_argument{"invalid number of channels"}; - } - - BinaryReader input{file_path}; - if(input.size() < HEADER_SIZE + (int)sizeof(PADDING)) - { - throw std::runtime_error{"invalid QOI file"}; - } - - input.read_chars(this->header.magic, 4); - this->header.width = input.read_ui32(); - this->header.height = input.read_ui32(); - this->header.channels = input.read_ui8(); - this->header.colorspace = input.read_ui8(); - - if(this->header.width == 0 || this->header.height == 0 || - this->header.channels < 3 || this->header.channels > 4 || - this->header.colorspace > 1 || - this->header.height >= PIXELS_MAX / this->header.width) - { - throw std::runtime_error{"QOI file have an invalid header"}; - } - - if(this->channels == 0) this->channels = this->header.channels; - - uint32_t num_pixels{this->header.width * this->header.height}; - this->pixels_len = num_pixels * this->channels; - this->pixels = new uint8_t[this->pixels_len]; - - std::array<Pixel, 64> index; - Pixel pixel(0, 0, 0, 255); - int chunks_len = input.size() - (int)sizeof(PADDING); - - /* - This algorithm is based on the original implementation that is in GitHub: - https://github.com/phoboslab/qoi - - For information about the QOI image format, see: https://qoiformat.org/ - */ - int pixel_p{0}; - int run{0}; - for(uint32_t decoded_pixel{0}; decoded_pixel < num_pixels; decoded_pixel++) - { - if(run > 0) - { - run--; - } - else if(input.pointer() < chunks_len) - { - int b1 = input.read_ui8(); - - if (b1 == OP_RGB) - { - pixel.colors.red = input.read_ui8(); - pixel.colors.green = input.read_ui8(); - pixel.colors.blue = input.read_ui8(); - } - else if (b1 == OP_RGBA) - { - pixel.colors.red = input.read_ui8(); - pixel.colors.green = input.read_ui8(); - pixel.colors.blue = input.read_ui8(); - pixel.colors.alpha = input.read_ui8(); - } - else if ((b1 & MASK_2_BITS) == OP_INDEX) - { - pixel = index[b1]; - } - else if ((b1 & MASK_2_BITS) == OP_DIFF) - { - pixel.colors.red += ((b1 >> 4) & 0x03) - 2; - pixel.colors.green += ((b1 >> 2) & 0x03) - 2; - pixel.colors.blue += (b1 & 0x03) - 2; - } - else if ((b1 & MASK_2_BITS) == OP_LUMA) - { - int b2 = input.read_ui8(); - int vg = (b1 & 0x3f) - 32; - pixel.colors.red += vg - 8 + ((b2 >> 4) & 0x0f); - pixel.colors.green += vg; - pixel.colors.blue += vg - 8 + (b2 & 0x0f); - } - else if ((b1 & MASK_2_BITS) == OP_RUN) - { - run = (b1 & 0x3f); - } - - index[color_hash(pixel.colors) % 64] = pixel; - } - - this->pixels[pixel_p++] = pixel.colors.red; - this->pixels[pixel_p++] = pixel.colors.green; - this->pixels[pixel_p++] = pixel.colors.blue; - if(this->channels == 4) this->pixels[pixel_p++] = pixel.colors.alpha; - } -} - -Image::~Image() -{ - delete[] this->pixels; -} - -} diff --git a/src/vk/qoi.hpp b/src/vk/qoi.hpp deleted file mode 100644 index 8a8688f..0000000 --- a/src/vk/qoi.hpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2022-2023 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 <cstdint> - -namespace VK::QOI -{ - struct Header - { - char magic[4]; - uint32_t width; - uint32_t height; - uint8_t channels; - uint8_t colorspace; - }; - - struct Image - { - Header header; - uint32_t pixels_len; - uint8_t channels; - uint8_t *pixels; - - Image(const char *file_path, uint8_t channels); - ~Image(); - }; - -} diff --git a/src/vk/queue.cpp b/src/vk/queue.cpp deleted file mode 100644 index deb59ba..0000000 --- a/src/vk/queue.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2022 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 "queue.hpp" - -#include "queue_family.hpp" - -namespace VK -{ - -Queue::Queue( - VK::QueueFamily *queue_family, VkQueue queue, int queue_index): - queue_family{queue_family}, - queue{queue}, - queue_index{queue_index} -{ - this->queue_family->queue_states[this->queue_index].busy = true; -} - -Queue::Queue(Queue &&that): - queue{that.queue}, - queue_family{that.queue_family}, - queue_index{that.queue_index} -{ - that.queue_family = nullptr; -} - -Queue& Queue::operator=(Queue &&that) -{ - this->queue = that.queue; - this->queue_family = that.queue_family; - this->queue_index = that.queue_index; - - that.queue_family = nullptr; - - return *this; -} - -Queue::~Queue() -{ - if(this->queue_family) - { - std::unique_lock<std::mutex> lock{this->queue_family->queue_mutex}; - this->queue_family->queue_states[this->queue_index].busy = false; - } -} - -} diff --git a/src/vk/queue.hpp b/src/vk/queue.hpp deleted file mode 100644 index 955daa5..0000000 --- a/src/vk/queue.hpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2022 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. - */ - -#ifndef CANDY_GEAR_VK_QUEUE_H -#define CANDY_GEAR_VK_QUEUE_H 1 - -#include "core.hpp" - -namespace VK -{ -class QueueFamily; - -struct Queue -{ - friend class VK::QueueFamily; - - Queue(const Queue &t) = delete; - Queue& operator=(const Queue &t) = delete; - - VkQueue queue; - - template<typename T> - void submit_one_time_command( - const VkCommandBuffer vk_command_buffer, T commands); - - Queue(Queue &&that); - Queue& operator=(Queue &&that); - - ~Queue(); - -private: - VK::QueueFamily *queue_family; - int queue_index; - - Queue(VK::QueueFamily *queue_family, VkQueue queue, int queue_index); -}; - -template<typename T> void -Queue::submit_one_time_command( - const VkCommandBuffer vk_command_buffer, T commands) -{ - VkCommandBufferBeginInfo buffer_begin_info{}; - buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - buffer_begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - - vkBeginCommandBuffer(vk_command_buffer, &buffer_begin_info); - - commands(); - - vkEndCommandBuffer(vk_command_buffer); - - VkSubmitInfo submit_info{}; - submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submit_info.pNext = nullptr; - submit_info.waitSemaphoreCount = 0; - submit_info.pWaitSemaphores = nullptr; - submit_info.pWaitDstStageMask = nullptr; - submit_info.commandBufferCount = 1; - submit_info.pCommandBuffers = &vk_command_buffer; - submit_info.signalSemaphoreCount = 0; - submit_info.pSignalSemaphores = nullptr; - - vkQueueSubmit(this->queue, 1, &submit_info, VK_NULL_HANDLE); - vkQueueWaitIdle(this->queue); -} - -} - -#endif /* CANDY_GEAR_VK_QUEUE_H */ diff --git a/src/vk/queue_family.cpp b/src/vk/queue_family.cpp deleted file mode 100644 index d917c13..0000000 --- a/src/vk/queue_family.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2022 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 "queue_family.hpp" - -#ifdef DEBUG -#include <sstream> -#endif - -#include "../core.hpp" - -namespace VK -{ - -QueueFamily::QueueFamily( - VK::Device *device, uint32_t family_index, - const VkQueueFamilyProperties &queue_family_properties): - queue_mutex{} -{ - -#ifdef DEBUG - std::stringstream message{}; - message << "Queue quantity: " << queue_family_properties.queueCount << - std::endl; - message << "Graphics: " << - (queue_family_properties.queueFlags & VK_QUEUE_GRAPHICS_BIT ? - "true" : "false") << std::endl; - message << "Compute: " << - (queue_family_properties.queueFlags & VK_QUEUE_COMPUTE_BIT ? - "true" : "false") << std::endl; - message << "Transfer: " << - (queue_family_properties.queueFlags & VK_QUEUE_TRANSFER_BIT ? - "true" : "false") << std::endl; - message << "Sparse Binding: " << - (queue_family_properties.queueFlags & VK_QUEUE_SPARSE_BINDING_BIT ? - "true" : "false") << std::endl; - cg_core.log.message(Log::Level::Trace, message.str()); -#endif - - this->device = device; - this->family_index = family_index; - this->family_properties = queue_family_properties; - - // Create queues - { - auto queue_count = this->family_properties.queueCount; - this->queue_states.resize(queue_count); - - for(auto i{0}; i < queue_count; i++) - { - vkGetDeviceQueue(device->device, this->family_index, i, - &this->queue_states[i].queue); - if(this->queue_states[i].queue == VK_NULL_HANDLE) - throw std::runtime_error("Failed to get Vulkan queue."); - } - } -} - -Queue -QueueFamily::get_queue() -{ - std::unique_lock<std::mutex> lock{this->queue_mutex}; - - for(auto i{0}; i < this->queue_states.size(); i++) - if(!this->queue_states[i].busy) - return Queue(this, this->queue_states[i].queue, i); - - throw std::length_error("No free queues found."); -} - -} diff --git a/src/vk/queue_family.hpp b/src/vk/queue_family.hpp deleted file mode 100644 index 83efc00..0000000 --- a/src/vk/queue_family.hpp +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2022 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. - */ - -#ifndef CANDY_GEAR_VK_QUEUE_FAMILY_H -#define CANDY_GEAR_VK_QUEUE_FAMILY_H 1 - -#include <mutex> -#include <vector> - -#include "core.hpp" -#include "queue.hpp" - -namespace VK -{ -class Device; - -struct QueueState -{ - VkQueue queue; - bool busy; -}; - -class QueueFamily -{ - friend class Queue; - - std::mutex queue_mutex; - std::vector<QueueState> queue_states; - -public: - VK::Device *device; - - uint32_t family_index; - VkQueueFamilyProperties family_properties; - - QueueFamily(VK::Device *device, uint32_t family_index, - const VkQueueFamilyProperties &queue_family_properties); - - Queue - get_queue(); -}; - -} - -#endif /* CANDY_GEAR_VK_QUEUE_FAMILY_H */ diff --git a/src/vk/rectangle.cpp b/src/vk/rectangle.cpp deleted file mode 100644 index dc18c45..0000000 --- a/src/vk/rectangle.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2022 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 "rectangle.hpp" - -namespace VK -{ - -const int Rectangle::VertexCount{4}; - -Rectangle::Rectangle(glm::vec4 position, glm::vec3 color): - position{position}, - color{color} -{ -} - -} diff --git a/src/vk/rectangle.hpp b/src/vk/rectangle.hpp deleted file mode 100644 index faee927..0000000 --- a/src/vk/rectangle.hpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2022 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. - */ - -#ifndef CANDY_GEAR_VK_RECTANGLE_H -#define CANDY_GEAR_VK_RECTANGLE_H 1 - -#include <vector> - -#include "core.hpp" -#include "destination_buffer.hpp" -#include "queue_family.hpp" -#include "uniform_buffer.hpp" - -namespace VK -{ - -struct Rectangle -{ - static const int VertexCount; - - glm::vec4 position; - glm::vec3 color; - - Rectangle(glm::vec4 position, glm::vec3 color); -}; - -} - -#endif /* CANDY_GEAR_VK_RECTANGLE_H */ diff --git a/src/vk/render_pass.cpp b/src/vk/render_pass.cpp deleted file mode 100644 index 799cde4..0000000 --- a/src/vk/render_pass.cpp +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright 2022-2023 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 "render_pass.hpp" - -#include <array> - -#include "../core.hpp" - -namespace -{ - -void -load_3d(void *obj) -{ - auto self = static_cast<VK::RenderPass*>(obj); - - std::array<VkAttachmentDescription, 2> attachments{}; - // Color attachment. - attachments[0].flags = 0; - attachments[0].format = cg_core.vk_swapchain->image_format; - attachments[0].samples = VK_SAMPLE_COUNT_1_BIT; - attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachments[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - attachments[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - // Depth attachment. - attachments[1].flags = 0; - attachments[1].format = VK_FORMAT_D32_SFLOAT; - attachments[1].samples = VK_SAMPLE_COUNT_1_BIT; - attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachments[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - attachments[1].finalLayout = - VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - - VkAttachmentReference color_attachment_ref{}; - color_attachment_ref.attachment = 0; - color_attachment_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - VkAttachmentReference depth_attachment_ref{}; - depth_attachment_ref.attachment = 1; - depth_attachment_ref.layout = - VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - - VkSubpassDescription subpass = {}; - subpass.flags = 0; - subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.inputAttachmentCount = 0; - subpass.pInputAttachments = nullptr; - subpass.colorAttachmentCount = 1; - subpass.pColorAttachments = &color_attachment_ref; - subpass.pResolveAttachments = nullptr; - subpass.pDepthStencilAttachment = &depth_attachment_ref; - subpass.preserveAttachmentCount = 0; - subpass.pPreserveAttachments = nullptr; - - VkSubpassDependency dependency = {}; - dependency.srcSubpass = VK_SUBPASS_EXTERNAL; - dependency.dstSubpass = 0; - dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | - VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; - dependency.srcAccessMask = 0; - dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | - VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; - dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - - VkRenderPassCreateInfo render_pass_info{}; - render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - render_pass_info.pNext = nullptr; - render_pass_info.flags = 0; - render_pass_info.attachmentCount = attachments.size(); - render_pass_info.pAttachments = attachments.data(); - render_pass_info.subpassCount = 1; - render_pass_info.pSubpasses = &subpass; - render_pass_info.dependencyCount = 1; - render_pass_info.pDependencies = &dependency; - - if(vkCreateRenderPass( - cg_core.vk_device_with_swapchain->device, &render_pass_info, nullptr, - &self->pipeline_3d) != VK_SUCCESS) - throw CommandError{"Failed to create Vulkan Render Pass 3D."}; -} - -void -unload_3d(void *obj) -{ - auto self = static_cast<VK::RenderPass*>(obj); - - vkDestroyRenderPass( - cg_core.vk_device_with_swapchain->device, self->pipeline_3d, nullptr); -} - -void -load_2d(void *obj) -{ - auto self = static_cast<VK::RenderPass*>(obj); - - std::array<VkAttachmentDescription, 1> attachments{}; - // Color attachment. - attachments[0].flags = 0; - attachments[0].format = cg_core.vk_swapchain->image_format; - attachments[0].samples = VK_SAMPLE_COUNT_1_BIT; - attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachments[0].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - attachments[0].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; - - VkAttachmentReference color_attachment_ref{}; - color_attachment_ref.attachment = 0; - color_attachment_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - VkSubpassDescription subpass{}; - subpass.flags = 0; - subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.inputAttachmentCount = 0; - subpass.pInputAttachments = nullptr; - subpass.colorAttachmentCount = 1; - subpass.pColorAttachments = &color_attachment_ref; - subpass.pResolveAttachments = nullptr; - subpass.pDepthStencilAttachment = nullptr; - subpass.preserveAttachmentCount = 0; - subpass.pPreserveAttachments = nullptr; - - VkSubpassDependency dependency{}; - dependency.srcSubpass = VK_SUBPASS_EXTERNAL; - dependency.dstSubpass = 0; - dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | - VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; - dependency.srcAccessMask = 0; - dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | - VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; - dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - - VkRenderPassCreateInfo render_pass_info{}; - render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - render_pass_info.pNext = nullptr; - render_pass_info.flags = 0; - render_pass_info.attachmentCount = attachments.size(); - render_pass_info.pAttachments = attachments.data(); - render_pass_info.subpassCount = 1; - render_pass_info.pSubpasses = &subpass; - render_pass_info.dependencyCount = 1; - render_pass_info.pDependencies = &dependency; - - if(vkCreateRenderPass( - cg_core.vk_device_with_swapchain->device, &render_pass_info, - nullptr, &self->pipeline_2d) != VK_SUCCESS) - throw CommandError{"Failed to create Vulkan Render Pass 2D."}; -} - -void -unload_2d(void *obj) -{ - auto self = static_cast<VK::RenderPass*>(obj); - - vkDestroyRenderPass( - cg_core.vk_device_with_swapchain->device, self->pipeline_2d, nullptr); -} - -const CommandChain loader{ - {&load_3d, &unload_3d}, - {&load_2d, &unload_2d} -}; - -} - -namespace VK -{ - -RenderPass::RenderPass() -{ - loader.execute(this); -} - -RenderPass::~RenderPass() -{ - loader.revert(this); -} - -} diff --git a/src/vk/render_pass.hpp b/src/vk/render_pass.hpp deleted file mode 100644 index 2f96062..0000000 --- a/src/vk/render_pass.hpp +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2022-2023 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. - */ - -#ifndef CANDY_GEAR_VK_RENDER_PASS_H -#define CANDY_GEAR_VK_RENDER_PASS_H 1 - -#include "core.hpp" - -namespace VK -{ - -struct RenderPass -{ - VkRenderPass pipeline_2d; - VkRenderPass pipeline_3d; - - RenderPass(); - ~RenderPass(); -}; - -} - -#endif /* CANDY_GEAR_VK_RENDER_PASS_H */ diff --git a/src/vk/renderer.cpp b/src/vk/renderer.cpp deleted file mode 100644 index 0f7f804..0000000 --- a/src/vk/renderer.cpp +++ /dev/null @@ -1,413 +0,0 @@ -/* - * Copyright 2022-2023 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 "renderer.hpp" - -#include <array> - -#include "../core.hpp" -#include "uniform_data_object.hpp" - -namespace -{ - -void -load_descriptor_pool(void *obj) -{ - auto self = static_cast<VK::Renderer*>(obj); - - uint32_t uniform_buffer_count = 0; - for(auto &view : self->views_3d) - uniform_buffer_count += (view->ub_3d.size() + view->ub_2d.size()); - for(auto &view : self->views_2d) - uniform_buffer_count += (view->ub_2d.size()); - - VkDescriptorPoolSize descriptor_pool_size{}; - descriptor_pool_size.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - descriptor_pool_size.descriptorCount = uniform_buffer_count; - - VkDescriptorPoolCreateInfo pool_info{}; - pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - pool_info.pNext = nullptr; - pool_info.flags = 0; - pool_info.maxSets = uniform_buffer_count; - pool_info.poolSizeCount = 1; - pool_info.pPoolSizes = &descriptor_pool_size; - - if(vkCreateDescriptorPool( - cg_core.vk_device_with_swapchain->device, &pool_info, nullptr, - &self->descriptor_pool) != VK_SUCCESS) - throw CommandError{"Failed to create a Vulkan descriptor pool."}; - - for(auto &view : self->views_3d) - view->load_descriptor_sets(self->descriptor_pool); - for(auto &view : self->views_2d) - view->load_descriptor_sets(self->descriptor_pool); -} - -void -unload_descriptor_pool(void *obj) -{ - auto self = static_cast<VK::Renderer*>(obj); - - for(auto &view : self->views_3d) view->unload_descriptor_sets(); - for(auto &view : self->views_2d) view->unload_descriptor_sets(); - - vkDestroyDescriptorPool( - cg_core.vk_device_with_swapchain->device, self->descriptor_pool, - nullptr); -} - -void -load_queue_family(void *obj) -{ - auto self = static_cast<VK::Renderer*>(obj); - - self->queue_family = - cg_core.vk_device_with_swapchain->get_queue_family_with_presentation(); -} - -void -load_command_pool(void *obj) -{ - auto self = static_cast<VK::Renderer*>(obj); - - VkCommandPoolCreateInfo create_info{}; - create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; - create_info.pNext = nullptr; - create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; - create_info.queueFamilyIndex = self->queue_family->family_index; - - vkCreateCommandPool( - self->queue_family->device->device, &create_info, nullptr, - &self->command_pool); -} - -void -unload_command_pool(void *obj) -{ - auto self = static_cast<VK::Renderer*>(obj); - - vkWaitForFences(cg_core.vk_device_with_swapchain->device, - VK::Swapchain::max_frames_in_flight, - cg_core.vk_swapchain->in_flight_fences.data(), VK_TRUE, - std::numeric_limits<uint64_t>::max()); - vkDestroyCommandPool( - self->queue_family->device->device, self->command_pool, nullptr); -} - -void -load_draw_command_buffer(void *obj) -{ - auto self = static_cast<VK::Renderer*>(obj); - - // FIXME: 3 is a magical number, triple buffering. - self->draw_command_buffers.resize(3); - - VkCommandBufferAllocateInfo allocate_info{}; - allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; - allocate_info.pNext = nullptr; - allocate_info.commandPool = self->command_pool; - allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; - allocate_info.commandBufferCount = self->draw_command_buffers.size(); - - if(vkAllocateCommandBuffers( - self->queue_family->device->device, &allocate_info, - self->draw_command_buffers.data()) != VK_SUCCESS) - throw CommandError{"Vulkan draw command buffers could not be allocated."}; -} - -const CommandChain loader{ - {&load_descriptor_pool, &unload_descriptor_pool}, - {&load_queue_family, nullptr}, - {&load_command_pool, &unload_command_pool}, - {&load_draw_command_buffer, nullptr} -}; - -} - -namespace VK -{ - -Renderer::Renderer(std::vector<std::shared_ptr<View2D>> views_2d, - std::vector<std::shared_ptr<View3D>> views_3d): - skeletal_models_to_draw{cg_core.vk_swapchain->images_count}, - static_models_to_draw{cg_core.vk_swapchain->images_count}, - sprites_3d_to_draw{cg_core.vk_swapchain->images_count}, - views_2d{views_2d}, - views_3d{views_3d} -{ - loader.execute(this); -} - -Renderer::Renderer(std::initializer_list<std::shared_ptr<View2D>> views_2d, - std::initializer_list<std::shared_ptr<View3D>> views_3d): - Renderer(std::vector(views_2d), std::vector(views_3d)) -{ -} - -Renderer::~Renderer() -{ - loader.revert(this); -} - -void -Renderer::draw() -{ - auto fence_status = vkGetFenceStatus( - cg_core.vk_device_with_swapchain->device, - cg_core.vk_swapchain->in_flight_fences[ - cg_core.vk_swapchain->current_frame]); - - if(fence_status == VK_SUCCESS) - { - auto next_frame = cg_core.vk_swapchain->current_frame + 1; - if(next_frame == Swapchain::max_frames_in_flight) next_frame = 0; - - vkResetFences(cg_core.vk_device_with_swapchain->device, 1, - &cg_core.vk_swapchain->in_flight_fences[ - cg_core.vk_swapchain->current_frame]); - - uint32_t image_index; - vkAcquireNextImageKHR( - cg_core.vk_device_with_swapchain->device, - cg_core.vk_swapchain->swapchain, std::numeric_limits<uint64_t>::max(), - cg_core.vk_swapchain->image_available_semaphores[ - cg_core.vk_swapchain->current_frame], VK_NULL_HANDLE, &image_index); - - VkCommandBuffer draw_command_buffer = - this->draw_command_buffers[cg_core.vk_swapchain->current_frame]; - vkResetCommandBuffer(draw_command_buffer, 0); - - // Begin command buffer. - { - VkCommandBufferBeginInfo begin_info{}; - begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - begin_info.flags = 0; - begin_info.pInheritanceInfo = nullptr; - if (vkBeginCommandBuffer(draw_command_buffer, &begin_info) != VK_SUCCESS) - throw std::runtime_error{"Failed to beggin draw command buffer."}; - } - - // 3D drawing. - { - // Dark gray blue. - std::array<VkClearValue, 2> clear_values{}; - clear_values[0].color = {0.12f, 0.12f, 0.18f, 1.0f}; - clear_values[1].depthStencil = {1.0f, 0}; - - { // Update world uniform buffer - UDOWorld3D_Vert ubo_world_3d_vert{}; - ubo_world_3d_vert.ambient_light_color = - glm::vec4{0.25, 0.25, 0.25, 1.0}; - cg_core.vk_light->ub_world_vert[image_index].copy_data( - &ubo_world_3d_vert); - - UDOWorld3D_Frag ubo_world_3d_frag{}; - ubo_world_3d_frag.directional_light_direction = - glm::vec3{-0.57735, 0.57735, -0.57735}; - ubo_world_3d_frag.directional_light_color = - glm::vec4{0.8, 0.8, 0.8, 1.0}; - cg_core.vk_light->ub_world_frag[image_index].copy_data( - &ubo_world_3d_frag); - } - - VkRenderPassBeginInfo render_pass_begin{}; - render_pass_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - render_pass_begin.pNext = nullptr; - render_pass_begin.renderPass = cg_core.vk_render_pass->pipeline_3d; - render_pass_begin.framebuffer = - cg_core.vk_framebuffer->pipeline_3d[image_index]; - render_pass_begin.renderArea.offset = {0, 0}; - render_pass_begin.renderArea.extent = { - static_cast<uint32_t>(cg_core.display_width), - static_cast<uint32_t>(cg_core.display_height)}; - render_pass_begin.clearValueCount = clear_values.size(); - render_pass_begin.pClearValues = clear_values.data(); - - vkCmdBeginRenderPass( - draw_command_buffer, &render_pass_begin, VK_SUBPASS_CONTENTS_INLINE); - } - - for(auto &view: this->views_3d) - { - { // Set viewport - VkViewport vk_viewport{}; - vk_viewport.x = view->region.x; - vk_viewport.y = view->region.y; - vk_viewport.width = view->region.z; - vk_viewport.height = view->region.w; - vk_viewport.minDepth = 0.0f; - vk_viewport.maxDepth = 1.0f; - vkCmdSetViewport(draw_command_buffer, 0, 1, &vk_viewport); - - VkRect2D vk_scissor{}; - vk_scissor.offset.x = static_cast<int32_t>(view->region.x); - vk_scissor.offset.y = static_cast<int32_t>(view->region.y); - vk_scissor.extent.width = static_cast<uint32_t>(view->region.z); - vk_scissor.extent.height = static_cast<uint32_t>(view->region.w); - vkCmdSetScissor(draw_command_buffer, 0, 1, &vk_scissor); - } - - cg_core.vk_graphics_pipeline_3d->draw( - view, draw_command_buffer, cg_core.vk_swapchain->current_frame, - image_index); - - cg_core.vk_graphics_pipeline_sprite_3d->draw( - view, draw_command_buffer, cg_core.vk_swapchain->current_frame, - image_index); - - cg_core.vk_graphics_pipeline_3d_skeletal->draw( - view, draw_command_buffer, cg_core.vk_swapchain->current_frame, - image_index); - - { // Update view uniform buffers - VK::UDOView3D ubo_view_3d{}; - - // View matrix. - glm::mat4 translation_matrix{1.0f}; - translation_matrix = glm::translate( - translation_matrix, *view->camera_position); - glm::mat4 rotation_matrix{glm::toMat4(*view->camera_orientation)}; - ubo_view_3d.view = glm::inverse(translation_matrix * rotation_matrix); - - // Projection matrix. - ubo_view_3d.proj = glm::perspective( - glm::radians(view->field_of_view), - view->region.z / view->region.w, - 0.1f, 100.0f); - - view->ub_3d[image_index].copy_data(&ubo_view_3d); - } - } - - vkCmdEndRenderPass(draw_command_buffer); - - { // 2D render pass - VkRenderPassBeginInfo render_pass_begin{}; - render_pass_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - render_pass_begin.pNext = nullptr; - render_pass_begin.renderPass = cg_core.vk_render_pass->pipeline_2d; - render_pass_begin.framebuffer = - cg_core.vk_framebuffer->pipeline_2d[image_index]; - render_pass_begin.renderArea.offset = {0, 0}; - render_pass_begin.renderArea.extent = { - static_cast<uint32_t>(cg_core.display_width), - static_cast<uint32_t>(cg_core.display_height)}; - render_pass_begin.clearValueCount = 0; - render_pass_begin.pClearValues = nullptr; - - vkCmdBeginRenderPass( - draw_command_buffer, &render_pass_begin, VK_SUBPASS_CONTENTS_INLINE); - - } - - { // 2D solid drawing - for(auto &view: this->views_2d) - cg_core.vk_graphics_pipeline_2d_solid->draw( - view, draw_command_buffer, cg_core.vk_swapchain->current_frame, - next_frame, image_index); - - for(auto &view: this->views_3d) - cg_core.vk_graphics_pipeline_2d_solid->draw( - view, draw_command_buffer, cg_core.vk_swapchain->current_frame, - next_frame, image_index); - } - - { // 2D wired drawing - for(auto &view: this->views_2d) - cg_core.vk_graphics_pipeline_2d_wired->draw( - view, draw_command_buffer, cg_core.vk_swapchain->current_frame, - next_frame, image_index); - - for(auto &view: this->views_3d) - cg_core.vk_graphics_pipeline_2d_wired->draw( - view, draw_command_buffer, cg_core.vk_swapchain->current_frame, - next_frame, image_index); - } - - vkCmdEndRenderPass(draw_command_buffer); - - // End command buffer. - if(vkEndCommandBuffer(draw_command_buffer) != VK_SUCCESS) - throw std::runtime_error{"Failed to end draw command buffer."}; - - // Submit drawing command. - { - auto queue{this->queue_family->get_queue()}; - - VkSemaphore wait_semaphores[]{ - cg_core.vk_swapchain->image_available_semaphores[ - cg_core.vk_swapchain->current_frame]}; - VkPipelineStageFlags wait_stages[] = - {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; - VkSemaphore signal_semaphores[]{ - cg_core.vk_swapchain->render_finished_semaphores[ - cg_core.vk_swapchain->current_frame]}; - - VkSubmitInfo submit_info{}; - submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submit_info.pNext = nullptr; - submit_info.waitSemaphoreCount = 1; - submit_info.pWaitSemaphores = wait_semaphores; - submit_info.pWaitDstStageMask = wait_stages; - submit_info.commandBufferCount = 1; - submit_info.pCommandBuffers = &draw_command_buffer; - submit_info.signalSemaphoreCount = 1; - submit_info.pSignalSemaphores = signal_semaphores; - - if(vkQueueSubmit( - queue.queue, 1, &submit_info, cg_core.vk_swapchain->in_flight_fences[ - cg_core.vk_swapchain->current_frame]) != VK_SUCCESS) - throw std::runtime_error{"Failed to submit draw command buffer."}; - - VkSwapchainKHR swap_chains[]{cg_core.vk_swapchain->swapchain}; - - VkPresentInfoKHR present_info{}; - present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; - present_info.pNext = nullptr; - present_info.waitSemaphoreCount = 1; - present_info.pWaitSemaphores = signal_semaphores; - present_info.swapchainCount = 1; - present_info.pSwapchains = swap_chains; - present_info.pImageIndices = &image_index; - present_info.pResults = nullptr; - - vkQueuePresentKHR(queue.queue, &present_info); - } - - // Prepare for the next frame. - { - this->skeletal_models_to_draw[next_frame].clear(); - this->static_models_to_draw[next_frame].clear(); - this->sprites_3d_to_draw[next_frame].clear(); - cg_core.vk_swapchain->current_frame = next_frame; - } - } - else - { - // Clear images for the current frame because we are skipping this frame. - this->skeletal_models_to_draw[cg_core.vk_swapchain->current_frame].clear(); - this->static_models_to_draw[cg_core.vk_swapchain->current_frame].clear(); - this->sprites_3d_to_draw[cg_core.vk_swapchain->current_frame].clear(); - for(auto &view: this->views_2d) - view->sprites_to_draw[cg_core.vk_swapchain->current_frame].clear(); - for(auto &view: this->views_3d) - view->sprites_to_draw[cg_core.vk_swapchain->current_frame].clear(); - } -} - -} diff --git a/src/vk/renderer.hpp b/src/vk/renderer.hpp deleted file mode 100644 index 96d25ba..0000000 --- a/src/vk/renderer.hpp +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2022-2023 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. - */ - -#ifndef CANDY_GEAR_VK_RENDERER_H -#define CANDY_GEAR_VK_RENDERER_H 1 - -#include <initializer_list> -#include <memory> -#include <vector> - -#include "core.hpp" -#include "skeletal_mesh.hpp" -#include "skeletal_model.hpp" -#include "sprite_3d.hpp" -#include "static_mesh.hpp" -#include "static_model.hpp" -#include "queue_family.hpp" -#include "view_2d.hpp" -#include "view_3d.hpp" - -namespace VK -{ - -struct Renderer -{ - std::vector< - std::unordered_map< - std::shared_ptr<SkeletalMesh>, - std::vector<std::shared_ptr<SkeletalModel>>>> - skeletal_models_to_draw; - - std::vector< - std::unordered_map< - std::shared_ptr<StaticMesh>, - std::vector<std::shared_ptr<StaticModel>>>> - static_models_to_draw; - - std::vector<std::vector<std::shared_ptr<Sprite3D>>> sprites_3d_to_draw; - - VkDescriptorPool descriptor_pool; - std::vector<std::shared_ptr<View2D>> views_2d; - std::vector<std::shared_ptr<View3D>> views_3d; - QueueFamily *queue_family; - VkCommandPool command_pool; - std::vector<VkCommandBuffer> draw_command_buffers; - - Renderer(std::vector<std::shared_ptr<View2D>> views_2d, - std::vector<std::shared_ptr<View3D>> views_3d); - Renderer(std::initializer_list<std::shared_ptr<View2D>> views_2d, - std::initializer_list<std::shared_ptr<View3D>> views_3d); - ~Renderer(); - - void - draw(); -}; - -} - -#endif /* CANDY_GEAR_VK_RENDERER_H */ diff --git a/src/vk/skeletal_mesh.cpp b/src/vk/skeletal_mesh.cpp deleted file mode 100644 index b65d27d..0000000 --- a/src/vk/skeletal_mesh.cpp +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright 2022-2023 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 "skeletal_mesh.hpp" - -#include "../binary_reader.hpp" -#include "../command.hpp" -#include "../core.hpp" -#include "skeletal_mesh_vertex.hpp" - -namespace -{ - -// Data that is only needed for the command chain but not for the SkeletalMesh -// goes here. -struct MeshBuilder -{ - std::string mesh_path; - VK::SkeletalMesh *mesh; - - MeshBuilder(VK::SkeletalMesh *m, std::string mp); - MeshBuilder(VK::SkeletalMesh *m, const char* mp); -}; - -MeshBuilder::MeshBuilder(VK::SkeletalMesh *m, std::string mp): - mesh{m}, - mesh_path{mp} -{ -} - -MeshBuilder::MeshBuilder(VK::SkeletalMesh *m, const char *mp): - MeshBuilder{m, std::string(mp)} -{ -} - -void -load_mesh(void *obj) -{ - auto self = static_cast<MeshBuilder*>(obj); - - BinaryReader input{self->mesh_path}; - - self->mesh->queue_family = - cg_core.vk_device_with_swapchain->get_queue_family_with_graphics(); - - { // Load vertexes. - auto vertex_count{input.read_ui32()}; - std::vector<VK::SkeletalMeshVertex> vertexes{vertex_count}; - - for(auto i{0}; i < vertex_count; i++) - { - vertexes[i].position = input.read_vec3(); - vertexes[i].normal = input.read_vec3(); - vertexes[i].texture_coord = input.read_vec2(); - - for(auto ii{0}; ii < VK::SKELETAL_MESH_MAX_NUM_OF_INFLUENCING_BONES; - ii++) - vertexes[i].bone_ids[ii] = input.read_ui32(); - - for(auto ii{0}; ii < VK::SKELETAL_MESH_MAX_NUM_OF_INFLUENCING_BONES; - ii++) - vertexes[i].bone_weights[ii] = input.read_float(); - } - - void *vertexes_data{vertexes.data()}; - size_t vertexes_size = sizeof(vertexes[0]) * vertexes.size(); - self->mesh->source_vertex_buffer = new VK::SourceBuffer{ - self->mesh->queue_family->device, vertexes_data, vertexes_size}; - self->mesh->vertex_buffer = new VK::DestinationBuffer{ - self->mesh->queue_family, self->mesh->source_vertex_buffer, - VK_BUFFER_USAGE_VERTEX_BUFFER_BIT}; - } - - { // Load indexes. - self->mesh->index_count = input.read_ui32(); - std::vector<uint32_t> indexes(self->mesh->index_count); - - for(auto i{0}; i < self->mesh->index_count; i++) - indexes[i] = input.read_ui32(); - - void *indexes_data{indexes.data()}; - size_t indexes_size{sizeof(indexes[0]) * indexes.size()}; - VK::SourceBuffer source_index_buffer{ - self->mesh->queue_family->device, indexes_data, indexes_size}; - self->mesh->index_buffer = new VK::DestinationBuffer{ - self->mesh->queue_family, &source_index_buffer, - VK_BUFFER_USAGE_INDEX_BUFFER_BIT}; - } - - { // Load bones - auto bone_count{input.read_ui32()}; - self->mesh->bones.reserve(bone_count); - for(int i{0}; i < bone_count; i++) - self->mesh->bones.emplace_back(input.read_mat4()); - } - - { // Load animations - auto num_animations{input.read_ui32()}; - self->mesh->animations.resize(num_animations); - for(uint32_t i{0}; i < num_animations; i++) - { - auto duration{input.read_double()}; - self->mesh->animations[i].final_time = (float)duration; - - auto ticks_per_second{input.read_double()}; - - auto num_bone_transforms{input.read_ui32()}; - std::vector<VK::BoneTransform> *bone_transforms = - &(self->mesh->animations[i].bone_transforms); - bone_transforms->resize(num_bone_transforms); - for(uint32_t bone_transform_index{0}; - bone_transform_index < num_bone_transforms; bone_transform_index++) - { - auto bone_id{input.read_ui32()}; - - auto num_positions{input.read_ui32()}; - VK::Channel<glm::vec3> *positions = - &((*bone_transforms)[bone_transform_index].positions); - for(auto position_key_index{0}; position_key_index < num_positions; - position_key_index++) - { - auto vec3{input.read_vec3()}; - auto timestamp{input.read_double()}; - positions->key_frames.emplace_back( - vec3, static_cast<float>(timestamp)); - } - - auto num_rotations{input.read_ui32()}; - VK::Channel<glm::quat> *rotations = - &((*bone_transforms)[bone_transform_index].rotations); - for(auto rotation_key_index{0}; rotation_key_index < num_rotations; - rotation_key_index++) - { - auto quat{input.read_quat()}; - auto timestamp{input.read_double()}; - rotations->key_frames.emplace_back( - quat, static_cast<float>(timestamp)); - } - - auto num_scales{input.read_ui32()}; - VK::Channel<glm::vec3> *scales = - &((*bone_transforms)[bone_transform_index].scales); - for(auto scaling_key_index{0}; scaling_key_index < num_scales; - scaling_key_index++) - { - auto vec3{input.read_vec3()}; - auto timestamp{input.read_double()}; - scales->key_frames.emplace_back(vec3, static_cast<float>(timestamp)); - } - } - } - } -} - -void -unload_mesh(void *obj) -{ - auto self = static_cast<MeshBuilder*>(obj); - - delete self->mesh->index_buffer; - delete self->mesh->vertex_buffer; - delete self->mesh->source_vertex_buffer; -} - -static const CommandChain loader{ - {&load_mesh, &unload_mesh} -}; - -} - -namespace VK -{ - -SkeletalMesh::SkeletalMesh(std::string mesh_path) -{ - MeshBuilder mesh_builder(this, mesh_path); - loader.execute(&mesh_builder); -} - -SkeletalMesh::SkeletalMesh(const char* mesh_path): - SkeletalMesh{std::string(mesh_path)} -{ -} - -SkeletalMesh::~SkeletalMesh() -{ - MeshBuilder mesh_builder(this, ""); - loader.revert(&mesh_builder); -} - -} diff --git a/src/vk/skeletal_mesh.hpp b/src/vk/skeletal_mesh.hpp deleted file mode 100644 index 7fc8334..0000000 --- a/src/vk/skeletal_mesh.hpp +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2022-2023 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. - */ - -#ifndef CANDY_GEAR_VK_SKELETAL_MESH_H -#define CANDY_GEAR_VK_SKELETAL_MESH_H 1 - -#include <string> -#include <vector> - -#include "animation.hpp" -#include "core.hpp" -#include "destination_buffer.hpp" -#include "queue_family.hpp" -#include "uniform_buffer.hpp" -#include "texture.hpp" - -namespace VK -{ - -struct SkeletalMesh -{ - QueueFamily *queue_family; - - uint32_t index_count; - SourceBuffer *source_vertex_buffer; - DestinationBuffer *index_buffer; - DestinationBuffer *vertex_buffer; - - std::vector<Bone> bones; - std::vector<Animation> animations; - - SkeletalMesh(std::string mesh_path); - SkeletalMesh(const char* mesh_path); - ~SkeletalMesh(); -}; - -} - -#endif /* CANDY_GEAR_VK_SKELETAL_MESH_H */ diff --git a/src/vk/skeletal_mesh_vertex.hpp b/src/vk/skeletal_mesh_vertex.hpp deleted file mode 100644 index b5bba3d..0000000 --- a/src/vk/skeletal_mesh_vertex.hpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2022-2023 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. - */ - -#ifndef CANDY_GEAR_VK_SKELETAL_MESH_VERTEX_H -#define CANDY_GEAR_VK_SKELETAL_MESH_VERTEX_H 1 - -#include "core.hpp" - -namespace VK -{ - -// This variable define the maximum ammount of bones that can influence a -// vertex. -const int SKELETAL_MESH_MAX_NUM_OF_INFLUENCING_BONES{4}; -const int SKELETAL_MESH_MAX_NUM_OF_BONES{50}; - -struct SkeletalMeshVertex -{ - glm::vec3 position; - glm::vec3 normal; - glm::vec2 texture_coord; - - uint32_t bone_ids[SKELETAL_MESH_MAX_NUM_OF_INFLUENCING_BONES]; - float bone_weights[SKELETAL_MESH_MAX_NUM_OF_INFLUENCING_BONES]; -}; - -} - -#endif /* CANDY_GEAR_VK_SKELETAL_MESH_VERTEX_H */ diff --git a/src/vk/skeletal_model.cpp b/src/vk/skeletal_model.cpp deleted file mode 100644 index d2739c4..0000000 --- a/src/vk/skeletal_model.cpp +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright 2022-2023 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 "skeletal_model.hpp" - -#include "../core.hpp" -#include "uniform_data_object.hpp" - -namespace -{ - -void -load_uniform_buffers(void *obj) -{ - auto self = static_cast<VK::SkeletalModel*>(obj); - - try - { - self->uniform_buffers.reserve(cg_core.vk_swapchain->images_count); - for(auto i{0}; i < cg_core.vk_swapchain->images_count; i++) - self->uniform_buffers.emplace_back( - cg_core.vk_device_with_swapchain, sizeof(VK::UDOSkeletalModel)); - } - catch(const std::exception& e) - { - throw CommandError{e.what()}; - } -} - -void -unload_uniform_buffers(void *obj) -{ - auto self = static_cast<VK::SkeletalModel*>(obj); - - self->uniform_buffers.clear(); -} - -void -load_descriptor_set_pool(void *obj) -{ - auto self = static_cast<VK::SkeletalModel*>(obj); - - std::array<VkDescriptorPoolSize, 1> descriptor_pool_sizes{}; - descriptor_pool_sizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - descriptor_pool_sizes[0].descriptorCount = - self->uniform_buffers.size(); - - VkDescriptorPoolCreateInfo pool_info{}; - pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - pool_info.pNext = nullptr; - pool_info.flags = 0; - pool_info.maxSets = self->uniform_buffers.size(); - pool_info.poolSizeCount = descriptor_pool_sizes.size(); - pool_info.pPoolSizes = descriptor_pool_sizes.data(); - - if(vkCreateDescriptorPool( - self->skeletal_mesh->queue_family->device->device, &pool_info, nullptr, - &self->descriptor_pool) != VK_SUCCESS) - throw CommandError{"Failed to create a Vulkan descriptor pool."}; -} - -void -unload_descriptor_set_pool(void *obj) -{ - auto self = static_cast<VK::SkeletalModel*>(obj); - - vkDestroyDescriptorPool( - self->skeletal_mesh->queue_family->device->device, self->descriptor_pool, - nullptr); -} - -void -load_descriptor_sets(void *obj) -{ - auto self = static_cast<VK::SkeletalModel*>(obj); - - std::vector<VkDescriptorSetLayout> layouts( - cg_core.vk_swapchain->images_count, - cg_core.vk_descriptor_set_layout->model); - - VkDescriptorSetAllocateInfo alloc_info{}; - alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; - alloc_info.descriptorPool = self->descriptor_pool; - alloc_info.descriptorSetCount = layouts.size(); - alloc_info.pSetLayouts = layouts.data(); - - self->descriptor_sets.resize(layouts.size()); - if(vkAllocateDescriptorSets( - self->skeletal_mesh->queue_family->device->device, &alloc_info, - self->descriptor_sets.data()) != VK_SUCCESS) - CommandError{"Failed to create Vulkan descriptor set."}; -} - -void -load_buffers_to_descriptor_sets(void *obj) -{ - auto self = static_cast<VK::SkeletalModel*>(obj); - - for(auto i{0}; i < self->uniform_buffers.size(); i++) - { - VkDescriptorBufferInfo buffer_info{}; - buffer_info.buffer = self->uniform_buffers[i].buffer; - buffer_info.offset = 0; - buffer_info.range = sizeof(VK::UDOSkeletalModel); - - std::array<VkWriteDescriptorSet, 1> write_descriptors{}; - write_descriptors[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - write_descriptors[0].dstSet = self->descriptor_sets[i]; - write_descriptors[0].dstBinding = 0; - write_descriptors[0].dstArrayElement = 0; - write_descriptors[0].descriptorCount = 1; - write_descriptors[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - write_descriptors[0].pBufferInfo = &buffer_info; - write_descriptors[0].pImageInfo = nullptr; - write_descriptors[0].pTexelBufferView = nullptr; - - vkUpdateDescriptorSets( - cg_core.vk_device_with_swapchain->device, write_descriptors.size(), - write_descriptors.data(), 0, nullptr); - } -} - -static const CommandChain loader{ - {&load_uniform_buffers, &unload_uniform_buffers}, - {&load_descriptor_set_pool, &unload_descriptor_set_pool}, - {&load_descriptor_sets, nullptr}, - {&load_buffers_to_descriptor_sets, nullptr} -}; - -} - -namespace VK -{ - -SkeletalModel::SkeletalModel( - std::shared_ptr<SkeletalMesh> skeletal_mesh, - std::shared_ptr<Texture> texture, std::shared_ptr<glm::vec3> position, - std::shared_ptr<glm::quat> orientation): - skeletal_mesh{skeletal_mesh}, - texture{texture}, - position{position}, - orientation{orientation}, - animation_index{0}, - animation_time{0.0f}, - bone_transforms(SKELETAL_MESH_MAX_NUM_OF_BONES) -{ - loader.execute(this); - - for(int i{0}; i < skeletal_mesh->bones.size(); i++) - this->bone_transforms[i] = skeletal_mesh->bones[i].offset_matrix; -} - -SkeletalModel::~SkeletalModel() -{ - loader.revert(this); -} - -void -SkeletalModel::tick(float delta) -{ - VK::Animation *current_animation = - &this->skeletal_mesh->animations[this->animation_index]; - - { // update time - this->animation_time += delta; - if(this->animation_time > current_animation->final_time) - { - this->animation_time -= current_animation->final_time; - for(VK::BoneTransform &bone_transform: - current_animation->bone_transforms) - { - bone_transform.positions.current_index = 0; - bone_transform.rotations.current_index = 0; - bone_transform.scales.current_index = 0; - } - } - } - - for(int i{0}; i < current_animation->bone_transforms.size(); i++) - { - VK::BoneTransform *bone_transform = ¤t_animation->bone_transforms[i]; - - auto position{bone_transform->positions.interpolate( - this->animation_time, - [](glm::vec3 frame) - { - return glm::translate(glm::mat4(1.0f), frame); - }, - [](glm::vec3 previous_frame, glm::vec3 next_frame, float scale_factor) - { - glm::vec3 final_position{glm::mix( - previous_frame, next_frame, scale_factor)}; - return glm::translate(glm::mat4(1.0f), final_position); - })}; - - auto rotation{bone_transform->rotations.interpolate( - this->animation_time, - [](glm::quat frame) - { - return glm::toMat4(glm::normalize(frame)); - }, - [](glm::quat previous_frame, glm::quat next_frame, float scale_factor) - { - return glm::toMat4(glm::slerp( - previous_frame, next_frame, scale_factor)); - })}; - - auto scale{bone_transform->scales.interpolate( - this->animation_time, - [](glm::vec3 frame) - { - return glm::scale(glm::mat4(1.0f), frame); - }, - [](glm::vec3 previous_frame, glm::vec3 next_frame, float scale_factor) - { - glm::vec3 scale{glm::mix( - previous_frame, next_frame, scale_factor)}; - return glm::scale(glm::mat4(1.0f), scale); - })}; - - this->bone_transforms[i] = position * rotation * scale; - } -} - -} diff --git a/src/vk/skeletal_model.hpp b/src/vk/skeletal_model.hpp deleted file mode 100644 index db54ac9..0000000 --- a/src/vk/skeletal_model.hpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2022-2023 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. - */ - -#ifndef CANDY_GEAR_VK_SKELETAL_MODEL_H -#define CANDY_GEAR_VK_SKELETAL_MODEL_H 1 - -#include <memory> -#include <vector> - -#include "core.hpp" -#include "skeletal_mesh.hpp" - -namespace VK -{ - -struct SkeletalModel -{ - std::shared_ptr<SkeletalMesh> skeletal_mesh; - std::shared_ptr<Texture> texture; - std::vector<UniformBuffer> uniform_buffers; - std::shared_ptr<glm::vec3> position; - std::shared_ptr<glm::quat> orientation; - int animation_index; - float animation_time; - std::vector<glm::mat4> bone_transforms; - - VkDescriptorPool descriptor_pool; - std::vector<VkDescriptorSet> descriptor_sets; - - SkeletalModel( - std::shared_ptr<SkeletalMesh> skeletal_mesh, - std::shared_ptr<Texture> texture, std::shared_ptr<glm::vec3> position, - std::shared_ptr<glm::quat> orientation); - ~SkeletalModel(); - - void - tick(float delta); -}; - -} - -#endif /* CANDY_GEAR_VK_SKELETAL_MODEL_H */ diff --git a/src/vk/source_buffer.cpp b/src/vk/source_buffer.cpp deleted file mode 100644 index f8f1aee..0000000 --- a/src/vk/source_buffer.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2022 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 "source_buffer.hpp" - -#include <cstring> - -namespace VK -{ - -SourceBuffer::SourceBuffer(Device *device, void *data, size_t data_size) -{ - this->device = device; - this->device_size = data_size; - this->buffer_usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; - this->memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | - VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; - - try - { - VK::BaseBuffer::loader.execute(static_cast<VK::BaseBuffer*>(this)); - } - catch(const CommandError &command_error) - { - std::string error{"Could not initialize Vulkan source buffer → "}; - error += command_error.what(); - throw std::runtime_error{error}; - } - this->copy_data(data); -} - -SourceBuffer::SourceBuffer(SourceBuffer &&that) -{ - this->buffer = that.buffer; - this->device_memory = that.device_memory; - this->device_size = that.device_size; - this->buffer_usage = that.buffer_usage; - this->memory_properties = that.memory_properties; - - that.buffer = VK_NULL_HANDLE; - that.device_memory = VK_NULL_HANDLE; -} - -SourceBuffer& -SourceBuffer::operator=(SourceBuffer &&that) -{ - this->buffer = that.buffer; - this->device_memory = that.device_memory; - this->device_size = that.device_size; - this->buffer_usage = that.buffer_usage; - this->memory_properties = that.memory_properties; - - that.buffer = VK_NULL_HANDLE; - that.device_memory = VK_NULL_HANDLE; - - return *this; -} - -SourceBuffer::~SourceBuffer() -{ - VK::BaseBuffer::loader.revert(static_cast<VK::BaseBuffer*>(this)); -} - -void -SourceBuffer::copy_data(void *src_data) -{ - void *dst_data; - vkMapMemory(this->device->device, this->device_memory, 0, this->device_size, - 0, &dst_data); - memcpy(dst_data, src_data, static_cast<size_t>(this->device_size)); - vkUnmapMemory(this->device->device, this->device_memory); -} - -} diff --git a/src/vk/source_buffer.hpp b/src/vk/source_buffer.hpp deleted file mode 100644 index 440e561..0000000 --- a/src/vk/source_buffer.hpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2022 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. - */ - -#ifndef CANDY_GEAR_VK_SOURCE_BUFFER_H -#define CANDY_GEAR_VK_SOURCE_BUFFER_H 1 - -#include "base_buffer.hpp" - -namespace VK -{ - -struct SourceBuffer: public BaseBuffer -{ - SourceBuffer(const SourceBuffer &t) = delete; - SourceBuffer& - operator=(const SourceBuffer &t) = delete; - - SourceBuffer(Device *device, void *data, size_t data_size); - - SourceBuffer(SourceBuffer &&that); - SourceBuffer& - operator=(SourceBuffer &&that); - - ~SourceBuffer(); - - void - copy_data(void *src_data); -}; - -} - -#endif /* CANDY_GEAR_VK_SOURCE_BUFFER_H */ diff --git a/src/vk/sprite.cpp b/src/vk/sprite.cpp deleted file mode 100644 index 95e11a3..0000000 --- a/src/vk/sprite.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2022-2023 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 "sprite.hpp" - -#include <array> - -#include "../core.hpp" -#include "sprite.hpp" -#include "uniform_data_object.hpp" - -namespace -{ - -struct SpriteBuilder -{ - VK::Sprite *sprite; - glm::vec4 ▭ - - SpriteBuilder(VK::Sprite *sprite, glm::vec4 &rect); -}; - -SpriteBuilder::SpriteBuilder(VK::Sprite *sprite, glm::vec4 &rect): - sprite{sprite}, - rect{rect} -{ -} - -void -load_mesh(void *obj) -{ - auto self = static_cast<SpriteBuilder*>(obj); - - self->sprite->queue_family = - cg_core.vk_device_with_swapchain->get_queue_family_with_graphics(); - - glm::vec2 rect[VK::Sprite::vertex_count]{ - glm::vec2{self->rect.x, self->rect.y}, - glm::vec2{self->rect.x, self->rect.w}, - glm::vec2{self->rect.z, self->rect.y}, - glm::vec2{self->rect.z, self->rect.w} - }; - - void *vertexes_data{&rect}; - static const size_t vertexes_size = - sizeof(glm::vec2) * VK::Sprite::vertex_count; - self->sprite->source_buffer = new VK::SourceBuffer{ - self->sprite->queue_family->device, vertexes_data, vertexes_size}; - self->sprite->vertex_buffer = new VK::DestinationBuffer{ - self->sprite->queue_family, self->sprite->source_buffer, - VK_BUFFER_USAGE_VERTEX_BUFFER_BIT}; -} - -void -unload_mesh(void *obj) -{ - auto self = static_cast<SpriteBuilder*>(obj); - - delete self->sprite->vertex_buffer; - delete self->sprite->source_buffer; -} - -static const CommandChain loader{ - {&load_mesh, &unload_mesh}, -}; - -} - -namespace VK -{ - -Sprite::Sprite(std::shared_ptr<Texture> texture, glm::vec4 &rect): - texture{texture} -{ - SpriteBuilder sprite_builder(this, rect); - loader.execute(&sprite_builder); -} - -Sprite::~Sprite() -{ - glm::vec4 vector_4d{}; - SpriteBuilder sprite_builder(this, vector_4d); - loader.revert(&sprite_builder); -} - -} diff --git a/src/vk/sprite.hpp b/src/vk/sprite.hpp deleted file mode 100644 index 791144e..0000000 --- a/src/vk/sprite.hpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2022-2023 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. - */ - -#ifndef CANDY_GEAR_VK_SPRITE_H -#define CANDY_GEAR_VK_SPRITE_H 1 - -#include <memory> -#include <unordered_map> -#include <vector> - -#include "core.hpp" -#include "destination_buffer.hpp" -#include "queue_family.hpp" -#include "uniform_buffer.hpp" -#include "texture.hpp" - -namespace VK -{ - -struct Sprite -{ - static const uint32_t vertex_count{4}; - - QueueFamily *queue_family; - - SourceBuffer *source_buffer; - DestinationBuffer *vertex_buffer; - - std::shared_ptr<Texture> texture; - - Sprite(std::shared_ptr<Texture> texture, glm::vec4 &rect); - ~Sprite(); -}; - -} - -#endif /* CANDY_GEAR_VK_SPRITE_H */ diff --git a/src/vk/sprite_3d.cpp b/src/vk/sprite_3d.cpp deleted file mode 100644 index 66199f1..0000000 --- a/src/vk/sprite_3d.cpp +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 2022-2023 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 "sprite_3d.hpp" - -#include "../core.hpp" -#include "uniform_data_object.hpp" - -namespace -{ - -void -load_uniform_buffers(void *obj) -{ - auto self = static_cast<VK::Sprite3D*>(obj); - - try - { - self->uniform_buffers.reserve(cg_core.vk_swapchain->images_count); - for(auto i{0}; i < cg_core.vk_swapchain->images_count; i++) - self->uniform_buffers.emplace_back( - cg_core.vk_device_with_swapchain, sizeof(VK::UDOSprite3D)); - } - catch(const std::exception& e) - { - throw CommandError{e.what()}; - } -} - -void -unload_uniform_buffers(void *obj) -{ - auto self = static_cast<VK::Sprite3D*>(obj); - - self->uniform_buffers.clear(); -} - -void -load_descriptor_set_pool(void *obj) -{ - auto self = static_cast<VK::Sprite3D*>(obj); - - std::array<VkDescriptorPoolSize, 1> descriptor_pool_sizes{}; - descriptor_pool_sizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - descriptor_pool_sizes[0].descriptorCount = - self->uniform_buffers.size(); - - VkDescriptorPoolCreateInfo pool_info{}; - pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - pool_info.pNext = nullptr; - pool_info.flags = 0; - pool_info.maxSets = self->uniform_buffers.size(); - pool_info.poolSizeCount = descriptor_pool_sizes.size(); - pool_info.pPoolSizes = descriptor_pool_sizes.data(); - - if(vkCreateDescriptorPool( - self->queue_family->device->device, &pool_info, nullptr, - &self->descriptor_pool) != VK_SUCCESS) - throw CommandError{"Failed to create a Vulkan descriptor pool."}; -} - -void -unload_descriptor_set_pool(void *obj) -{ - auto self = static_cast<VK::Sprite3D*>(obj); - - vkDestroyDescriptorPool( - self->queue_family->device->device, self->descriptor_pool, nullptr); -} -void -load_descriptor_sets(void *obj) -{ - auto self = static_cast<VK::Sprite3D*>(obj); - - std::vector<VkDescriptorSetLayout> layouts( - cg_core.vk_swapchain->images_count, - cg_core.vk_descriptor_set_layout->model); - - VkDescriptorSetAllocateInfo alloc_info{}; - alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; - alloc_info.descriptorPool = self->descriptor_pool; - alloc_info.descriptorSetCount = layouts.size(); - alloc_info.pSetLayouts = layouts.data(); - - self->descriptor_sets.resize(layouts.size()); - if(vkAllocateDescriptorSets( - self->queue_family->device->device, &alloc_info, - self->descriptor_sets.data()) != VK_SUCCESS) - CommandError{"Failed to create Vulkan descriptor set."}; -} - -void -load_buffers_to_descriptor_sets(void *obj) -{ - auto self = static_cast<VK::Sprite3D*>(obj); - - for(auto i{0}; i < self->uniform_buffers.size(); i++) - { - VkDescriptorBufferInfo buffer_info{}; - buffer_info.buffer = self->uniform_buffers[i].buffer; - buffer_info.offset = 0; - buffer_info.range = sizeof(VK::UDOSprite3D); - - VkDescriptorImageInfo image_info{}; - image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - image_info.imageView = self->sprite->texture->view; - image_info.sampler = self->sprite->texture->sampler; - - std::array<VkWriteDescriptorSet, 1> write_descriptors{}; - write_descriptors[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - write_descriptors[0].dstSet = self->descriptor_sets[i]; - write_descriptors[0].dstBinding = 0; - write_descriptors[0].dstArrayElement = 0; - write_descriptors[0].descriptorCount = 1; - write_descriptors[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - write_descriptors[0].pBufferInfo = &buffer_info; - write_descriptors[0].pImageInfo = nullptr; - write_descriptors[0].pTexelBufferView = nullptr; - - vkUpdateDescriptorSets( - cg_core.vk_device_with_swapchain->device, write_descriptors.size(), - write_descriptors.data(), 0, nullptr); - } -} - -static const CommandChain loader{ - {&load_uniform_buffers, &unload_uniform_buffers}, - {&load_descriptor_set_pool, &unload_descriptor_set_pool}, - {&load_descriptor_sets, nullptr}, - {&load_buffers_to_descriptor_sets, nullptr} -}; - -} - -namespace VK -{ - -Sprite3D::Sprite3D( - std::shared_ptr<VK::Sprite> sprite, std::shared_ptr<glm::vec3> position, - glm::vec2 size): - sprite{sprite}, - position{position}, - size{size} -{ - this->queue_family = - cg_core.vk_device_with_swapchain->get_queue_family_with_graphics(); - loader.execute(this); -} - -Sprite3D::~Sprite3D() -{ - loader.revert(this); -} - -} diff --git a/src/vk/sprite_3d.hpp b/src/vk/sprite_3d.hpp deleted file mode 100644 index 2059606..0000000 --- a/src/vk/sprite_3d.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2022-2023 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. - */ - -#ifndef CANDY_GEAR_VK_SPRITE_3D_H -#define CANDY_GEAR_VK_SPRITE_3D_H 1 - -#include "core.hpp" -#include "sprite.hpp" - -namespace VK -{ - -struct Sprite3D -{ - std::shared_ptr<Sprite> sprite; - std::shared_ptr<glm::vec3> position; - glm::vec2 size; - - QueueFamily *queue_family; - - std::vector<UniformBuffer> uniform_buffers; - VkDescriptorPool descriptor_pool; - std::vector<VkDescriptorSet> descriptor_sets; - - Sprite3D( - std::shared_ptr<Sprite> sprite, std::shared_ptr<glm::vec3> position, - glm::vec2 size); - ~Sprite3D(); -}; - -} - -#endif /* CANDY_GEAR_VK_SPRITE_3D_H */ diff --git a/src/vk/sprite_to_draw.cpp b/src/vk/sprite_to_draw.cpp deleted file mode 100644 index 76ee847..0000000 --- a/src/vk/sprite_to_draw.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2022-2023 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 "sprite_to_draw.hpp" - -namespace VK -{ - SpriteToDraw::SpriteToDraw( - std::shared_ptr<Sprite> sprite, const glm::vec4 &position, float z_index): - sprite{sprite}, - position{position}, - z_index{z_index} - { - } - - bool - operator<(const SpriteToDraw& a, const SpriteToDraw& b) - { - return a.z_index < b.z_index; - } - - bool - operator>(const SpriteToDraw& a, const SpriteToDraw& b) - { - return a.z_index > b.z_index; - } -} diff --git a/src/vk/sprite_to_draw.hpp b/src/vk/sprite_to_draw.hpp deleted file mode 100644 index 84effff..0000000 --- a/src/vk/sprite_to_draw.hpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2022-2023 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. - */ - -#ifndef CANDY_GEAR_VK_SPRITES_TO_DRAW_H -#define CANDY_GEAR_VK_SPRITES_TO_DRAW_H 1 - -#include <memory> - -#include "core.hpp" -#include "sprite.hpp" - -namespace VK -{ - struct SpriteToDraw - { - std::shared_ptr<Sprite> sprite; - glm::vec4 position; - float z_index; - - SpriteToDraw(std::shared_ptr<Sprite> sprite, const glm::vec4 &position, - float z_index); - }; - - bool - operator<(const SpriteToDraw &a, const SpriteToDraw &b); - - bool - operator>(const SpriteToDraw &a, const SpriteToDraw &b); -} - -#endif /* CANDY_GEAR_VK_SPRITES_TO_DRAW_H */ diff --git a/src/vk/static_mesh.cpp b/src/vk/static_mesh.cpp deleted file mode 100644 index 29034df..0000000 --- a/src/vk/static_mesh.cpp +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2022-2023 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 "static_mesh.hpp" - -#include "../binary_reader.hpp" -#include "../command.hpp" -#include "../core.hpp" -#include "static_mesh_vertex.hpp" - -namespace -{ - -// Data that is only needed for the command chain but not for the StaticMesh -// goes here. -struct MeshBuilder -{ - std::string mesh_path; - VK::StaticMesh *mesh; - - MeshBuilder(VK::StaticMesh *m, std::string mp); - MeshBuilder(VK::StaticMesh *m, const char* mp); -}; - -MeshBuilder::MeshBuilder(VK::StaticMesh *m, std::string mp): - mesh{m}, - mesh_path{mp} -{ -} - -MeshBuilder::MeshBuilder(VK::StaticMesh *m, const char *mp): - MeshBuilder{m, std::string(mp)} -{ -} - -void -load_mesh(void *obj) -{ - auto self = static_cast<MeshBuilder*>(obj); - - BinaryReader input{self->mesh_path}; - - self->mesh->queue_family = - cg_core.vk_device_with_swapchain->get_queue_family_with_graphics(); - - { // Load vertexes. - auto vertex_count{input.read_ui32()}; - std::vector<VK::StaticMeshVertex> vertexes{vertex_count}; - - for(auto i{0}; i < vertex_count; i++) - { - vertexes[i].position = input.read_vec3(); - vertexes[i].normal = input.read_vec3(); - vertexes[i].texture_coord = input.read_vec2(); - } - - void *vertexes_data{vertexes.data()}; - size_t vertexes_size = sizeof(vertexes[0]) * vertexes.size(); - self->mesh->source_vertex_buffer = new VK::SourceBuffer{ - self->mesh->queue_family->device, vertexes_data, vertexes_size}; - self->mesh->vertex_buffer = new VK::DestinationBuffer{ - self->mesh->queue_family, self->mesh->source_vertex_buffer, - VK_BUFFER_USAGE_VERTEX_BUFFER_BIT}; - } - - { // Load indexes - self->mesh->index_count = input.read_ui32(); - std::vector<uint32_t> indexes(self->mesh->index_count); - - for(auto i{0}; i < self->mesh->index_count; i++) - indexes[i] = input.read_ui32(); - - void *indexes_data{indexes.data()}; - size_t indexes_size{sizeof(indexes[0]) * indexes.size()}; - VK::SourceBuffer source_index_buffer{ - self->mesh->queue_family->device, indexes_data, indexes_size}; - self->mesh->index_buffer = new VK::DestinationBuffer{ - self->mesh->queue_family, &source_index_buffer, - VK_BUFFER_USAGE_INDEX_BUFFER_BIT}; - } -} - -void -unload_mesh(void *obj) -{ - auto self = static_cast<MeshBuilder*>(obj); - - delete self->mesh->index_buffer; - delete self->mesh->vertex_buffer; - delete self->mesh->source_vertex_buffer; -} - -static const CommandChain loader{ - {&load_mesh, &unload_mesh} -}; - -} - -namespace VK -{ - -StaticMesh::StaticMesh(std::string mesh_path) -{ - MeshBuilder mesh_builder(this, mesh_path); - loader.execute(&mesh_builder); -} - -StaticMesh::StaticMesh(const char* mesh_path): - StaticMesh{std::string(mesh_path)} -{ -} - -StaticMesh::~StaticMesh() -{ - MeshBuilder mesh_builder(this, ""); - loader.revert(&mesh_builder); -} - -} diff --git a/src/vk/static_mesh.hpp b/src/vk/static_mesh.hpp deleted file mode 100644 index 0ab38b2..0000000 --- a/src/vk/static_mesh.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2022-2023 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. - */ - -#ifndef CANDY_GEAR_VK_STATIC_MESH_H -#define CANDY_GEAR_VK_STATIC_MESH_H 1 - -#include <string> -#include <vector> - -#include "core.hpp" -#include "destination_buffer.hpp" -#include "queue_family.hpp" -#include "uniform_buffer.hpp" -#include "texture.hpp" - -namespace VK -{ - -struct StaticMesh -{ - QueueFamily *queue_family; - - uint32_t index_count; - SourceBuffer *source_vertex_buffer; - DestinationBuffer *index_buffer; - DestinationBuffer *vertex_buffer; - - StaticMesh(std::string mesh_path); - StaticMesh(const char* mesh_path); - ~StaticMesh(); -}; - -} - -#endif /* CANDY_GEAR_VK_STATIC_MESH_H */ diff --git a/src/vk/static_mesh_vertex.hpp b/src/vk/static_mesh_vertex.hpp deleted file mode 100644 index 7a91fe4..0000000 --- a/src/vk/static_mesh_vertex.hpp +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2022-2023 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. - */ - -#ifndef CANDY_GEAR_VK_STATIC_MESH_VERTEX_H -#define CANDY_GEAR_VK_STATIC_MESH_VERTEX_H 1 - -#include "core.hpp" - -namespace VK -{ - -struct StaticMeshVertex -{ - glm::vec3 position; - glm::vec3 normal; - glm::vec2 texture_coord; -}; - -} - -#endif /* CANDY_GEAR_VK_STATIC_MESH_VERTEX_H */ diff --git a/src/vk/static_model.cpp b/src/vk/static_model.cpp deleted file mode 100644 index ef53155..0000000 --- a/src/vk/static_model.cpp +++ /dev/null @@ -1,165 +0,0 @@ -/* - * 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 "static_model.hpp" - -#include "../core.hpp" -#include "uniform_data_object.hpp" - -namespace -{ - -void -load_uniform_buffers(void *obj) -{ - auto self = static_cast<VK::StaticModel*>(obj); - - try - { - self->uniform_buffers.reserve(cg_core.vk_swapchain->images_count); - for(auto i{0}; i < cg_core.vk_swapchain->images_count; i++) - self->uniform_buffers.emplace_back( - cg_core.vk_device_with_swapchain, sizeof(VK::UDOStaticModel)); - } - catch(const std::exception& e) - { - throw CommandError{e.what()}; - } -} - -void -unload_uniform_buffers(void *obj) -{ - auto self = static_cast<VK::StaticModel*>(obj); - - self->uniform_buffers.clear(); -} - -void -load_descriptor_set_pool(void *obj) -{ - auto self = static_cast<VK::StaticModel*>(obj); - - std::array<VkDescriptorPoolSize, 1> descriptor_pool_sizes{}; - descriptor_pool_sizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - descriptor_pool_sizes[0].descriptorCount = - self->uniform_buffers.size(); - - VkDescriptorPoolCreateInfo pool_info{}; - pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - pool_info.pNext = nullptr; - pool_info.flags = 0; - pool_info.maxSets = self->uniform_buffers.size(); - pool_info.poolSizeCount = descriptor_pool_sizes.size(); - pool_info.pPoolSizes = descriptor_pool_sizes.data(); - - if(vkCreateDescriptorPool( - self->static_mesh->queue_family->device->device, &pool_info, nullptr, - &self->descriptor_pool) != VK_SUCCESS) - throw CommandError{"Failed to create a Vulkan descriptor pool."}; -} - -void -unload_descriptor_set_pool(void *obj) -{ - auto self = static_cast<VK::StaticModel*>(obj); - - vkDestroyDescriptorPool( - self->static_mesh->queue_family->device->device, self->descriptor_pool, - nullptr); -} - -void -load_descriptor_sets(void *obj) -{ - auto self = static_cast<VK::StaticModel*>(obj); - - std::vector<VkDescriptorSetLayout> layouts( - cg_core.vk_swapchain->images_count, - cg_core.vk_descriptor_set_layout->model); - - VkDescriptorSetAllocateInfo alloc_info{}; - alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; - alloc_info.descriptorPool = self->descriptor_pool; - alloc_info.descriptorSetCount = layouts.size(); - alloc_info.pSetLayouts = layouts.data(); - - self->descriptor_sets.resize(layouts.size()); - if(vkAllocateDescriptorSets( - self->static_mesh->queue_family->device->device, &alloc_info, - self->descriptor_sets.data()) != VK_SUCCESS) - CommandError{"Failed to create Vulkan descriptor set."}; -} - -void -load_buffers_to_descriptor_sets(void *obj) -{ - auto self = static_cast<VK::StaticModel*>(obj); - - for(auto i{0}; i < self->uniform_buffers.size(); i++) - { - VkDescriptorBufferInfo buffer_info{}; - buffer_info.buffer = self->uniform_buffers[i].buffer; - buffer_info.offset = 0; - buffer_info.range = sizeof(VK::UDOStaticModel); - - std::array<VkWriteDescriptorSet, 1> write_descriptors{}; - write_descriptors[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - write_descriptors[0].dstSet = self->descriptor_sets[i]; - write_descriptors[0].dstBinding = 0; - write_descriptors[0].dstArrayElement = 0; - write_descriptors[0].descriptorCount = 1; - write_descriptors[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - write_descriptors[0].pBufferInfo = &buffer_info; - write_descriptors[0].pImageInfo = nullptr; - write_descriptors[0].pTexelBufferView = nullptr; - - vkUpdateDescriptorSets( - cg_core.vk_device_with_swapchain->device, write_descriptors.size(), - write_descriptors.data(), 0, nullptr); - } -} - -static const CommandChain loader{ - {&load_uniform_buffers, &unload_uniform_buffers}, - {&load_descriptor_set_pool, &unload_descriptor_set_pool}, - {&load_descriptor_sets, nullptr}, - {&load_buffers_to_descriptor_sets, nullptr} -}; - -} - -namespace VK -{ - -StaticModel::StaticModel( - std::shared_ptr<StaticMesh> static_mesh, - std::shared_ptr<Texture> texture, std::shared_ptr<glm::vec3> position, - std::shared_ptr<glm::quat> orientation): - static_mesh{static_mesh}, - texture{texture}, - position{position}, - orientation{orientation} -{ - loader.execute(this); -} - -StaticModel::~StaticModel() -{ - loader.revert(this); -} - -} diff --git a/src/vk/static_model.hpp b/src/vk/static_model.hpp deleted file mode 100644 index 72f4fac..0000000 --- a/src/vk/static_model.hpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2022-2023 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. - */ - -#ifndef CANDY_GEAR_VK_STATIC_MODEL_H -#define CANDY_GEAR_VK_STATIC_MODEL_H 1 - -#include <memory> -#include <vector> - -#include "core.hpp" -#include "static_mesh.hpp" - -namespace VK -{ - -struct StaticModel -{ - std::shared_ptr<StaticMesh> static_mesh; - std::shared_ptr<Texture> texture; - std::vector<UniformBuffer> uniform_buffers; - std::shared_ptr<glm::vec3> position; - std::shared_ptr<glm::quat> orientation; - - VkDescriptorPool descriptor_pool; - std::vector<VkDescriptorSet> descriptor_sets; - - StaticModel( - std::shared_ptr<StaticMesh> static_mesh, - std::shared_ptr<Texture> texture, std::shared_ptr<glm::vec3> position, - std::shared_ptr<glm::quat> orientation); - ~StaticModel(); -}; - -} - -#endif /* CANDY_GEAR_VK_STATIC_MODEL_H */ diff --git a/src/vk/swapchain.cpp b/src/vk/swapchain.cpp deleted file mode 100644 index 2c67ebd..0000000 --- a/src/vk/swapchain.cpp +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright 2022 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 "swapchain.hpp" - -#include "../core.hpp" - -#include <vector> - -namespace -{ - -void -load_swapchain(void *obj) -{ - auto self = static_cast<VK::Swapchain*>(obj); - - // Surface formats. - uint32_t vk_surface_format_count; - std::vector<VkSurfaceFormatKHR> vk_surface_formats; - vkGetPhysicalDeviceSurfaceFormatsKHR( - cg_core.vk_device_with_swapchain->physical_device, cg_core.window_surface, - &vk_surface_format_count, nullptr); - vk_surface_formats.resize(vk_surface_format_count); - vkGetPhysicalDeviceSurfaceFormatsKHR( - cg_core.vk_device_with_swapchain->physical_device, cg_core.window_surface, - &vk_surface_format_count, vk_surface_formats.data()); - - VkSwapchainCreateInfoKHR swapchain_create_info = {}; - swapchain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; - swapchain_create_info.pNext = nullptr; - swapchain_create_info.flags = 0; - swapchain_create_info.surface = cg_core.window_surface; - swapchain_create_info.minImageCount = 3; // triple buffering. - - self->image_format = vk_surface_formats[0].format; - swapchain_create_info.imageFormat = self->image_format; - swapchain_create_info.imageColorSpace = vk_surface_formats[0].colorSpace; - - swapchain_create_info.imageExtent = { - cg_core.display_width, cg_core.display_height}; - swapchain_create_info.imageArrayLayers = 1; - swapchain_create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; - swapchain_create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; - swapchain_create_info.queueFamilyIndexCount = 0; - swapchain_create_info.pQueueFamilyIndices = nullptr; - swapchain_create_info.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; - swapchain_create_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; - swapchain_create_info.presentMode = VK_PRESENT_MODE_FIFO_KHR; - swapchain_create_info.clipped = VK_FALSE; - swapchain_create_info.oldSwapchain = VK_NULL_HANDLE; - - if(vkCreateSwapchainKHR( - cg_core.vk_device_with_swapchain->device, &swapchain_create_info, - nullptr, &self->swapchain) != VK_SUCCESS) - throw CommandError{"Vulkan failed to create swapchain."}; - - vkGetSwapchainImagesKHR( - cg_core.vk_device_with_swapchain->device, self->swapchain, - &self->images_count, nullptr); - self->images = new VkImage[self->images_count]; - vkGetSwapchainImagesKHR( - cg_core.vk_device_with_swapchain->device, self->swapchain, - &self->images_count, self->images); -} - -void -unload_swapchain(void *obj) -{ - auto self = static_cast<VK::Swapchain*>(obj); - - delete[] self->images; - vkDestroySwapchainKHR( - cg_core.vk_device_with_swapchain->device, self->swapchain, nullptr); -} - -void -load_image_view(void *obj) -{ - auto self = static_cast<VK::Swapchain*>(obj); - - self->image_views = new VkImageView[self->images_count]; - for(auto i{0}; i < self->images_count; i++) - { - VkImageViewCreateInfo create_info = {}; - create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - create_info.image = self->images[i]; - create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; - create_info.format = self->image_format; - create_info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; - create_info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; - create_info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; - create_info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; - create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - create_info.subresourceRange.baseMipLevel = 0; - create_info.subresourceRange.levelCount = 1; - create_info.subresourceRange.baseArrayLayer = 0; - create_info.subresourceRange.layerCount = 1; - - if(vkCreateImageView( - cg_core.vk_device_with_swapchain->device, &create_info, nullptr, - &self->image_views[i])) - throw CommandError{"Could no create Image View for swapchain."}; - } -} - -void -unload_image_view(void *obj) -{ - auto self = static_cast<VK::Swapchain*>(obj); - - for(auto i{0}; i < self->images_count; i++) - vkDestroyImageView( - cg_core.vk_device_with_swapchain->device, self->image_views[i], nullptr); -} - -void -load_frame_sync(void *obj) -{ - auto self = static_cast<VK::Swapchain*>(obj); - - self->image_available_semaphores.resize(self->max_frames_in_flight); - self->render_finished_semaphores.resize(self->max_frames_in_flight); - self->in_flight_fences.resize(self->max_frames_in_flight); - - VkSemaphoreCreateInfo semaphore_info = {}; - semaphore_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; - semaphore_info.pNext = nullptr; - semaphore_info.flags = 0; - - VkFenceCreateInfo fence_info = {}; - fence_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; - fence_info.pNext = nullptr; - fence_info.flags = VK_FENCE_CREATE_SIGNALED_BIT; - - // FIXME: if this loop fails, it will not destroy the semaphores. - for(auto i{0}; i < self->max_frames_in_flight; i++) - { - if(vkCreateSemaphore( - cg_core.vk_device_with_swapchain->device, &semaphore_info, - nullptr, &self->image_available_semaphores[i]) != VK_SUCCESS || - vkCreateSemaphore( - cg_core.vk_device_with_swapchain->device, &semaphore_info, - nullptr, &self->render_finished_semaphores[i]) != VK_SUCCESS || - vkCreateFence(cg_core.vk_device_with_swapchain->device, &fence_info, - nullptr, &self->in_flight_fences[i]) != VK_SUCCESS) - throw CommandError{"Failed to create semaphores."}; - } -} - -void -unload_frame_sync(void *obj) -{ - auto self = static_cast<VK::Swapchain*>(obj); - - vkDeviceWaitIdle(cg_core.vk_device_with_swapchain->device); - - for(auto i{0}; i < self->max_frames_in_flight; i++) - { - vkDestroySemaphore(cg_core.vk_device_with_swapchain->device, - self->render_finished_semaphores[i], nullptr); - vkDestroySemaphore(cg_core.vk_device_with_swapchain->device, - self->image_available_semaphores[i], nullptr); - vkDestroyFence(cg_core.vk_device_with_swapchain->device, - self->in_flight_fences[i], nullptr); - } -} - -const CommandChain loader{ - {&load_swapchain, &unload_swapchain}, - {&load_image_view, &unload_image_view}, - {&load_frame_sync, &unload_frame_sync} -}; - -} - -namespace VK -{ - -Swapchain::Swapchain(): - current_frame{0} -{ - loader.execute(this); -} - -Swapchain::~Swapchain() -{ - loader.revert(this); -} - -} diff --git a/src/vk/swapchain.hpp b/src/vk/swapchain.hpp deleted file mode 100644 index a5ade81..0000000 --- a/src/vk/swapchain.hpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2022 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. - */ - -#ifndef CANDY_GEAR_VK_SWAPCHAIN_H -#define CANDY_GEAR_VK_SWAPCHAIN_H 1 - -#include "core.hpp" -#include "../command.hpp" - -namespace VK -{ - -struct Swapchain -{ - VkSwapchainKHR swapchain; - VkFormat image_format; - - uint32_t images_count; - VkImage *images; - VkImageView *image_views; - - static const int max_frames_in_flight{2}; - size_t current_frame; - std::vector<VkSemaphore> image_available_semaphores; - std::vector<VkSemaphore> render_finished_semaphores; - std::vector<VkFence> in_flight_fences; - - Swapchain(); - ~Swapchain(); -}; - -} - -#endif /* CANDY_GEAR_VK_SWAPCHAIN_H */ diff --git a/src/vk/texture.cpp b/src/vk/texture.cpp deleted file mode 100644 index a4cac40..0000000 --- a/src/vk/texture.cpp +++ /dev/null @@ -1,559 +0,0 @@ -/* - * 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 "texture.hpp" - -#include "../command.hpp" -#include "../core.hpp" -#include "image.hpp" -#include "qoi.hpp" -#include "source_buffer.hpp" - -namespace -{ - -inline void -create_vulkan_image( - VkImage *image, VkDeviceMemory *device_memory, int width, int height, - uint32_t mip_levels) -{ - VkExtent3D vk_extent3d{}; - vk_extent3d.width = width; - vk_extent3d.height = height; - vk_extent3d.depth = 1; - - VK::Image::create( - cg_core.vk_device_with_swapchain, - image, - device_memory, - VK_FORMAT_R8G8B8A8_UNORM, - vk_extent3d, - mip_levels, - VK_IMAGE_TILING_OPTIMAL, - VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT); -} - -struct ImageBuilder -{ - VK::Texture *texture; -}; - -struct ImageTextureBuilder: public ImageBuilder -{ - std::string texture_path; - - ImageTextureBuilder(VK::Texture *t, std::string tp); - ImageTextureBuilder(VK::Texture *t, const char* tp); -}; - -ImageTextureBuilder::ImageTextureBuilder(VK::Texture *t, std::string tp): - texture_path{tp} -{ - this->texture = t; -} - -ImageTextureBuilder::ImageTextureBuilder(VK::Texture *t, const char* tp): - ImageTextureBuilder{t, std::string(tp)} -{ -} - -void -load_image(void *obj) -{ - auto self = static_cast<ImageTextureBuilder*>(obj); - - const int num_channels = 4; // all images are converted to RGBA - VK::QOI::Image qoi_image(self->texture_path.c_str(), num_channels); - uint8_t *pixels; - - { // Load file image from file. - self->texture->width = qoi_image.header.width; - self->texture->height = qoi_image.header.height; - self->texture->mip_levels = 1; - - pixels = qoi_image.pixels; - } - - // Load file image into a vulkan buffer. - size_t image_size{static_cast<size_t>( - qoi_image.header.width * qoi_image.header.height * num_channels)}; - VK::SourceBuffer source_image_buffer{ - cg_core.vk_device_with_swapchain, pixels, image_size}; - - { // Create vulkan image. - try - { - create_vulkan_image( - &self->texture->image, - &self->texture->device_memory, - self->texture->width, - self->texture->height, - self->texture->mip_levels); - } - catch(VK::Image::Error error) - { - throw CommandError{error.what()}; - } - } - - // Copy image from vulkan buffer into vulkan image. - { - auto queue_family = self->texture->queue_family; - auto queue{queue_family->get_queue()}; - VK::CommandPool command_pool{queue_family, 1}; - VkCommandBuffer vk_command_buffer{command_pool.command_buffers[0]}; - - queue.submit_one_time_command(vk_command_buffer, [&](){ - VK::Image::move_image_state( - vk_command_buffer, self->texture->image, VK_FORMAT_R8G8B8A8_UNORM, - 0, VK_ACCESS_TRANSFER_WRITE_BIT, - VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); - - VkBufferImageCopy image_copy{}; - image_copy.bufferOffset = 0; - image_copy.bufferRowLength = 0; - image_copy.bufferImageHeight = 0; - image_copy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - image_copy.imageSubresource.mipLevel = 0; - image_copy.imageSubresource.baseArrayLayer = 0; - image_copy.imageSubresource.layerCount = 1; - image_copy.imageOffset = {0, 0, 0}; - image_copy.imageExtent = { - self->texture->width, self->texture->height, 1}; - - vkCmdCopyBufferToImage( - vk_command_buffer, source_image_buffer.buffer, self->texture->image, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &image_copy); - - VK::Image::move_image_state( - vk_command_buffer, self->texture->image, VK_FORMAT_R8G8B8A8_UNORM, - VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); - }); - } -} - -void -unload_image(void *obj) -{ - auto self = static_cast<ImageBuilder*>(obj); - - vkDestroyImage( - cg_core.vk_device_with_swapchain->device, self->texture->image, nullptr); - vkFreeMemory( - cg_core.vk_device_with_swapchain->device, self->texture->device_memory, - nullptr); -} - -void -load_sampler(void *obj) -{ - auto self = static_cast<ImageBuilder*>(obj); - - VkSamplerCreateInfo sampler_info{}; - sampler_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; - sampler_info.pNext = nullptr; - sampler_info.flags = 0; - sampler_info.magFilter = VK_FILTER_LINEAR; - sampler_info.minFilter = VK_FILTER_LINEAR; - sampler_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; - sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; - sampler_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; - sampler_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; - sampler_info.mipLodBias = 0.0f; - sampler_info.anisotropyEnable = VK_TRUE; - sampler_info.maxAnisotropy = 16; - sampler_info.compareEnable = VK_FALSE; - sampler_info.compareOp = VK_COMPARE_OP_NEVER; - sampler_info.minLod = 0.0f; - sampler_info.maxLod = 0.0f; - sampler_info.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; - sampler_info.unnormalizedCoordinates = VK_FALSE; - - if(vkCreateSampler( - cg_core.vk_device_with_swapchain->device, &sampler_info, nullptr, - &self->texture->sampler) != VK_SUCCESS) - throw CommandError{"Failed to create texture sampler."}; -} - -void -unload_sampler(void *obj) -{ - auto self = static_cast<ImageBuilder*>(obj); - - vkDestroySampler( - cg_core.vk_device_with_swapchain->device, self->texture->sampler, nullptr); -} - -void -load_view(void *obj) -{ - auto self = static_cast<ImageBuilder*>(obj); - - try - { - VK::Image::create_view( - cg_core.vk_device_with_swapchain, &self->texture->view, - self->texture->image, - VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_ASPECT_COLOR_BIT); - } - catch(VK::Image::Error error) - { - throw CommandError{error.what()}; - } -} - -void -unload_view(void *obj) -{ - auto self = static_cast<ImageBuilder*>(obj); - - vkDestroyImageView( - cg_core.vk_device_with_swapchain->device, self->texture->view, nullptr); -} - -const CommandChain image_loader{ - {&load_image, &unload_image}, - {&load_sampler, &unload_sampler}, - {&load_view, &unload_view} -}; - -struct CharacterToDraw -{ - int pos_x; - std::shared_ptr<VK::Character> character; - - CharacterToDraw(int x, std::shared_ptr<VK::Character> character): - pos_x{x}, - character{character} - {}; -}; - -struct TextTextureBuilder: public ImageBuilder -{ - VK::Font *font; - const char* str; - uint32_t max_bearing_y; - std::vector<CharacterToDraw> chars_to_draw; - - TextTextureBuilder(VK::Texture *texture, VK::Font *font, const char* str): - font{font}, - str{str} - { - this->texture = texture; - } -}; - -void -load_text_proportions(void *obj) -{ - auto self = static_cast<TextTextureBuilder*>(obj); - - uint32_t texture_width{0}, texture_descender{0}; - auto unicode_text{VK::Character::str_to_unicode(self->str)}; - - auto first_image{self->font->character(unicode_text[0])}; - if(first_image->bearing_x < 0) texture_width = - first_image->bearing_x; - - self->max_bearing_y = 0; - self->chars_to_draw.reserve(unicode_text.size()); - - // FIXME: I need to test several different fonts to find all bugs in this - // code. - std::shared_ptr<VK::Character> char_image{}; - { // Calculate image size - int max_height; - for(auto char_code : unicode_text) - { - char_image = self->font->character(char_code); - uint32_t descender{char_image->height - char_image->bearing_y}; - uint32_t pos_x{texture_width + char_image->bearing_x}; - - if(char_image->image != VK_NULL_HANDLE) - self->chars_to_draw.emplace_back(pos_x, char_image); - - if(char_image->bearing_y > self->max_bearing_y) - self->max_bearing_y = char_image->bearing_y; - if(descender > texture_descender) texture_descender = descender; - - texture_width += char_image->advance; - } - } - - { // Restore image width if last character have a negative bearing. - int bearing_x_pluss_width = char_image->bearing_x + char_image->width; - if(bearing_x_pluss_width > char_image->advance) - texture_width += bearing_x_pluss_width - char_image->advance; - } - - self->texture->width = texture_width; - self->texture->height = self->max_bearing_y + texture_descender; - self->texture->mip_levels = 1; -} - -void -load_text_image(void *obj) -{ - auto self = static_cast<TextTextureBuilder*>(obj); - - const int NumChannels = 4; - - size_t image_size{static_cast<size_t>( - self->texture->width * self->texture->height * NumChannels)}; - std::vector<unsigned char> pixels(image_size); - for(auto x{0}; x < self->texture->width; x++) - { - for(auto y{0}; y < self->texture->height; y++) - { - auto image_coord = y * self->font->face->glyph->bitmap.width + - x * NumChannels; - pixels[image_coord] = 0; // Red - pixels[image_coord + 1] = 0; // Green - pixels[image_coord + 2] = 0; // Blue - pixels[image_coord + 3] = 0; // Alpha - } - } - VK::SourceBuffer source_image_buffer{ - cg_core.vk_device_with_swapchain, pixels.data(), image_size}; - - { // Create vulkan image. - try - { - create_vulkan_image( - &self->texture->image, - &self->texture->device_memory, - self->texture->width, - self->texture->height, - self->texture->mip_levels); - } - catch(VK::Image::Error error) - { - throw CommandError{error.what()}; - } - } - - { // Render text - auto queue_family{ - cg_core.vk_device_with_swapchain->get_queue_family_with_presentation()}; - auto queue{queue_family->get_queue()}; - VK::CommandPool command_pool{queue_family, 1}; - VkCommandBuffer vk_command_buffer{command_pool.command_buffers[0]}; - - queue.submit_one_time_command(vk_command_buffer, [&](){ - VK::Image::move_image_state( - vk_command_buffer, self->texture->image, VK_FORMAT_R8G8B8A8_UNORM, - 0, VK_ACCESS_TRANSFER_WRITE_BIT, - VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); - - VkBufferImageCopy image_copy{}; - image_copy.bufferOffset = 0; - image_copy.bufferRowLength = 0; - image_copy.bufferImageHeight = 0; - image_copy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - image_copy.imageSubresource.mipLevel = 0; - image_copy.imageSubresource.baseArrayLayer = 0; - image_copy.imageSubresource.layerCount = 1; - image_copy.imageOffset = {0, 0, 0}; - image_copy.imageExtent = {self->texture->width, self->texture->height, 1}; - - vkCmdCopyBufferToImage( - vk_command_buffer, source_image_buffer.buffer, self->texture->image, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &image_copy); - - for(auto &to_draw: self->chars_to_draw) - { - VkImageSubresourceLayers - source_subresources{}, destination_subresources{}; - source_subresources.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - source_subresources.mipLevel = 0; - source_subresources.baseArrayLayer = 0; - source_subresources.layerCount = 1; - - destination_subresources.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - destination_subresources.mipLevel = 0; - destination_subresources.baseArrayLayer = 0; - destination_subresources.layerCount = 1; - - VkImageCopy image_copy{}; - image_copy.srcSubresource = source_subresources; - image_copy.srcOffset = {0, 0, 0}; - image_copy.dstSubresource = destination_subresources; - image_copy.dstOffset = { - to_draw.pos_x, - (int)(self->max_bearing_y - to_draw.character->bearing_y), - 0}; - image_copy.extent = { - to_draw.character->width, to_draw.character->height, 1}; - - vkCmdCopyImage( - vk_command_buffer, - to_draw.character->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - self->texture->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - 1, &image_copy); - } - - VK::Image::move_image_state( - vk_command_buffer, self->texture->image, VK_FORMAT_R8G8B8A8_UNORM, - VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); - }); - } -} - -const CommandChain text_loader{ - {&load_text_proportions, nullptr}, - {&load_text_image, &unload_image}, - {&load_sampler, &unload_sampler}, - {&load_view, &unload_view} -}; - -void -load_descriptor_set_pool(void *obj) -{ - auto self = static_cast<VK::Texture*>(obj); - - std::array<VkDescriptorPoolSize, 1> descriptor_pool_sizes{}; - descriptor_pool_sizes[0].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - descriptor_pool_sizes[0].descriptorCount = - cg_core.vk_swapchain->images_count; - - VkDescriptorPoolCreateInfo pool_info{}; - pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - pool_info.pNext = nullptr; - pool_info.flags = 0; - pool_info.maxSets = cg_core.vk_swapchain->images_count; - pool_info.poolSizeCount = descriptor_pool_sizes.size(); - pool_info.pPoolSizes = descriptor_pool_sizes.data(); - - if(vkCreateDescriptorPool( - self->queue_family->device->device, &pool_info, nullptr, - &self->descriptor_pool) != VK_SUCCESS) - throw CommandError{"Failed to create a Vulkan descriptor pool."}; -} - -void -unload_descriptor_set_pool(void *obj) -{ - auto self = static_cast<VK::Texture*>(obj); - - vkDestroyDescriptorPool( - self->queue_family->device->device, self->descriptor_pool, nullptr); -} - -void -load_descriptor_sets(void *obj) -{ - auto self = static_cast<VK::Texture*>(obj); - - std::vector<VkDescriptorSetLayout> layouts( - cg_core.vk_swapchain->images_count, - cg_core.vk_descriptor_set_layout->texture); - - VkDescriptorSetAllocateInfo alloc_info{}; - alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; - alloc_info.descriptorPool = self->descriptor_pool; - alloc_info.descriptorSetCount = layouts.size(); - alloc_info.pSetLayouts = layouts.data(); - - self->descriptor_sets.resize(layouts.size()); - if(vkAllocateDescriptorSets( - self->queue_family->device->device, &alloc_info, - self->descriptor_sets.data()) != VK_SUCCESS) - CommandError{"Failed to create Vulkan descriptor set."}; -} - -void -load_data_to_descriptor_sets(void *obj) -{ - auto self = static_cast<VK::Texture*>(obj); - - for(auto i{0}; i < cg_core.vk_swapchain->images_count; i++) - { - VkDescriptorImageInfo image_info{}; - image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - image_info.imageView = self->view; - image_info.sampler = self->sampler; - - std::array<VkWriteDescriptorSet, 1> write_descriptors{}; - write_descriptors[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - write_descriptors[0].dstSet = self->descriptor_sets[i]; - write_descriptors[0].dstBinding = 0; - write_descriptors[0].dstArrayElement = 0; - write_descriptors[0].descriptorCount = 1; - write_descriptors[0].descriptorType = - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - write_descriptors[0].pBufferInfo = nullptr; - write_descriptors[0].pImageInfo = &image_info; - write_descriptors[0].pTexelBufferView = nullptr; - - vkUpdateDescriptorSets( - cg_core.vk_device_with_swapchain->device, write_descriptors.size(), - write_descriptors.data(), 0, nullptr); - } -} - -const CommandChain descriptor_loader{ - {&load_descriptor_set_pool, &unload_descriptor_set_pool}, - {&load_descriptor_sets, nullptr}, - {&load_data_to_descriptor_sets, nullptr} -}; - -} - -namespace VK -{ - -Texture::Texture(Font *font, const char* str) -{ - this->queue_family = - cg_core.vk_device_with_swapchain->get_queue_family_with_presentation(); - - TextTextureBuilder text_builder(this, font, str); - text_loader.execute(&text_builder); - descriptor_loader.execute(this); -} - -Texture::Texture(std::string texture_path) -{ - this->queue_family = - cg_core.vk_device_with_swapchain->get_queue_family_with_presentation(); - - ImageTextureBuilder texture_builder(this, texture_path); - image_loader.execute(&texture_builder); - descriptor_loader.execute(this); -} - -Texture::Texture(const char* texture_path): - Texture{std::string(texture_path)} -{ -} - -Texture::~Texture() -{ - ImageTextureBuilder texture_builder(this, ""); - image_loader.revert(&texture_builder); - descriptor_loader.revert(this); -} - -} diff --git a/src/vk/texture.hpp b/src/vk/texture.hpp deleted file mode 100644 index 22711eb..0000000 --- a/src/vk/texture.hpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2022-2023 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. - */ - -#ifndef CANDY_GEAR_VK_TEXTURE_H -#define CANDY_GEAR_VK_TEXTURE_H 1 - -#include <string> - -#include "core.hpp" -#include "font.hpp" -#include "queue_family.hpp" - -namespace VK -{ - -struct Texture -{ - QueueFamily *queue_family; - - VkImage image; - VkSampler sampler; - VkImageView view; - VkDeviceMemory device_memory; - uint32_t width, height; - uint32_t mip_levels; - - VkDescriptorPool descriptor_pool; - std::vector<VkDescriptorSet> descriptor_sets; - - Texture(Font *font, const char *str); - Texture(std::string texture_path); - Texture(const char* texture_path); - ~Texture(); -}; - -} - -#endif /* CANDY_GEAR_TEXTURE_H */ diff --git a/src/vk/uniform_buffer.cpp b/src/vk/uniform_buffer.cpp deleted file mode 100644 index dd61898..0000000 --- a/src/vk/uniform_buffer.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2022 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 "uniform_buffer.hpp" - -#include <cstring> -#include <stdexcept> - -namespace VK -{ - -UniformBuffer::UniformBuffer(Device *device, VkDeviceSize data_size) -{ - this->device = device; - this->device_size = data_size; - this->buffer_usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; - this->memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | - VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; - - try - { - BaseBuffer::loader.execute(static_cast<BaseBuffer*>(this)); - } - catch(const CommandError &command_error) - { - std::string error{"Could not initialize Vulkan uniform buffer → "}; - error += command_error.what(); - throw CommandError{error}; - } -} - -UniformBuffer::~UniformBuffer() -{ - BaseBuffer::loader.revert(static_cast<BaseBuffer*>(this)); -} - -UniformBuffer::UniformBuffer(UniformBuffer &&that) -{ - this->device = that.device; - this->buffer = that.buffer; - this->device_memory = that.device_memory; - this->device_size = that.device_size; - this->buffer_usage = that.buffer_usage; - this->memory_properties = that.memory_properties; - - that.buffer = VK_NULL_HANDLE; - that.device_memory = VK_NULL_HANDLE; -} - -UniformBuffer& -UniformBuffer::operator=(UniformBuffer &&that) -{ - this->device = that.device; - this->buffer = that.buffer; - this->device_memory = that.device_memory; - this->device_size = that.device_size; - this->buffer_usage = that.buffer_usage; - this->memory_properties = that.memory_properties; - - that.buffer = VK_NULL_HANDLE; - that.device_memory = VK_NULL_HANDLE; - - return *this; -} - -void -UniformBuffer::copy_data(void *ubo) -{ - void *data; - vkMapMemory(this->device->device, this->device_memory, 0, - this->device_size, 0, &data); - memcpy(data, ubo, this->device_size); - vkUnmapMemory(this->device->device, this->device_memory); -} - -} diff --git a/src/vk/uniform_buffer.hpp b/src/vk/uniform_buffer.hpp deleted file mode 100644 index e978894..0000000 --- a/src/vk/uniform_buffer.hpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2022 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. - */ - -#ifndef CANDY_GEAR_VK_UNIFORM_BUFFER_H -#define CANDY_GEAR_VK_UNIFORM_BUFFER_H 1 - -#include <memory> - -#include "core.hpp" - -#include "base_buffer.hpp" - -namespace VK -{ - -// FIXME: this class need to delete or create custom copy constructors! -class UniformBuffer: public BaseBuffer -{ - UniformBuffer(const UniformBuffer &t) = delete; - UniformBuffer& - operator=(const UniformBuffer &t) = delete; - -public: - UniformBuffer(Device *device, VkDeviceSize data_size); - ~UniformBuffer(); - - UniformBuffer(UniformBuffer &&that); - UniformBuffer& - operator=(UniformBuffer &&that); - - void copy_data(void* ubo); -}; - -} - -#endif /* CANDY_GEAR_VK_UNIFORM_BUFFER_H */ diff --git a/src/vk/uniform_data_object.hpp b/src/vk/uniform_data_object.hpp deleted file mode 100644 index 5cc22cb..0000000 --- a/src/vk/uniform_data_object.hpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2022-2023 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. - */ - -#ifndef CANDY_GEAR_VK_UNIFORM_DATA_OBJECT_H -#define CANDY_GEAR_VK_UNIFORM_DATA_OBJECT_H 1 - -#include "core.hpp" -#include "skeletal_mesh_vertex.hpp" - -namespace VK -{ - -// UDO = "uniform data object" - -struct UDOView2D -{ - glm::mat4 proj; -}; - -struct UDOView3D -{ - glm::mat4 view; - glm::mat4 proj; -}; - -struct UDOWorld3D_Vert -{ - glm::vec4 ambient_light_color; -}; - -struct UDOWorld3D_Frag -{ - glm::vec3 directional_light_direction; - glm::vec4 directional_light_color; -}; - -struct UDOStaticModel -{ - glm::mat4 base_matrix; -}; - -struct UDOSkeletalModel -{ - glm::mat4 base_matrix; - glm::mat4 bone_matrices[SKELETAL_MESH_MAX_NUM_OF_BONES]; -}; - -struct UDOVector4D -{ - glm::vec4 vector; -}; - -struct UDOVector3D -{ - glm::vec3 vectors; -}; - -struct UDOSprite3D -{ - glm::vec3 position; - uint32_t padding; - glm::vec2 size; -}; - -} - -#endif /* CANDY_GEAR_VK_UNIFORM_DATA_OBJECT_H */ diff --git a/src/vk/view_2d.cpp b/src/vk/view_2d.cpp deleted file mode 100644 index c628a18..0000000 --- a/src/vk/view_2d.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright 2022-2023 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 "view_2d.hpp" - -#include <array> - -#include "../core.hpp" -#include "uniform_data_object.hpp" - -namespace -{ - -void -load_2d_uniform_buffer(void *obj) -{ - auto self = static_cast<VK::View2D*>(obj); - - try - { - self->ub_2d.reserve(cg_core.vk_swapchain->images_count); - for(auto i{0}; i < cg_core.vk_swapchain->images_count; i++) - self->ub_2d.emplace_back( - cg_core.vk_device_with_swapchain, sizeof(VK::UDOView2D)); - } - catch(const std::exception& e) - { - throw CommandError{e.what()}; - } -} - -void -unload_2d_uniform_buffer(void *obj) -{ - auto self = static_cast<VK::View2D*>(obj); - - self->ub_2d.clear(); -} - -void -load_descriptor_sets_2d(void *obj) -{ - auto self = static_cast<VK::View2D*>(obj); - - std::vector<VkDescriptorSetLayout> layouts( - cg_core.vk_swapchain->images_count, - cg_core.vk_descriptor_set_layout->view); - - VkDescriptorSetAllocateInfo alloc_info{}; - alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; - alloc_info.descriptorPool = self->descriptor_pool; - alloc_info.descriptorSetCount = layouts.size(); - alloc_info.pSetLayouts = layouts.data(); - - self->descriptor_sets_2d.resize(layouts.size()); - if(vkAllocateDescriptorSets( - cg_core.vk_device_with_swapchain->device, &alloc_info, - self->descriptor_sets_2d.data()) != VK_SUCCESS) - throw CommandError{"Failed to create Vulkan descriptor sets for view."}; -} - -void -load_resources_to_descriptor_sets_2d(void *obj) -{ - auto self = static_cast<VK::View2D*>(obj); - - for(auto i{0}; i < self->ub_2d.size(); i++) - { - VkDescriptorBufferInfo view_2d_info{}; - view_2d_info.buffer = self->ub_2d[i].buffer; - view_2d_info.offset = 0; - view_2d_info.range = sizeof(VK::UDOView2D); - - std::array<VkWriteDescriptorSet, 1> write_descriptors{}; - write_descriptors[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - write_descriptors[0].dstSet = self->descriptor_sets_2d[i]; - write_descriptors[0].dstBinding = 0; - write_descriptors[0].dstArrayElement = 0; - write_descriptors[0].descriptorCount = 1; - write_descriptors[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - write_descriptors[0].pBufferInfo = &view_2d_info; - write_descriptors[0].pImageInfo = nullptr; - write_descriptors[0].pTexelBufferView = nullptr; - - vkUpdateDescriptorSets( - cg_core.vk_device_with_swapchain->device, write_descriptors.size(), - write_descriptors.data(), 0, nullptr); - - VK::UDOView2D ubo_view_2d; - ubo_view_2d.proj = glm::ortho( - 0.0f, self->projection_width, - 0.0f, self->projection_height, - 0.0f, 100.0f); - self->ub_2d[i].copy_data(&ubo_view_2d); - } -} - -} - -namespace VK -{ - -const CommandChain View2D::loader{ - {&load_2d_uniform_buffer, &unload_2d_uniform_buffer} -}; - -const CommandChain View2D::descriptor_sets_loader{ - {&load_descriptor_sets_2d, nullptr}, - {&load_resources_to_descriptor_sets_2d, nullptr} -}; - -View2D::View2D( - glm::vec4 region, float projection_width, float projection_height): - projection_width{projection_width}, - projection_height{projection_height}, - region{region}, - descriptor_pool{VK_NULL_HANDLE}, - rectangles_to_draw{cg_core.vk_swapchain->images_count}, - sprites_to_draw{cg_core.vk_swapchain->images_count} -{ - loader.execute(this); -} - -View2D::~View2D() -{ - loader.revert(this); -} - -void -View2D::load_descriptor_sets(VkDescriptorPool descriptor_pool) -{ - if(this->descriptor_pool != VK_NULL_HANDLE) return; - - this->descriptor_pool = descriptor_pool; - descriptor_sets_loader.execute(this); -} - -void -View2D::unload_descriptor_sets() -{ - if(this->descriptor_pool == VK_NULL_HANDLE) return; - - this->descriptor_pool = VK_NULL_HANDLE; - descriptor_sets_loader.revert(this); -} - -} diff --git a/src/vk/view_2d.hpp b/src/vk/view_2d.hpp deleted file mode 100644 index ead21e2..0000000 --- a/src/vk/view_2d.hpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2022 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. - */ - -#ifndef CANDY_GEAR_VK_VIEW_2D_H -#define CANDY_GEAR_VK_VIEW_2D_H 1 - -#include <memory> -#include <unordered_map> -#include <vector> - -#include "core.hpp" -#include "sprite_to_draw.hpp" -#include "rectangle.hpp" - -namespace VK -{ - -struct View2D -{ - glm::vec4 region; - float projection_width, projection_height; - - // FIXME: if these vectors get resized, they can cause a segmentation fault! - std::vector<UniformBuffer> ub_2d; - - VkDescriptorPool descriptor_pool; - std::vector<VkDescriptorSet> descriptor_sets_2d; - - std::vector<std::vector<Rectangle>> rectangles_to_draw; - std::vector<std::vector<SpriteToDraw>> sprites_to_draw; - - View2D(glm::vec4 region, float projection_width, float projection_height); - virtual ~View2D(); - - void - virtual load_descriptor_sets(VkDescriptorPool descriptor_pool); - - void - virtual unload_descriptor_sets(); - -protected: - static const CommandChain loader, descriptor_sets_loader; -}; - -} - -#endif /* CANDY_GEAR_VK_VIEW_2D_H */ diff --git a/src/vk/view_3d.cpp b/src/vk/view_3d.cpp deleted file mode 100644 index 273874c..0000000 --- a/src/vk/view_3d.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright 2022-2023 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 "view_3d.hpp" - -#include <array> - -#include "../core.hpp" -#include "uniform_data_object.hpp" - -namespace -{ - -void -load_3d_uniform_buffer(void *obj) -{ - auto self = static_cast<VK::View3D*>(obj); - - try - { - self->ub_3d.reserve(cg_core.vk_swapchain->images_count); - for(auto i{0}; i < cg_core.vk_swapchain->images_count; i++) - self->ub_3d.emplace_back( - cg_core.vk_device_with_swapchain, sizeof(VK::UDOView3D)); - } - catch(const std::exception& e) - { - throw CommandError{e.what()}; - } -} - -void -unload_3d_uniform_buffer(void *obj) -{ - auto self = static_cast<VK::View3D*>(obj); - - self->ub_3d.clear(); -} - -void -load_descriptor_sets_3d(void *obj) -{ - auto self = static_cast<VK::View3D*>(obj); - - std::vector<VkDescriptorSetLayout> layouts( - cg_core.vk_swapchain->images_count, - cg_core.vk_descriptor_set_layout->view); - - VkDescriptorSetAllocateInfo alloc_info{}; - alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; - alloc_info.descriptorPool = self->descriptor_pool; - alloc_info.descriptorSetCount = layouts.size(); - alloc_info.pSetLayouts = layouts.data(); - - self->descriptor_sets_3d.resize(layouts.size()); - if(vkAllocateDescriptorSets( - cg_core.vk_device_with_swapchain->device, &alloc_info, - self->descriptor_sets_3d.data()) != VK_SUCCESS) - throw CommandError{"Failed to create Vulkan descriptor sets for view."}; -} - -void -load_resources_to_descriptor_sets_3d(void *obj) -{ - auto self = static_cast<VK::View3D*>(obj); - - for(auto i{0}; i < self->ub_3d.size(); i++) - { - VkDescriptorBufferInfo view_3d_info{}; - view_3d_info.buffer = self->ub_3d[i].buffer; - view_3d_info.offset = 0; - view_3d_info.range = sizeof(VK::UDOView3D); - - std::array<VkWriteDescriptorSet, 1> write_descriptors{}; - write_descriptors[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - write_descriptors[0].dstSet = self->descriptor_sets_3d[i]; - write_descriptors[0].dstBinding = 0; - write_descriptors[0].dstArrayElement = 0; - write_descriptors[0].descriptorCount = 1; - write_descriptors[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - write_descriptors[0].pBufferInfo = &view_3d_info; - write_descriptors[0].pImageInfo = nullptr; - write_descriptors[0].pTexelBufferView = nullptr; - - vkUpdateDescriptorSets( - cg_core.vk_device_with_swapchain->device, write_descriptors.size(), - write_descriptors.data(), 0, nullptr); - } -} - -const CommandChain loader{ - {&load_3d_uniform_buffer, &unload_3d_uniform_buffer} -}; - -const CommandChain descriptor_sets_loader{ - {&load_descriptor_sets_3d, nullptr}, - {&load_resources_to_descriptor_sets_3d, nullptr} -}; - -} - -namespace VK -{ - -View3D::View3D( - glm::vec4 region, float projection_width, float projection_height): - View2D{region, projection_width, projection_height}, - field_of_view{45.0f}, - camera_position{std::make_shared<glm::vec3>(0.0f, 0.0f, 0.0f)}, - camera_orientation{std::make_shared<glm::quat>(0.0f, 0.0f, 0.0f, 0.0f)} -{ - ::loader.execute(this); -} - -View3D::~View3D() -{ - ::loader.revert(this); -} - -void -View3D::load_descriptor_sets(VkDescriptorPool descriptor_pool) -{ - if(this->descriptor_pool != VK_NULL_HANDLE) return; - - auto parent = dynamic_cast<VK::View2D*>(this); - this->descriptor_pool = descriptor_pool; - View2D::descriptor_sets_loader.execute(parent); - ::descriptor_sets_loader.execute(this); -} - -void -View3D::unload_descriptor_sets() -{ - if(this->descriptor_pool == VK_NULL_HANDLE) return; - - auto parent = dynamic_cast<VK::View2D*>(this); - this->descriptor_pool = VK_NULL_HANDLE; - ::descriptor_sets_loader.revert(this); - View2D::descriptor_sets_loader.revert(parent); -} - -} diff --git a/src/vk/view_3d.hpp b/src/vk/view_3d.hpp deleted file mode 100644 index c5a803b..0000000 --- a/src/vk/view_3d.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2022 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. - */ - -#ifndef CANDY_GEAR_VK_VIEW_3D_H -#define CANDY_GEAR_VK_VIEW_3D_H 1 - -#include "view_2d.hpp" - -namespace VK -{ - -struct View3D: public View2D -{ - float field_of_view; - // FIXME: if this vector get resized, it can cause a segmentation fault! - std::vector<UniformBuffer> ub_3d; - - std::vector<VkDescriptorSet> descriptor_sets_3d; - - std::shared_ptr<glm::vec3> camera_position; - std::shared_ptr<glm::quat> camera_orientation; - - View3D(glm::vec4 region, float projection_width, float projection_height); - ~View3D(); - - void - load_descriptor_sets(VkDescriptorPool descriptor_pool); - - void - unload_descriptor_sets(); -}; - -} - -#endif /* CANDY_GEAR_VK_VIEW_3D_H */ |