Browse Source

added device class

Jef Belmans 2 years ago
parent
commit
e29f87e8e6

+ 5 - 0
coral_renderer/CMakeLists.txt

@@ -6,6 +6,11 @@ add_executable(coral_renderer
     "first_app.cpp"
     "coral_pipeline.h"
     "coral_pipeline.cpp"
+    "coral_device.h"
+    "coral_device.cpp"
+    "vk_initializers.h"
+    "vk_initializers.cpp"
+    "vk_types.h"
 )
 
 add_dependencies(coral_renderer Shaders)

+ 439 - 0
coral_renderer/coral_device.cpp

@@ -0,0 +1,439 @@
+#include "coral_device.h"
+
+// STD
+#include <iostream>
+#include <set>
+#include <unordered_set>
+
+#include <VkBootstrap.h>
+#include "vk_initializers.h"
+
+#define VMA_IMPLEMENTATION
+#include "vk_mem_alloc.h"
+
+using namespace coral_3d;
+
+coral_device::coral_device(coral_window& window) : window_{ window }
+{
+    create_instance();
+    create_command_pool();
+    create_command_buffers();
+}
+
+coral_device::~coral_device()
+{
+    // Wait for the GPU to be done with the last frame
+    vkDeviceWaitIdle(device_);
+
+    deletion_queue_.flush();
+
+    vkDestroyDevice(device_, nullptr);
+    vkDestroySurfaceKHR(instance_, surface_, nullptr);
+    vkb::destroy_debug_utils_messenger(instance_, debug_messenger_);
+    vkDestroyInstance(instance_, nullptr);
+}
+
+uint32_t coral_device::find_memory_type(uint32_t type_filter, VkMemoryPropertyFlags properties)
+{
+    VkPhysicalDeviceMemoryProperties mem_properties;
+    vkGetPhysicalDeviceMemoryProperties(physical_device_, &mem_properties);
+
+    for (uint32_t i = 0; i < mem_properties.memoryTypeCount; i++)
+    {
+        if ((type_filter & (1 << i)) &&
+            (mem_properties.memoryTypes[i].propertyFlags & properties) == properties)
+        {
+            return i;
+        }
+    }
+
+    throw std::runtime_error("failed to find suitable memory type!");
+}
+
+VkFormat coral_device::find_supported_format(const std::vector<VkFormat>& candidates, VkImageTiling tiling, VkFormatFeatureFlags features)
+{
+    for (VkFormat format : candidates)
+    {
+        VkFormatProperties props;
+        vkGetPhysicalDeviceFormatProperties(physical_device_, format, &props);
+
+        if (tiling == VK_IMAGE_TILING_LINEAR && 
+            (props.linearTilingFeatures & features) == features)
+        {
+            return format;
+        }
+        else if (tiling == VK_IMAGE_TILING_OPTIMAL &&
+            (props.optimalTilingFeatures & features) == features)
+        {
+            return format;
+        }
+    }
+        
+    throw std::runtime_error("failed to find supported format!");
+}
+
+AllocatedBuffer coral_device::create_buffer(size_t alloc_size, VkBufferUsageFlags usage, VmaMemoryUsage memory_usage)
+{
+    VkBufferCreateInfo info{};
+    info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+    info.pNext = nullptr;
+
+    info.size = alloc_size;
+    info.usage = usage;
+
+    VmaAllocationCreateInfo vma_alloc_info{};
+    vma_alloc_info.usage = memory_usage;
+
+    AllocatedBuffer new_buffer{};
+
+    if(vmaCreateBuffer(allocator_, &info, &vma_alloc_info,
+        &new_buffer.buffer,
+        &new_buffer.allocation,
+        nullptr) != VK_SUCCESS);
+    {
+        throw std::runtime_error(
+            "ERROR! coral_device::create_buffer() >> Failed to create buffer!");
+    }
+
+    return new_buffer;
+}
+
+void coral_device::immediate_submit(std::function<void(VkCommandBuffer cmd)>&& function)
+{
+    VkCommandBuffer cmd{ upload_context_.command_buffer };
+
+    // Begin command buffer recording. We use it exact once before resetting
+    VkCommandBufferBeginInfo cmd_begin_info{ vkinit::command_buffer_bi(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT) };
+    if (vkBeginCommandBuffer(cmd, &cmd_begin_info) != VK_SUCCESS)
+        throw std::runtime_error(
+            "ERROR! coral_device::immediate_submit() >> Failed to begin recording!");
+
+    // Execute function
+    function(cmd);
+
+    if(vkEndCommandBuffer(cmd) != VK_SUCCESS)
+        throw std::runtime_error(
+            "ERROR! coral_device::immediate_submit() >> Failed to end recording!");
+
+    VkSubmitInfo submit{ vkinit::submit_info(&cmd) };
+
+    // Submit command buffer to queue and execute it
+    // uploadFence will now block until the graphic commands finish execution
+    if(vkQueueSubmit(graphics_queue_, 1, &submit, upload_context_.upload_fence)
+        != VK_SUCCESS)
+        throw std::runtime_error(
+            "ERROR! coral_device::immediate_submit() >> Failed to submit commands!");
+
+    vkWaitForFences(device_, 1, &upload_context_.upload_fence, true, UINT64_MAX);
+    vkResetFences(device_, 1, &upload_context_.upload_fence);
+
+    // Reset command buffers inside the pool
+    vkResetCommandPool(device_, upload_context_.command_pool, 0);
+}
+
+void coral_device::copy_buffer(AllocatedBuffer src_buffer, AllocatedBuffer dst_buffer, VkDeviceSize size)
+{
+    immediate_submit([&](VkCommandBuffer cmd)
+        {
+            VkBufferCopy copy_region{};
+            copy_region.srcOffset = 0;  // Optional
+            copy_region.dstOffset = 0;  // Optional
+            copy_region.size = size;
+            vkCmdCopyBuffer(cmd, src_buffer.buffer, dst_buffer.buffer, 1, &copy_region);
+        });
+}
+
+void coral_device::copy_buffer_to_image(AllocatedBuffer buffer, AllocatedImage image, uint32_t width, uint32_t height, uint32_t layer_count)
+{
+    immediate_submit([&](VkCommandBuffer cmd)
+        {
+            VkBufferImageCopy copy_region{};
+            copy_region.bufferOffset = 0;
+            copy_region.bufferRowLength = 0;
+            copy_region.bufferImageHeight = 0;
+
+            copy_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+            copy_region.imageSubresource.mipLevel = 0;
+            copy_region.imageSubresource.baseArrayLayer = 0;
+            copy_region.imageSubresource.layerCount = layer_count;
+
+            copy_region.imageExtent = { width, height, 1 };
+
+            // Copy buffer to image
+            vkCmdCopyBufferToImage(cmd, buffer.buffer, image.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &copy_region);
+        });
+}
+
+void coral_device::create_instance()
+{
+    std::cout << "Creating instance...\n";
+
+    vkb::InstanceBuilder builder;
+    auto instance_desc = builder.set_app_name("Coral3D")
+        .request_validation_layers(c_enable_validation_layers_)
+        .require_api_version(1, 1, 0)
+        .use_default_debug_messenger()
+        .build();
+
+    vkb::Instance vkb_instance{instance_desc.value()};
+    instance_ = vkb_instance.instance;
+    debug_messenger_ = vkb_instance.debug_messenger;
+
+    // Check if this instance has all required extensions
+    // Will throw if not found
+    has_glfw_required_instance_extensions();
+
+    create_surface();
+
+    VkPhysicalDeviceFeatures feats{};
+    feats.multiDrawIndirect = true;
+
+    vkb::PhysicalDeviceSelector selector{vkb_instance};
+    selector.set_required_features(feats);
+
+    vkb::PhysicalDevice physical_device = selector
+        .set_minimum_version(1, 1)
+        .set_surface(surface_)
+        .select()
+        .value();
+
+    vkb::DeviceBuilder device_builder{physical_device};
+
+    VkPhysicalDeviceShaderDrawParameterFeatures shader_draw_params{};
+    shader_draw_params.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES;
+    shader_draw_params.pNext = nullptr;
+    
+    shader_draw_params.shaderDrawParameters = VK_TRUE;
+
+    vkb::Device vkb_device{device_builder.add_pNext(&shader_draw_params).build().value()};
+
+    graphics_queue_ = vkb_device.get_queue(vkb::QueueType::graphics).value();
+    present_queue_ = vkb_device.get_queue(vkb::QueueType::present).value();
+
+    device_ = vkb_device.device;
+    physical_device_ = physical_device.physical_device;
+
+    VmaAllocatorCreateInfo allocator_info{};
+    allocator_info.physicalDevice = physical_device_;
+    allocator_info.device = device_;
+    allocator_info.instance = instance_;
+    vmaCreateAllocator(&allocator_info, &allocator_);
+
+    deletion_queue_.deletors.emplace_back([=]() {
+        vmaDestroyAllocator(allocator_);
+        });
+
+    vkGetPhysicalDeviceProperties(physical_device_, &properties);
+    std::cout << "physical device: " << properties.deviceName << std::endl;
+}
+
+void coral_device::create_surface() 
+{ 
+    window_.create_window_surface(instance_, &surface_);
+}
+
+void coral_device::create_command_pool()
+{
+    auto indices { find_physical_queue_families() };
+
+    VkCommandPoolCreateInfo graphics_pool_info{
+        vkinit::command_pool_ci(indices.graphics_family) };
+
+    // Create general pool
+    if (vkCreateCommandPool(device_, &graphics_pool_info, nullptr, &command_pool_) != VK_SUCCESS)
+        throw std::runtime_error("ERROR! coral_device::create_command_pool() >> Failed to create command pool!");
+
+    deletion_queue_.deletors.emplace_front([=]() {
+        vkDestroyCommandPool(device_, command_pool_, nullptr);
+        });
+
+    // Create pool for upload context, used for immediate commands
+    if (vkCreateCommandPool(device_, &graphics_pool_info, nullptr, &upload_context_.command_pool)
+        != VK_SUCCESS)
+    {
+        throw std::runtime_error(
+            "ERROR! coral_device::create_command_pool() >> Failed to create upload command pool!");
+    }
+
+    deletion_queue_.deletors.emplace_back([=]() {
+        vkDestroyCommandPool(device_, upload_context_.command_pool, nullptr);
+        });
+}
+
+void coral_3d::coral_device::create_command_buffers()
+{
+    auto indices{ find_physical_queue_families() };
+   
+    // Allocate default command buffer that we will use for immediate commands
+    VkCommandBufferAllocateInfo alloc_info{
+        vkinit::command_buffer_ai(upload_context_.command_pool, 1) };
+    if (vkAllocateCommandBuffers(device_, &alloc_info, &upload_context_.command_buffer)
+        != VK_SUCCESS)
+    {
+        throw std::runtime_error(
+            "ERROR! coral_device::create_command_buffers() >> Failed to create upload command buffer!");
+    }
+}
+
+std::vector<const char*> coral_device::get_required_extensions()
+{
+    uint32_t glfw_extension_count = 0;
+    const char** glfw_extensions;
+    glfw_extensions = glfwGetRequiredInstanceExtensions(&glfw_extension_count);
+
+    std::vector<const char*> extensions(glfw_extensions, glfw_extensions + glfw_extension_count);
+
+    if (c_enable_validation_layers_)
+    {
+        extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
+    }
+
+    return extensions;
+}
+
+bool coral_device::check_validation_layer_support()
+{
+    uint32_t layer_count;
+    vkEnumerateInstanceLayerProperties(&layer_count, nullptr);
+
+    std::vector<VkLayerProperties> available_layers(layer_count);
+    vkEnumerateInstanceLayerProperties(&layer_count, available_layers.data());
+
+    for (const char* layer_name : c_validation_layers)
+    {
+        bool layer_found = false;
+
+        for (const auto& layer_properties : available_layers)
+        {
+            if (strcmp(layer_name, layer_properties.layerName) == 0)
+            {
+                layer_found = true;
+                break;
+            }
+        }
+
+        if (!layer_found) return false;
+    }
+
+    return true;
+}
+
+QueueFamilyIndices coral_device::find_queue_families(VkPhysicalDevice device)
+{
+    QueueFamilyIndices indices;
+
+    uint32_t queue_family_count = 0;
+    vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_family_count, nullptr);
+
+    std::vector<VkQueueFamilyProperties> queue_families(queue_family_count);
+    vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_family_count, queue_families.data());
+
+    int i = 0;
+    for (const auto& queue_family : queue_families)
+    {
+        if (queue_family.queueCount > 0 && 
+            queue_family.queueFlags & VK_QUEUE_GRAPHICS_BIT)
+        {
+            indices.graphics_family = i;
+            indices.graphics_family_has_value = true;
+        }
+
+        VkBool32 presentSupport = false;
+        vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface_, &presentSupport);
+
+        if (queue_family.queueCount > 0 &&
+            presentSupport)
+        {
+            indices.present_family = i;
+            indices.present_family_has_value = true;
+        }
+
+        if (indices.is_complete()) break;
+
+        i++;
+    }
+
+    return indices;
+}
+
+void coral_device::has_glfw_required_instance_extensions()
+{
+    uint32_t extension_count = 0;
+    vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr);
+    std::vector<VkExtensionProperties> extensions(extension_count);
+    vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, extensions.data());
+
+    std::cout << "available extensions:" << std::endl;
+    std::unordered_set<std::string> available;
+
+    for (const auto& extension : extensions)
+    {
+        std::cout << "\t" << extension.extensionName << std::endl;
+        available.insert(extension.extensionName);
+    }
+
+    std::cout << "required extensions:" << std::endl;
+    auto required_extensions = get_required_extensions();
+
+    for (const auto& required : required_extensions)
+    {
+        std::cout << "\t" << required << std::endl;
+        if (available.find(required) == available.end())
+        {
+            throw std::runtime_error(
+                "ERROR! coral_device::has_glfw_required_instance_extensions() >> Missing required glfw extension.");
+        }
+    }
+}
+
+bool coral_device::check_device_extension_support(VkPhysicalDevice device)
+{
+    uint32_t extension_count;
+    vkEnumerateDeviceExtensionProperties(device, nullptr, &extension_count, nullptr);
+
+    std::vector<VkExtensionProperties> available_extensions(extension_count);
+    vkEnumerateDeviceExtensionProperties(
+        device,
+        nullptr,
+        &extension_count,
+        available_extensions.data());
+
+    std::set<std::string> required_extensions(c_device_extensions.begin(), c_device_extensions.end());
+
+    for (const auto& extension : available_extensions)
+    {
+        required_extensions.erase(extension.extensionName);
+    }
+
+    return required_extensions.empty();
+}
+
+SwapchainSupportDetails coral_device::query_swapchain_support(VkPhysicalDevice device)
+{
+    SwapchainSupportDetails details;
+    vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, surface_, &details.capabilities);
+
+    uint32_t format_count;
+    vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface_, &format_count, nullptr);
+
+    if (format_count != 0)
+    {
+        details.formats.resize(format_count);
+        vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface_, &format_count, details.formats.data());
+    }
+
+    uint32_t present_mode_count;
+    vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface_, &present_mode_count, nullptr);
+
+    if (present_mode_count != 0)
+    {
+        details.present_modes.resize(present_mode_count);
+        vkGetPhysicalDeviceSurfacePresentModesKHR(
+            device,
+            surface_,
+            &present_mode_count,
+            details.present_modes.data());
+    }
+
+    return details;
+}

+ 125 - 0
coral_renderer/coral_device.h

@@ -0,0 +1,125 @@
+#pragma once
+
+#include "coral_window.h"
+
+#include <vk_mem_alloc.h>
+
+#include <string>
+#include <vector>
+#include <deque>
+#include <functional>
+
+#include "vk_types.h"
+
+namespace coral_3d
+{
+	struct DeletionQueue
+	{
+		std::deque <std::function<void()>> deletors;
+
+		void flush()
+		{
+			for (auto it = deletors.rbegin(); it != deletors.rend(); it++)
+				(*it)();
+
+			deletors.clear();
+		}
+	};
+
+	struct UploadContext
+	{
+		VkFence upload_fence;
+		VkCommandPool command_pool;
+		VkCommandBuffer command_buffer;
+	};
+
+	struct SwapchainSupportDetails
+	{
+		VkSurfaceCapabilitiesKHR capabilities;
+		std::vector<VkSurfaceFormatKHR> formats;
+		std::vector<VkPresentModeKHR> present_modes;
+	};
+
+	struct QueueFamilyIndices
+	{
+		uint32_t graphics_family;
+		uint32_t present_family;
+		bool graphics_family_has_value { false };
+		bool present_family_has_value { false };
+		bool is_complete() { return graphics_family_has_value && present_family_has_value; }
+	};
+
+	class coral_device final
+	{
+	public:
+
+#ifdef NDEBUG
+		const bool c_enable_validation_layers_{false};
+#else
+		const bool c_enable_validation_layers_{ true };
+#endif
+
+		coral_device(coral_window& window);
+		~coral_device();
+
+		// Non-copyable & non-movable
+		coral_device(const coral_device&) = delete;
+		void operator=(const coral_device&) = delete;
+		coral_device(coral_device&&) = delete;
+		coral_device& operator=(coral_device&&) = delete;
+
+		VkCommandPool get_command_pool() { return command_pool_; }
+		VkDevice device() { return device_; }
+		VkSurfaceKHR surface() { return surface_; }
+		VkQueue graphics_queue() { return graphics_queue_; }
+		VkQueue present_queue() { return present_queue_; }
+
+		SwapchainSupportDetails get_swapchain_support() {};
+		uint32_t find_memory_type(uint32_t type_filter, VkMemoryPropertyFlags properties);
+		QueueFamilyIndices find_physical_queue_families() { return find_queue_families(physical_device_); }
+		VkFormat find_supported_format(
+			const std::vector<VkFormat>& candidates, VkImageTiling tiling, VkFormatFeatureFlags features);
+
+		// Buffer helpers
+		AllocatedBuffer create_buffer(size_t alloc_size, VkBufferUsageFlags usage, VmaMemoryUsage memory_usage);
+		void immediate_submit(std::function<void(VkCommandBuffer cmd)>&& function);
+		void copy_buffer(AllocatedBuffer src_buffer, AllocatedBuffer dst_buffer, VkDeviceSize size);
+		void copy_buffer_to_image(AllocatedBuffer buffer, AllocatedImage image, uint32_t width, uint32_t height, uint32_t layer_count);
+
+		VkPhysicalDeviceProperties properties;
+
+	private:
+		void create_instance();
+		void create_surface();
+		void create_command_pool();
+		void create_command_buffers();
+
+		// Helper methods
+		std::vector<const char*> get_required_extensions();
+		bool check_validation_layer_support();
+		QueueFamilyIndices find_queue_families(VkPhysicalDevice device);
+		void has_glfw_required_instance_extensions();
+		bool check_device_extension_support(VkPhysicalDevice device);
+		SwapchainSupportDetails query_swapchain_support(VkPhysicalDevice device);
+
+		DeletionQueue deletion_queue_;
+
+		// For immediate commands
+		UploadContext upload_context_;
+
+		VkInstance instance_;
+		VkDebugUtilsMessengerEXT debug_messenger_;
+		VkPhysicalDevice physical_device_ { VK_NULL_HANDLE };
+		coral_window& window_;
+		VkCommandPool command_pool_;
+
+		VmaAllocator allocator_;
+		VkDevice device_;
+		VkSurfaceKHR surface_;
+		VkQueue graphics_queue_;
+		VkQueue present_queue_;
+
+		const std::vector<const char*> c_validation_layers { "VK_LAYER_KHRONOS_validation" };
+		const std::vector<const char*> c_device_extensions { VK_KHR_SWAPCHAIN_EXTENSION_NAME };
+	};
+}

+ 27 - 3
coral_renderer/coral_pipeline.cpp

@@ -6,9 +6,18 @@
 using namespace coral_3d;
 
 coral_pipeline::coral_pipeline(
-	const std::string& vert_file_path, const std::string& frag_file_path)
+	coral_device& device,
+	const std::string& vert_file_path,
+	const std::string& frag_file_path,
+	const PipelineConfigInfo& config_info) : device_{device}
 {
-	create_graphics_pipeline(vert_file_path, frag_file_path);
+	create_graphics_pipeline(vert_file_path, frag_file_path, config_info);
+}
+
+PipelineConfigInfo coral_3d::coral_pipeline::default_pipeline_config_info(uint32_t width, uint32_t height)
+{
+	PipelineConfigInfo config_info{};
+	return config_info;
 }
 
 std::vector<char> coral_pipeline::read_file(const std::string& file_path)
@@ -31,11 +40,26 @@ std::vector<char> coral_pipeline::read_file(const std::string& file_path)
 }
 
 void coral_pipeline::create_graphics_pipeline(
-	const std::string& vert_file_path, const std::string& frag_file_path)
+	const std::string& vert_file_path,
+	const std::string& frag_file_path,
+	const PipelineConfigInfo& config_info)
 {
 	auto vertShader = read_file(vert_file_path);
 	auto fragShader = read_file(frag_file_path);
 
 	std::cout << "Vertex shader code size: " << vertShader.size() << "\n";
 	std::cout << "Frag shader code size: " << fragShader.size() << "\n";
+}
+
+void coral_3d::coral_pipeline::create_shader_module(const std::vector<char>& code, VkShaderModule* shader_module)
+{
+	VkShaderModuleCreateInfo create_info{};
+	create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
+	create_info.pNext = nullptr;
+
+	create_info.codeSize = code.size();
+	create_info.pCode = reinterpret_cast<const uint32_t*>(code.data());
+
+	if(vkCreateShaderModule(device_.device(), &create_info, nullptr, shader_module) != VK_SUCCESS)
+		throw std::runtime_error("ERROR! coral_pipeline::create_shader_module() >> Failed to create shader module!");
 }

+ 29 - 2
coral_renderer/coral_pipeline.h

@@ -1,19 +1,46 @@
 #pragma once
 
+#include "coral_device.h"
+
+// STD
 #include <string>
 #include <vector>
 
 namespace coral_3d
 {
+	struct PipelineConfigInfo{};
+
 	class coral_pipeline final
 	{
 	public:
-		coral_pipeline(const std::string& vert_file_path, const std::string& frag_file_path);
+		coral_pipeline(
+			coral_device& device,
+			const std::string& vert_file_path,
+			const std::string& frag_file_path,
+			const PipelineConfigInfo& config_info);
+
+		~coral_pipeline() {};
+
+		coral_pipeline(const coral_pipeline&) = delete;
+		coral_pipeline& operator=(const coral_pipeline&) = delete;
+
+		static PipelineConfigInfo default_pipeline_config_info(uint32_t width, uint32_t height);
 
 	private:
 		static std::vector<char> read_file(const std::string& file_path);
 		
-		void create_graphics_pipeline(const std::string& vert_file_path, const std::string& frag_file_path);
+		void create_graphics_pipeline(
+			const std::string& vert_file_path,
+			const std::string& frag_file_path,
+			const PipelineConfigInfo& config_info
+		);
+
+		void create_shader_module(const std::vector<char>& code, VkShaderModule* shader_module);
+
+		coral_device& device_;
+		VkPipeline graphics_pipeline_;
+		VkShaderModule vert_shader_module_;
+		VkShaderModule frag_shader_module_;
 	};
 }
 

+ 12 - 3
coral_renderer/coral_window.cpp

@@ -1,10 +1,12 @@
 #include "coral_window.h"
 
+#include <stdexcept>
+
 using namespace coral_3d;
 
 coral_window::coral_window(int width, int height, const std::string& name)
-	: cWidth(width)
-	, cHeight(height)
+	: c_width(width)
+	, c_height(height)
 	, window_name_(name)
 {
 	init_window();
@@ -24,5 +26,12 @@ void coral_window::init_window()
 	glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
 	glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
 
-	pWindow_ = glfwCreateWindow(cWidth, cHeight, window_name_.c_str(), nullptr, nullptr);
+	pWindow_ = glfwCreateWindow(c_width, c_height, window_name_.c_str(), nullptr, nullptr);
+}
+
+void coral_window::create_window_surface(VkInstance instance, VkSurfaceKHR* surface)
+{
+	if (glfwCreateWindowSurface(instance, pWindow_, nullptr, surface) != VK_SUCCESS)
+		throw std::runtime_error(
+			"ERROR! coral_window::create_window_surface() >> Failed to create window surface!");
 }

+ 3 - 2
coral_renderer/coral_window.h

@@ -17,10 +17,11 @@ namespace coral_3d
 		coral_window& operator=(const coral_window&) = delete;
 
 		bool should_close() { return glfwWindowShouldClose(pWindow_); }
+		void create_window_surface(VkInstance instance, VkSurfaceKHR* surface);
 
 	private:
-		const int cWidth;
-		const int cHeight;
+		const int c_width;
+		const int c_height;
 
 		std::string window_name_;
 		GLFWwindow* pWindow_;

+ 1 - 1
coral_renderer/first_app.cpp

@@ -4,7 +4,7 @@ using namespace coral_3d;
 
 void first_app::run()
 {
-	while (!coral_window_.should_close())
+	while (!window_.should_close())
 	{
 		glfwPollEvents();
 	}

+ 9 - 4
coral_renderer/first_app.h

@@ -1,7 +1,8 @@
 #pragma once
 
-#include "coral_window.h"
 #include "coral_pipeline.h"
+#include "coral_window.h"
+#include "coral_device.h"
 
 namespace coral_3d
 {
@@ -14,8 +15,12 @@ namespace coral_3d
 		void run();
 
 	private:
-		coral_window coral_window_{ WIDTH, HEIGHT, "Coral Renderer" };
-		coral_pipeline coral_pipeline_{"shaders/PosNormCol.vert.spv", "shaders/PosNormCol.frag.spv"};
-
+		coral_window window_{ WIDTH, HEIGHT, "Coral Renderer" };
+		coral_device device_{ window_ };
+		coral_pipeline coral_pipeline_{
+			device_,
+			"shaders/PosNormCol.vert.spv",
+			"shaders/PosNormCol.frag.spv",
+			coral_pipeline::default_pipeline_config_info(WIDTH, HEIGHT)};
 	};
 }

+ 313 - 0
coral_renderer/vk_initializers.cpp

@@ -0,0 +1,313 @@
+#include "vk_initializers.h"
+
+VkCommandPoolCreateInfo vkinit::command_pool_ci(uint32_t queueFamilyIndex, VkCommandPoolCreateFlags flags)
+{
+	// Create a command pool for commands submitted to the graphics queue
+	VkCommandPoolCreateInfo info{};
+	info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+	info.pNext = nullptr;
+
+	// The command pool will be one that can submit graphics commands
+	info.queueFamilyIndex = queueFamilyIndex;
+
+	// We also want the pool to allow for resetting individual command buffers
+	info.flags = flags;
+
+	return info;
+}
+
+VkCommandBufferAllocateInfo vkinit::command_buffer_ai(VkCommandPool pool, uint32_t count, VkCommandBufferLevel level)
+{
+	// Allocate the default command buffer that we will use for rendering
+	VkCommandBufferAllocateInfo info{};
+	info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+	info.pNext = nullptr;
+
+	// Commands will be made from our m_CommandPool
+	info.commandPool = pool;
+
+	// Allocate just one command buffer
+	info.commandBufferCount = count;
+
+	// The command buffer is a primary buffer (that can submit to the queue)
+	info.level = level;
+
+	return info;
+}
+
+VkCommandBufferBeginInfo vkinit::command_buffer_bi(VkCommandBufferResetFlags flags)
+{
+	VkCommandBufferBeginInfo info{};
+	info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+	info.pNext = nullptr;
+
+	info.pInheritanceInfo = nullptr;
+	info.flags = flags;
+
+	return info;
+}
+
+VkSubmitInfo vkinit::submit_info(VkCommandBuffer* cmd)
+{
+	VkSubmitInfo info{};
+	info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+	info.pNext = nullptr;
+
+	info.waitSemaphoreCount = 0;
+	info.pWaitSemaphores = nullptr;
+	info.pWaitDstStageMask = nullptr;
+	info.commandBufferCount = 1;
+	info.pCommandBuffers = cmd;
+	info.signalSemaphoreCount = 0;
+	info.pSignalSemaphores = nullptr;
+
+	return info;
+}
+
+VkFenceCreateInfo vkinit::fence_ci(VkFenceCreateFlags flags)
+{
+	VkFenceCreateInfo info = {};
+	info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
+	info.pNext = nullptr;
+	info.flags = flags;
+	return info;
+}
+
+VkSemaphoreCreateInfo vkinit::semaphore_ci(VkSemaphoreCreateFlags flags)
+{
+	VkSemaphoreCreateInfo info = {};
+	info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
+	info.pNext = nullptr;
+	info.flags = flags;
+	return info;
+}
+
+VkPipelineShaderStageCreateInfo vkinit::pipeline_shader_stage_ci(VkShaderStageFlagBits stage, VkShaderModule shaderModule)
+{
+	VkPipelineShaderStageCreateInfo info{};
+	info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
+	info.pNext = nullptr;
+
+	// Shader stage
+	info.stage = stage;
+	info.module = shaderModule;
+
+	// Entry point in the shader
+	info.pName = "main";
+
+	return info;
+}
+
+VkPipelineVertexInputStateCreateInfo vkinit::vertex_input_state_ci()
+{
+	VkPipelineVertexInputStateCreateInfo info{};
+	info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
+	info.pNext = nullptr;
+
+	// No vertex bindings or attributes
+	info.vertexBindingDescriptionCount = 0;
+	info.vertexAttributeDescriptionCount = 0;
+
+	return info;
+}
+
+VkPipelineInputAssemblyStateCreateInfo vkinit::input_assembly_ci(VkPrimitiveTopology topology)
+{
+	VkPipelineInputAssemblyStateCreateInfo info{};
+	info.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
+	info.pNext = nullptr;
+
+	// Primitive topology
+	info.topology = topology;
+	info.primitiveRestartEnable = VK_FALSE;
+
+	return info;
+}
+
+VkPipelineRasterizationStateCreateInfo vkinit::rasterization_state_ci(VkPolygonMode polygonMode)
+{
+	VkPipelineRasterizationStateCreateInfo info{};
+	info.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
+	info.pNext = nullptr;
+
+	// How to handle polygons
+	info.depthClampEnable = VK_FALSE;
+	info.rasterizerDiscardEnable = VK_FALSE;
+
+	// How to handle filling points between vertices
+	info.polygonMode = polygonMode; // Solid / Wireframe
+	info.lineWidth = 1.0f;
+
+	// No backface culling
+	info.cullMode = VK_CULL_MODE_NONE;
+	info.frontFace = VK_FRONT_FACE_CLOCKWISE;
+
+	// No depth bias
+	info.depthBiasEnable = VK_FALSE;
+	info.depthBiasConstantFactor = 0.0f;
+	info.depthBiasClamp = 0.0f;
+	info.depthBiasSlopeFactor = 0.0f;
+
+	return info;
+}
+
+VkPipelineMultisampleStateCreateInfo vkinit::multisample_state_ci()
+{
+	VkPipelineMultisampleStateCreateInfo info{};
+	info.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
+	info.pNext = nullptr;
+
+	// No multisampling
+	info.sampleShadingEnable = VK_FALSE;
+	// 1 sample per pixel
+	info.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
+	info.minSampleShading = 1.0f;
+	info.pSampleMask = nullptr;
+	info.alphaToCoverageEnable = VK_FALSE;
+	info.alphaToOneEnable = VK_FALSE;
+
+	return info;
+}
+
+VkPipelineColorBlendAttachmentState vkinit::color_blend_attachment_state()
+{
+	VkPipelineColorBlendAttachmentState info{};
+	info.colorWriteMask = 
+		VK_COLOR_COMPONENT_R_BIT |
+		VK_COLOR_COMPONENT_G_BIT |
+		VK_COLOR_COMPONENT_B_BIT |
+		VK_COLOR_COMPONENT_A_BIT;
+	info.blendEnable = VK_FALSE;
+
+	return info;
+}
+
+VkPipelineLayoutCreateInfo vkinit::pipeline_layout_ci()
+{
+	VkPipelineLayoutCreateInfo info{};
+	info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+	info.pNext = nullptr;
+
+	// Empty defaults
+	info.flags = 0;
+	info.setLayoutCount = 0;
+	info.pSetLayouts = nullptr;
+	info.pushConstantRangeCount = 0;
+	info.pPushConstantRanges = nullptr;
+
+	return info;
+}
+
+VkImageCreateInfo vkinit::image_ci(VkFormat format, VkImageUsageFlags usageFlags, VkExtent3D extent)
+{
+	VkImageCreateInfo info = { };
+	info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+	info.pNext = nullptr;
+
+	info.imageType = VK_IMAGE_TYPE_2D;
+
+	info.format = format;
+	info.extent = extent;
+
+	info.mipLevels = 1;
+	info.arrayLayers = 1;
+	info.samples = VK_SAMPLE_COUNT_1_BIT;
+	info.tiling = VK_IMAGE_TILING_OPTIMAL;
+	info.usage = usageFlags;
+
+	return info;
+}
+
+VkImageViewCreateInfo vkinit::image_view_ci(VkFormat format, VkImage image, VkImageAspectFlags aspectFlags)
+{
+	//build a image-view for the depth image to use for rendering
+	VkImageViewCreateInfo info = {};
+	info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+	info.pNext = nullptr;
+
+	info.viewType = VK_IMAGE_VIEW_TYPE_2D;
+	info.image = image;
+	info.format = format;
+	info.subresourceRange.baseMipLevel = 0;
+	info.subresourceRange.levelCount = 1;
+	info.subresourceRange.baseArrayLayer = 0;
+	info.subresourceRange.layerCount = 1;
+	info.subresourceRange.aspectMask = aspectFlags;
+
+	return info;
+}
+
+VkPipelineDepthStencilStateCreateInfo vkinit::depth_stencil_ci(bool bDepthTest, bool bDepthWrite, VkCompareOp compareOp)
+{
+	VkPipelineDepthStencilStateCreateInfo info{};
+	info.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
+	info.pNext = nullptr;
+
+	info.depthTestEnable = bDepthTest ? VK_TRUE : VK_FALSE;
+	info.depthWriteEnable = bDepthWrite ? VK_TRUE : VK_FALSE;
+	info.depthCompareOp = bDepthTest ? compareOp : VK_COMPARE_OP_ALWAYS;
+	info.depthBoundsTestEnable = VK_FALSE;
+	info.minDepthBounds = 0.0f;
+	info.maxDepthBounds = 1.0f;
+	info.stencilTestEnable = VK_FALSE;
+
+	return info;
+}
+
+VkSamplerCreateInfo vkinit::sampler_ci(VkFilter filters, VkSamplerAddressMode samplerAddressMode)
+{
+	VkSamplerCreateInfo info{};
+	info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
+	info.pNext = nullptr;
+
+	info.magFilter = filters;
+	info.minFilter = filters;
+	info.addressModeU = samplerAddressMode;
+	info.addressModeV = samplerAddressMode;
+	info.addressModeW = samplerAddressMode;
+
+	return info;
+}
+
+VkDescriptorSetLayoutBinding vkinit::descriptor_set_layout_binding(VkDescriptorType type, VkShaderStageFlags stageFlags, uint32_t binding)
+{
+	VkDescriptorSetLayoutBinding setBind{};
+	setBind.binding = binding;
+	setBind.descriptorCount = 1;
+	setBind.descriptorType = type;
+	setBind.pImmutableSamplers = nullptr;
+	setBind.stageFlags = stageFlags;
+
+	return setBind;
+}
+
+VkWriteDescriptorSet vkinit::write_descriptor_buffer(VkDescriptorType type, VkDescriptorSet dstSet, VkDescriptorBufferInfo* bufferInfo, uint32_t binding)
+{
+	VkWriteDescriptorSet write{};
+	write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+	write.pNext = nullptr;
+
+	write.dstSet = dstSet;
+	write.dstBinding = binding;
+
+	write.descriptorCount = 1;
+	write.descriptorType = type;
+	write.pBufferInfo = bufferInfo;
+
+	return write;
+}
+
+VkWriteDescriptorSet vkinit::write_descriptor_image(VkDescriptorType type, VkDescriptorSet dstSet, VkDescriptorImageInfo* imageInfo, uint32_t binding)
+{
+	VkWriteDescriptorSet write{};
+	write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+	write.pNext = nullptr;
+
+	write.dstBinding = binding;
+	write.dstSet = dstSet;
+	write.descriptorCount = 1;
+	write.descriptorType = type;
+	write.pImageInfo = imageInfo;
+
+	return write;
+}

+ 35 - 0
coral_renderer/vk_initializers.h

@@ -0,0 +1,35 @@
+#pragma once
+#include "vk_types.h"
+
+namespace vkinit
+{
+	// Commands
+	VkCommandPoolCreateInfo command_pool_ci(uint32_t queueFamilyIndex, VkCommandPoolCreateFlags flags = 0);
+	VkCommandBufferAllocateInfo command_buffer_ai(VkCommandPool pool, uint32_t count = 1, VkCommandBufferLevel level = VK_COMMAND_BUFFER_LEVEL_PRIMARY);
+	VkCommandBufferBeginInfo command_buffer_bi(VkCommandBufferResetFlags flags = 0);
+	VkSubmitInfo submit_info(VkCommandBuffer* cmd);
+
+	// Sync structures
+	VkFenceCreateInfo fence_ci(VkFenceCreateFlags flags = 0);
+	VkSemaphoreCreateInfo semaphore_ci(VkSemaphoreCreateFlags flags = 0);
+
+	// Pipeline initializers
+	VkPipelineShaderStageCreateInfo pipeline_shader_stage_ci(VkShaderStageFlagBits stage, VkShaderModule shaderModule);
+	VkPipelineVertexInputStateCreateInfo vertex_input_state_ci();
+	VkPipelineInputAssemblyStateCreateInfo input_assembly_ci(VkPrimitiveTopology topology);
+	VkPipelineRasterizationStateCreateInfo rasterization_state_ci(VkPolygonMode polygonMode);
+	VkPipelineMultisampleStateCreateInfo multisample_state_ci();
+	VkPipelineColorBlendAttachmentState color_blend_attachment_state();
+	VkPipelineLayoutCreateInfo pipeline_layout_ci();
+
+	// Image initializers
+	VkImageCreateInfo image_ci(VkFormat format, VkImageUsageFlags usageFlags, VkExtent3D extent);
+	VkImageViewCreateInfo image_view_ci(VkFormat format, VkImage image, VkImageAspectFlags aspectFlags);
+	VkPipelineDepthStencilStateCreateInfo depth_stencil_ci(bool bDepthTest, bool bDepthWrite, VkCompareOp compareOp);
+	VkSamplerCreateInfo sampler_ci(VkFilter filters, VkSamplerAddressMode samplerAddressMode = VK_SAMPLER_ADDRESS_MODE_REPEAT);
+
+	// Descriptor set initializers
+	VkDescriptorSetLayoutBinding descriptor_set_layout_binding(VkDescriptorType type, VkShaderStageFlags stageFlags, uint32_t binding);
+	VkWriteDescriptorSet write_descriptor_buffer(VkDescriptorType type, VkDescriptorSet dstSet, VkDescriptorBufferInfo* bufferInfo, uint32_t binding);
+	VkWriteDescriptorSet write_descriptor_image(VkDescriptorType type, VkDescriptorSet dstSet, VkDescriptorImageInfo* imageInfo, uint32_t binding);
+}

+ 15 - 0
coral_renderer/vk_types.h

@@ -0,0 +1,15 @@
+#pragma once
+#include <vulkan/vulkan.h>
+#include <vk_mem_alloc.h>
+
+struct AllocatedBuffer
+{
+	VkBuffer buffer;
+	VmaAllocation allocation;
+};
+
+struct AllocatedImage
+{
+	VkImage image;
+	VmaAllocation allocation;
+};

+ 2 - 2
out/build/x64-Debug/.cmake/api/v1/reply/codemodel-v2-f38ecb006106d96b623a.json → out/build/x64-Debug/.cmake/api/v1/reply/codemodel-v2-9ed5b9eadee087677b35.json

@@ -139,14 +139,14 @@
 				{
 					"directoryIndex" : 1,
 					"id" : "Shaders::@189d46817749ee15bd40",
-					"jsonFile" : "target-Shaders-Debug-9ed77a058bf6df3681a6.json",
+					"jsonFile" : "target-Shaders-Debug-4d04420832e8090eb8fd.json",
 					"name" : "Shaders",
 					"projectIndex" : 0
 				},
 				{
 					"directoryIndex" : 1,
 					"id" : "coral_renderer::@189d46817749ee15bd40",
-					"jsonFile" : "target-coral_renderer-Debug-0baaf089c8efb44b52c5.json",
+					"jsonFile" : "target-coral_renderer-Debug-e0018bfd4eeb3d52c447.json",
 					"name" : "coral_renderer",
 					"projectIndex" : 0
 				},

+ 2 - 2
out/build/x64-Debug/.cmake/api/v1/reply/index-2023-07-03T12-17-19-0442.json → out/build/x64-Debug/.cmake/api/v1/reply/index-2023-07-03T16-34-28-0129.json

@@ -26,7 +26,7 @@
 	"objects" : 
 	[
 		{
-			"jsonFile" : "codemodel-v2-f38ecb006106d96b623a.json",
+			"jsonFile" : "codemodel-v2-9ed5b9eadee087677b35.json",
 			"kind" : "codemodel",
 			"version" : 
 			{
@@ -108,7 +108,7 @@
 						}
 					},
 					{
-						"jsonFile" : "codemodel-v2-f38ecb006106d96b623a.json",
+						"jsonFile" : "codemodel-v2-9ed5b9eadee087677b35.json",
 						"kind" : "codemodel",
 						"version" : 
 						{

+ 1 - 1
out/build/x64-Debug/.cmake/api/v1/reply/target-Shaders-Debug-9ed77a058bf6df3681a6.json → out/build/x64-Debug/.cmake/api/v1/reply/target-Shaders-Debug-4d04420832e8090eb8fd.json

@@ -18,7 +18,7 @@
 			{
 				"command" : 0,
 				"file" : 0,
-				"line" : 48,
+				"line" : 53,
 				"parent" : 0
 			}
 		]

+ 42 - 8
out/build/x64-Debug/.cmake/api/v1/reply/target-coral_renderer-Debug-0baaf089c8efb44b52c5.json → out/build/x64-Debug/.cmake/api/v1/reply/target-coral_renderer-Debug-e0018bfd4eeb3d52c447.json

@@ -46,7 +46,7 @@
 			{
 				"command" : 2,
 				"file" : 0,
-				"line" : 11,
+				"line" : 16,
 				"parent" : 0
 			},
 			{
@@ -124,20 +124,22 @@
 				0,
 				2,
 				4,
-				6
+				6,
+				8,
+				10
 			]
 		}
 	],
 	"dependencies" : 
 	[
-		{
-			"backtrace" : 3,
-			"id" : "tinyobjloader::@037116246cbfaaeb5504"
-		},
 		{
 			"backtrace" : 4,
 			"id" : "Shaders::@189d46817749ee15bd40"
 		},
+		{
+			"backtrace" : 3,
+			"id" : "tinyobjloader::@037116246cbfaaeb5504"
+		},
 		{
 			"backtrace" : 3,
 			"id" : "vkbootstrap::@037116246cbfaaeb5504"
@@ -208,7 +210,9 @@
 				0,
 				2,
 				4,
-				6
+				6,
+				8,
+				10
 			]
 		},
 		{
@@ -217,7 +221,10 @@
 			[
 				1,
 				3,
-				5
+				5,
+				7,
+				9,
+				11
 			]
 		}
 	],
@@ -261,6 +268,33 @@
 			"compileGroupIndex" : 0,
 			"path" : "coral_renderer/coral_pipeline.cpp",
 			"sourceGroupIndex" : 0
+		},
+		{
+			"backtrace" : 1,
+			"path" : "coral_renderer/coral_device.h",
+			"sourceGroupIndex" : 1
+		},
+		{
+			"backtrace" : 1,
+			"compileGroupIndex" : 0,
+			"path" : "coral_renderer/coral_device.cpp",
+			"sourceGroupIndex" : 0
+		},
+		{
+			"backtrace" : 1,
+			"path" : "coral_renderer/vk_initializers.h",
+			"sourceGroupIndex" : 1
+		},
+		{
+			"backtrace" : 1,
+			"compileGroupIndex" : 0,
+			"path" : "coral_renderer/vk_initializers.cpp",
+			"sourceGroupIndex" : 0
+		},
+		{
+			"backtrace" : 1,
+			"path" : "coral_renderer/vk_types.h",
+			"sourceGroupIndex" : 1
 		}
 	],
 	"type" : "EXECUTABLE"

BIN
out/build/x64-Debug/.ninja_deps


+ 23 - 12
out/build/x64-Debug/.ninja_log

@@ -1,6 +1,6 @@
 # ninja log v5
 83	880	7100896830474354	third_party/GLFW/src/CMakeFiles/glfw.dir/win32_window.c.obj	a8e8a800f8bba3b2
-8	177	7100896823515372	C:/Game Development/Visual Studio Solutions/Coral3D/shaders/compiled/PosNormCol.frag.spv	fe5845b8ffa9c1e4
+4	112	7100903934393469	C:/Game Development/Visual Studio Solutions/Coral3D/shaders/compiled/PosNormCol.frag.spv	fe5845b8ffa9c1e4
 49	879	7100896830274317	third_party/GLFW/src/CMakeFiles/glfw.dir/vulkan.c.obj	aa414f7e617935ab
 1622	1662	7100896838374290	third_party/tinyobjloader.lib	c2812261322ebfda
 13	183	7100896823585962	C:/Game Development/Visual Studio Solutions/Coral3D/shaders/compiled/PosNormCol.vert.spv	c8f5e229bc7280d6
@@ -8,7 +8,7 @@
 33	884	7100896830594381	third_party/GLFW/src/CMakeFiles/glfw.dir/init.c.obj	4c5b5a61c74a0503
 44	877	7100896830284325	third_party/GLFW/src/CMakeFiles/glfw.dir/monitor.c.obj	9c133f055c1c47
 78	880	7100896830464361	third_party/GLFW/src/CMakeFiles/glfw.dir/win32_thread.c.obj	ac4ae588ab2b3867
-183	1246	7100896834230582	coral_renderer/CMakeFiles/coral_renderer.dir/main.cpp.obj	f207d5295f665d92
+12	1104	7101010250284312	coral_renderer/CMakeFiles/coral_renderer.dir/main.cpp.obj	f207d5295f665d92
 60	884	7100896830574384	third_party/GLFW/src/CMakeFiles/glfw.dir/win32_init.c.obj	f9e962456dc8d656
 73	877	7100896830284325	third_party/GLFW/src/CMakeFiles/glfw.dir/win32_time.c.obj	694a8d84a0a6a42f
 64	881	7100896830464361	third_party/GLFW/src/CMakeFiles/glfw.dir/win32_joystick.c.obj	360eb123f11402ca
@@ -19,17 +19,28 @@
 884	936	7100896831119011	third_party/GLFW/src/glfw3.lib	90fe5d3bf3988c3
 55	882	7100896830514374	third_party/GLFW/src/CMakeFiles/glfw.dir/window.c.obj	b364e0375cf5f3ae
 177	854	7100896830294323	third_party/GLFW/src/CMakeFiles/glfw.dir/osmesa_context.c.obj	e9ed1005530706e4
-1783	2058	7100896841776504	coral_renderer/coral_renderer.exe	75c7a3660d6adb71
-867	1310	7100896834888700	coral_renderer/CMakeFiles/coral_renderer.dir/first_app.cpp.obj	2fa3f3bbdc72680a
+1293	1484	7101010313989280	coral_renderer/coral_renderer.exe	9430c422cdae868a
+21	816	7101010247411132	coral_renderer/CMakeFiles/coral_renderer.dir/first_app.cpp.obj	2fa3f3bbdc72680a
 22	1622	7100896837972087	third_party/CMakeFiles/tinyobjloader.dir/tinyobjloader/tiny_obj_loader.cc.obj	1e9e954b98b13f50
 18	1747	7100896839230016	third_party/CMakeFiles/vkbootstrap.dir/vkbootstrap/VkBootstrap.cpp.obj	64385be2816b800a
 10	22	0	clean	21a4d0550fd2b6b1
-855	1312	7100896834908699	coral_renderer/CMakeFiles/coral_renderer.dir/coral_window.cpp.obj	bedfd30a6102baa8
+17	901	7100924294778084	coral_renderer/CMakeFiles/coral_renderer.dir/coral_pipeline.cpp.obj	429a0363ba93b7c7
+17	793	7101010247174908	coral_renderer/CMakeFiles/coral_renderer.dir/coral_window.cpp.obj	bedfd30a6102baa8
 1747	1783	7100896839604022	third_party/vkbootstrap.lib	b339a5cc36d209fb
-4	112	7100903934393469	C:/Game Development/Visual Studio Solutions/Coral3D/shaders/compiled/PosNormCol.frag.spv	fe5845b8ffa9c1e4
-112	1081	7100903944109632	coral_renderer/CMakeFiles/coral_renderer.dir/coral_pipeline.cpp.obj	429a0363ba93b7c7
-1082	1271	7100903945238713	coral_renderer/coral_renderer.exe	e5b24f44f65d7711
-8	517	7100905499969639	coral_renderer/CMakeFiles/coral_renderer.dir/first_app.cpp.obj	2fa3f3bbdc72680a
-12	728	7100905502062287	coral_renderer/CMakeFiles/coral_renderer.dir/coral_pipeline.cpp.obj	429a0363ba93b7c7
-3	756	7100905502325432	coral_renderer/CMakeFiles/coral_renderer.dir/main.cpp.obj	f207d5295f665d92
-756	935	7100905503360420	coral_renderer/coral_renderer.exe	e5b24f44f65d7711
+11	1292	7101010312856146	coral_renderer/CMakeFiles/coral_renderer.dir/coral_device.cpp.obj	f65feb738e17e8d7
+9	92	7101052779454361	coral_renderer/CMakeFiles/coral_renderer.dir/vk_initializers.cpp.obj	e2dbff82d1c3ba0d
+12	1379	7101053002408436	coral_renderer/CMakeFiles/coral_renderer.dir/coral_device.cpp.obj	f65feb738e17e8d7
+1379	1595	7101053003792744	coral_renderer/coral_renderer.exe	20dbc57cca0c9133
+9	947	7101061569586022	coral_renderer/CMakeFiles/coral_renderer.dir/first_app.cpp.obj	2fa3f3bbdc72680a
+4	1203	7101061572146360	coral_renderer/CMakeFiles/coral_renderer.dir/main.cpp.obj	f207d5295f665d92
+15	697	7101062177889014	coral_renderer/CMakeFiles/coral_renderer.dir/first_app.cpp.obj	2fa3f3bbdc72680a
+10	905	7101062179985669	coral_renderer/CMakeFiles/coral_renderer.dir/main.cpp.obj	f207d5295f665d92
+19	930	7101062180232226	coral_renderer/CMakeFiles/coral_renderer.dir/coral_pipeline.cpp.obj	429a0363ba93b7c7
+23	1479	7101062185678497	coral_renderer/CMakeFiles/coral_renderer.dir/coral_device.cpp.obj	f65feb738e17e8d7
+1479	1667	7101062186843170	coral_renderer/coral_renderer.exe	20dbc57cca0c9133
+4	1562	7101063007902346	coral_renderer/CMakeFiles/coral_renderer.dir/coral_device.cpp.obj	f65feb738e17e8d7
+1563	1793	7101063009357869	coral_renderer/coral_renderer.exe	20dbc57cca0c9133
+12	1438	7101063203639556	coral_renderer/CMakeFiles/coral_renderer.dir/coral_device.cpp.obj	f65feb738e17e8d7
+1439	1642	7101063204872836	coral_renderer/coral_renderer.exe	20dbc57cca0c9133
+12	1293	7101063541931709	coral_renderer/CMakeFiles/coral_renderer.dir/coral_device.cpp.obj	f65feb738e17e8d7
+1293	1485	7101063543131099	coral_renderer/coral_renderer.exe	20dbc57cca0c9133

+ 2 - 2
out/build/x64-Debug/Testing/Temporary/LastTest.log

@@ -1,3 +1,3 @@
-Start testing: Jul 03 14:17 Romance Daylight Time
+Start testing: Jul 03 18:34 Romance Daylight Time
 ----------------------------------------------------------
-End testing: Jul 03 14:17 Romance Daylight Time
+End testing: Jul 03 18:34 Romance Daylight Time

+ 17 - 1
out/build/x64-Debug/build.ninja

@@ -139,6 +139,22 @@ build coral_renderer\CMakeFiles\coral_renderer.dir\coral_pipeline.cpp.obj: CXX_C
   TARGET_COMPILE_PDB = coral_renderer\CMakeFiles\coral_renderer.dir\
   TARGET_PDB = coral_renderer\coral_renderer.pdb
 
+build coral_renderer\CMakeFiles\coral_renderer.dir\coral_device.cpp.obj: CXX_COMPILER__coral_renderer_unscanned_Debug C$:\Game$ Development\Visual$ Studio$ Solutions\Coral3D\coral_renderer\coral_device.cpp || cmake_object_order_depends_target_coral_renderer
+  FLAGS = /DWIN32 /D_WINDOWS /EHsc /Zi /Ob0 /Od /RTC1 -std:c++latest -MDd /W4 /WX /w
+  INCLUDES = -I"C:\Game Development\Visual Studio Solutions\Coral3D\third_party\GLFW\include" -I"C:\Game Development\Visual Studio Solutions\Coral3D\third_party\glm" -I"C:\Game Development\Visual Studio Solutions\Coral3D\third_party\vkbootstrap" -I"C:\Game Development\Visual Studio Solutions\Coral3D\third_party\tinyobjloader" -I"C:\Game Development\Visual Studio Solutions\Coral3D\third_party\vma" -I"C:\Game Development\Visual Studio Solutions\Coral3D\third_party\stb_image" -external:IC:\VulkanSDK\1.3.250.0\Include -external:W0
+  OBJECT_DIR = coral_renderer\CMakeFiles\coral_renderer.dir
+  OBJECT_FILE_DIR = coral_renderer\CMakeFiles\coral_renderer.dir
+  TARGET_COMPILE_PDB = coral_renderer\CMakeFiles\coral_renderer.dir\
+  TARGET_PDB = coral_renderer\coral_renderer.pdb
+
+build coral_renderer\CMakeFiles\coral_renderer.dir\vk_initializers.cpp.obj: CXX_COMPILER__coral_renderer_unscanned_Debug C$:\Game$ Development\Visual$ Studio$ Solutions\Coral3D\coral_renderer\vk_initializers.cpp || cmake_object_order_depends_target_coral_renderer
+  FLAGS = /DWIN32 /D_WINDOWS /EHsc /Zi /Ob0 /Od /RTC1 -std:c++latest -MDd /W4 /WX /w
+  INCLUDES = -I"C:\Game Development\Visual Studio Solutions\Coral3D\third_party\GLFW\include" -I"C:\Game Development\Visual Studio Solutions\Coral3D\third_party\glm" -I"C:\Game Development\Visual Studio Solutions\Coral3D\third_party\vkbootstrap" -I"C:\Game Development\Visual Studio Solutions\Coral3D\third_party\tinyobjloader" -I"C:\Game Development\Visual Studio Solutions\Coral3D\third_party\vma" -I"C:\Game Development\Visual Studio Solutions\Coral3D\third_party\stb_image" -external:IC:\VulkanSDK\1.3.250.0\Include -external:W0
+  OBJECT_DIR = coral_renderer\CMakeFiles\coral_renderer.dir
+  OBJECT_FILE_DIR = coral_renderer\CMakeFiles\coral_renderer.dir
+  TARGET_COMPILE_PDB = coral_renderer\CMakeFiles\coral_renderer.dir\
+  TARGET_PDB = coral_renderer\coral_renderer.pdb
+
 
 # =============================================================================
 # Link build statements for EXECUTABLE target coral_renderer
@@ -147,7 +163,7 @@ build coral_renderer\CMakeFiles\coral_renderer.dir\coral_pipeline.cpp.obj: CXX_C
 #############################################
 # Link the executable coral_renderer\coral_renderer.exe
 
-build coral_renderer\coral_renderer.exe: CXX_EXECUTABLE_LINKER__coral_renderer_Debug coral_renderer\CMakeFiles\coral_renderer.dir\main.cpp.obj coral_renderer\CMakeFiles\coral_renderer.dir\coral_window.cpp.obj coral_renderer\CMakeFiles\coral_renderer.dir\first_app.cpp.obj coral_renderer\CMakeFiles\coral_renderer.dir\coral_pipeline.cpp.obj | C$:\VulkanSDK\1.3.250.0\Lib\vulkan-1.lib third_party\GLFW\src\glfw3.lib third_party\vkbootstrap.lib third_party\tinyobjloader.lib C$:\VulkanSDK\1.3.250.0\Lib\vulkan-1.lib || coral_renderer\Shaders third_party\GLFW\src\glfw3.lib third_party\tinyobjloader.lib third_party\vkbootstrap.lib
+build coral_renderer\coral_renderer.exe: CXX_EXECUTABLE_LINKER__coral_renderer_Debug coral_renderer\CMakeFiles\coral_renderer.dir\main.cpp.obj coral_renderer\CMakeFiles\coral_renderer.dir\coral_window.cpp.obj coral_renderer\CMakeFiles\coral_renderer.dir\first_app.cpp.obj coral_renderer\CMakeFiles\coral_renderer.dir\coral_pipeline.cpp.obj coral_renderer\CMakeFiles\coral_renderer.dir\coral_device.cpp.obj coral_renderer\CMakeFiles\coral_renderer.dir\vk_initializers.cpp.obj | C$:\VulkanSDK\1.3.250.0\Lib\vulkan-1.lib third_party\GLFW\src\glfw3.lib third_party\vkbootstrap.lib third_party\tinyobjloader.lib C$:\VulkanSDK\1.3.250.0\Lib\vulkan-1.lib || coral_renderer\Shaders third_party\GLFW\src\glfw3.lib third_party\tinyobjloader.lib third_party\vkbootstrap.lib
   FLAGS = /DWIN32 /D_WINDOWS /EHsc /Zi /Ob0 /Od /RTC1 -MDd
   LINK_FLAGS = /machine:x64 /debug /INCREMENTAL /subsystem:console
   LINK_LIBRARIES = C:\VulkanSDK\1.3.250.0\Lib\vulkan-1.lib  third_party\GLFW\src\glfw3.lib  third_party\vkbootstrap.lib  third_party\tinyobjloader.lib  C:\VulkanSDK\1.3.250.0\Lib\vulkan-1.lib  kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib

BIN
out/build/x64-Debug/coral_renderer/CMakeFiles/coral_renderer.dir/vc140.pdb


BIN
out/build/x64-Debug/coral_renderer/coral_renderer.ilk


BIN
out/build/x64-Debug/coral_renderer/coral_renderer.pdb