diff --git a/.gitmodules b/.gitmodules index f476259..9957619 100644 --- a/.gitmodules +++ b/.gitmodules @@ -37,3 +37,7 @@ path = external/physfs/physfs url = https://github.com/icculus/physfs.git branch = main +[submodule "external/Vulkan-Headers"] + path = external/Vulkan-Headers + url = https://github.com/KhronosGroup/Vulkan-Headers.git + shallow = true diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index aa4c6e9..6b9f60a 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -38,6 +38,9 @@ if(NOT MM_HEADLESS) add_subdirectory("glad-debug") endif() + add_subdirectory("Vulkan-Headers") + target_compile_definitions(Vulkan-Headers INTERFACE VULKAN_HPP_DISPATCH_LOADER_DYNAMIC=1) + # stb utilies add_subdirectory("stb") diff --git a/external/Vulkan-Headers b/external/Vulkan-Headers new file mode 160000 index 0000000..245d25c --- /dev/null +++ b/external/Vulkan-Headers @@ -0,0 +1 @@ +Subproject commit 245d25ce8c3337919dc7916d0e62e31a0d8748ab diff --git a/framework/CMakeLists.txt b/framework/CMakeLists.txt index 822919f..0ad0dcb 100644 --- a/framework/CMakeLists.txt +++ b/framework/CMakeLists.txt @@ -17,6 +17,7 @@ if(NOT MM_HEADLESS) add_subdirectory(simple_sdl_renderer) add_subdirectory(opengl_primitives) add_subdirectory(opengl_renderer) + add_subdirectory(vulkan_renderer) add_subdirectory(imgui) add_subdirectory(input) add_subdirectory(sound) diff --git a/framework/sdl_service/CMakeLists.txt b/framework/sdl_service/CMakeLists.txt index 4ca7020..98b4b16 100644 --- a/framework/sdl_service/CMakeLists.txt +++ b/framework/sdl_service/CMakeLists.txt @@ -40,6 +40,9 @@ else() target_link_libraries(sdl_service glad) endif() +# nope +#target_link_libraries(sdl_service Vulkan::Headers) + if(VCPKG_TARGET_TRIPLET) target_link_libraries(sdl_service SDL2::SDL2 SDL2::SDL2main SDL2::SDL2-static) endif() diff --git a/framework/sdl_service/test/CMakeLists.txt b/framework/sdl_service/test/CMakeLists.txt index d3f6046..d01ccc6 100644 --- a/framework/sdl_service/test/CMakeLists.txt +++ b/framework/sdl_service/test/CMakeLists.txt @@ -1,4 +1,6 @@ -add_executable(sdl_service_test start_test.cpp) +add_executable(sdl_service_test + ./start_test.cpp +) target_include_directories(sdl_service_test PRIVATE ".") diff --git a/framework/vulkan_renderer/CMakeLists.txt b/framework/vulkan_renderer/CMakeLists.txt new file mode 100644 index 0000000..a101f33 --- /dev/null +++ b/framework/vulkan_renderer/CMakeLists.txt @@ -0,0 +1,26 @@ +cmake_minimum_required(VERSION 3.9 FATAL_ERROR) + +project(vulkan_renderer CXX) + +add_library(vulkan_renderer + src/mm/services/vulkan_renderer.hpp + src/mm/services/vulkan_renderer.cpp +) + +target_include_directories(vulkan_renderer PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/src") + +target_link_libraries(vulkan_renderer + Vulkan::Headers + + engine + logger + + sdl_service +) + +######################## + +if (BUILD_TESTING) + add_subdirectory(test) +endif() + diff --git a/framework/vulkan_renderer/src/mm/services/vulkan_renderer.cpp b/framework/vulkan_renderer/src/mm/services/vulkan_renderer.cpp new file mode 100644 index 0000000..b4d1483 --- /dev/null +++ b/framework/vulkan_renderer/src/mm/services/vulkan_renderer.cpp @@ -0,0 +1,652 @@ +#include "./vulkan_renderer.hpp" + +#include +#include + +#include + +// mf ycm, FIXME: remove before merge +#include +#include +#include +#include +#include + +#include + +// HACK +namespace { // dont leak linkage +#include +#include + +// meh, we dont have the type, only the value +//static_assert(alignof(tut1_vert_spv) == alignof(uint32_t)); +//static_assert(alignof(tut1_frag_spv) == alignof(uint32_t)); +} + +#include + +// https://youtu.be/eaKeeRngZBo + +// this needs to be defined only once +VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE + +// create a dispatcher, based on additional vkDevice/vkGetDeviceProcAddr +static void setup_dispacher(void) { + // both should work + // but vk::DynamicLoader reloads the dll, so it will be open more then once + // and also might be a different one from sdl +#if 0 + static vk::DynamicLoader dl; + PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = dl.getProcAddress("vkGetInstanceProcAddr"); +#else + auto load_res = SDL_Vulkan_LoadLibrary(nullptr); + assert(load_res == 0); + PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = reinterpret_cast(SDL_Vulkan_GetVkGetInstanceProcAddr()); +#endif + + VULKAN_HPP_DEFAULT_DISPATCHER.init(vkGetInstanceProcAddr); +} + +static bool can_use_layer(std::string_view layer_want) { + for (const auto& layer : vk::enumerateInstanceLayerProperties()) { + if (static_cast(layer.layerName) == layer_want) { + return true; + } + } + + return false; +} + +VKAPI_ATTR VkBool32 VKAPI_CALL debug_callback( + VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, + VkDebugUtilsMessageTypeFlagsEXT messageType, + const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, + void* /*pUserData*/ +) { + spdlog::level::level_enum level{}; + switch (messageSeverity) { + case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT: + level = spdlog::level::level_enum::debug; + break; + case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT: + level = spdlog::level::level_enum::info; + break; + case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT: + level = spdlog::level::level_enum::warn; + break; + case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT: + level = spdlog::level::level_enum::err; + break; + default: + level = spdlog::level::level_enum::critical; // what ever + } + + switch (messageType) { + case VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT: + spdlog::get("VulkanGeneral")->log(level, "{}", pCallbackData->pMessage); + break; + case VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT: + spdlog::get("VulkanValidation")->log(level, "{}", pCallbackData->pMessage); + break; + case VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT: + spdlog::get("VulkanPerformance")->log(level, "{}", pCallbackData->pMessage); + break; + } + + return VK_FALSE; +} + +static const vk::DebugUtilsMessengerCreateInfoEXT debug_utils_messenger_create_info{ + {}, + vk::DebugUtilsMessageSeverityFlagBitsEXT::eError + | vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning + | vk::DebugUtilsMessageSeverityFlagBitsEXT::eInfo + | vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose, + vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral + | vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation + | vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance, + debug_callback +}; + +static vk::Instance create_instance( + const vk::ApplicationInfo& app_info, + std::vector extensions = {}, + std::vector layers = {} +) { + // for debugging + extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); + + // Get the required extension count + unsigned int count; + if (SDL_Vulkan_GetInstanceExtensions(nullptr, &count, nullptr) != SDL_TRUE) { + return nullptr; + } + + size_t additional_extension_count = extensions.size(); + extensions.resize(additional_extension_count + count); + + // fill sdl extensions + if (SDL_Vulkan_GetInstanceExtensions(nullptr, &count, extensions.data() + additional_extension_count) != SDL_TRUE) { + return nullptr; + } + + // Now we can make the Vulkan instance + vk::StructureChain c{ + vk::InstanceCreateInfo{ + {}, + &app_info, + static_cast(layers.size()), + layers.data(), + static_cast(extensions.size()), + extensions.data() + }, + debug_utils_messenger_create_info + }; + + vk::Instance instance = vk::createInstance(c.get(), nullptr); + + // initialize function pointers for instance + VULKAN_HPP_DEFAULT_DISPATCHER.init(instance); + + return instance; +} + +namespace MM::Services { + +VulkanRenderer::VulkanRenderer(void) { +#if 0 + MM::Logger::initSectionLogger("VulkanGeneral"); + // way too noisy otherwise + spdlog::get("VulkanGeneral")->set_level(spdlog::level::level_enum::warn); +#else + // or just dont log to stdio? + MM::Logger::initSectionLogger("VulkanGeneral", false); +#endif + MM::Logger::initSectionLogger("VulkanValidation"); + MM::Logger::initSectionLogger("VulkanPerformance"); + + SPDLOG_INFO("constructed VulkanRenderer"); +} + +VulkanRenderer::~VulkanRenderer(void) { +} + +bool VulkanRenderer::enable(Engine&, std::vector& task_array) { + assert(!VULKAN_HPP_DEFAULT_DISPATCHER.vkEnumerateInstanceLayerProperties); + setup_dispacher(); + assert(VULKAN_HPP_DEFAULT_DISPATCHER.vkEnumerateInstanceLayerProperties); + + // TODO: user configurable + const vk::ApplicationInfo app_info { + "app_name", + VK_MAKE_VERSION(1, 0, 0), // app version + "MushMachine", + // TODO: engine version macro or something + VK_MAKE_VERSION(0, 8, 0), // engine version + VK_API_VERSION_1_1 + }; + + // TODO: make validation layer conditional + std::vector layers{}; + + if (can_use_layer("VK_LAYER_KHRONOS_validation")) { + layers.push_back("VK_LAYER_KHRONOS_validation"); + SPDLOG_INFO("ENABLED validation layer"); + } else { + SPDLOG_INFO("validation layer NOT AVAILABLE!"); + } + + vk::Instance instance = create_instance( + app_info, + {}, + layers + ); + _instance = instance; + + // TODO: dont require this? + _debug_messenger = instance.createDebugUtilsMessengerEXT(debug_utils_messenger_create_info); + + _swapchain_curr_idx = 0; // important + + { // add task + task_array.push_back( + UpdateStrategies::TaskInfo{"VulkanRenderer::render"} + .phase(UpdateStrategies::update_phase_t::POST) // *smirk* + .fn([this](Engine& e){ this->render(e); }) + ); + } + + return true; +} + +void VulkanRenderer::disable(Engine&) { + // cleanup + if (_device) { + vk::Device device{_device}; + + auto device_destroy_each = [&device](auto& container) { + for (const auto& it : container) { + device.destroy(it); + } + }; + + auto device_destroy_each_kv = [&device](auto& map) { + for (const auto& it : map) { + device.destroy(it.second); + } + }; + + device.waitIdle(); + + // resouce cache + device_destroy_each_kv(_r_shader_module); + + device_destroy_each(_swapchain_framebuffers); + device_destroy_each(_swapchain_image_views); + device.destroy(_swapchain); + device_destroy_each(_swapchain_sem_image_available); + device_destroy_each(_swapchain_sem_render_finished); + device_destroy_each(_swapchain_fence_in_flight); + device.destroy(); + } + + vk::Instance instance{_instance}; + instance.destroy(_surface); + instance.destroy(_debug_messenger); + instance.destroy(); +} + +void VulkanRenderer::render(Engine&) { + vk::Device device{_device}; + vk::SwapchainKHR swapchain{_swapchain}; + + // wait for next fb/img/img_view to be free again + // in most cases there are 2 but might be 1 or more + vk::Fence in_flight{_swapchain_fence_in_flight.at(_swapchain_curr_idx)}; + auto wait_in_flight_res = device.waitForFences(in_flight, true, UINT64_MAX); + device.resetFences(in_flight); + + uint32_t next_img_index = device.acquireNextImageKHR( + _swapchain, + UINT64_MAX, + _swapchain_sem_image_available.at(_swapchain_curr_idx) + ).value; + + { + auto g_queue = vk::Queue{_graphics_queue}; + // do the commands n stuff + + // queue submit + vk::Semaphore tmp_sem_wait{_swapchain_sem_image_available.at(_swapchain_curr_idx)}; + vk::PipelineStageFlags tmp_sem_wait_stages{vk::PipelineStageFlagBits::eColorAttachmentOutput}; + vk::Semaphore tmp_sem_sig{_swapchain_sem_render_finished.at(_swapchain_curr_idx)}; + g_queue.submit({vk::SubmitInfo{ + tmp_sem_wait, + tmp_sem_wait_stages, + {}, + tmp_sem_sig + }}, _swapchain_fence_in_flight.at(_swapchain_curr_idx)); + } + + { // queue present + auto p_queue = vk::Queue{_graphics_queue}; // TODO: present queue + + vk::Semaphore tmp_sem_wait{_swapchain_sem_render_finished.at(_swapchain_curr_idx)}; + auto present_res = p_queue.presentKHR(vk::PresentInfoKHR{ + tmp_sem_wait, + swapchain, + // _swapchain_curr_idx + next_img_index + }); + + } + // next image (everything) + _swapchain_curr_idx = (_swapchain_curr_idx + 1) % _swapchain_images.size(); +} + +bool VulkanRenderer::createDevice(Engine& engine) { + // the surface for the window (not device dependent) + if (SDL_Vulkan_CreateSurface(engine.getService().win, _instance, &_surface) != SDL_TRUE) { + SPDLOG_ERROR("creating vulkan surface from window. (is the SDL_WINDOW_VULKAN flag set?)"); + return false; + } + + // convenience hpp wrapper + assert(_surface); + vk::SurfaceKHR surface{_surface}; + assert(_instance); + vk::Instance instance{_instance}; + + auto physical_devices = instance.enumeratePhysicalDevices(); + if (physical_devices.empty()) { + SPDLOG_ERROR("no physical vulkan devices found"); + return false; + } + + // list devices + for (const auto& ph_device : physical_devices) { + auto props = ph_device.getProperties(); + SPDLOG_INFO( + "found device: [{}] ({}) '{}'", + props.deviceID, + (props.deviceType == vk::PhysicalDeviceType::eDiscreteGpu ? "discrete" : "other"), + props.deviceName + ); + } + + auto& selected_phys_dev = physical_devices.front(); + _physical_device = selected_phys_dev; + + for (const auto& fam_props : selected_phys_dev.getQueueFamilyProperties()) { + auto test_bit = [](const auto& flags, const auto& bit) -> bool { + return (flags & bit) == bit; + }; + SPDLOG_INFO( + "QueueFamily: queueCount:{} graphics:{} compute:{} transfer:{}", + fam_props.queueCount, + test_bit(fam_props.queueFlags, vk::QueueFlagBits::eGraphics) ? "true" : "false", + test_bit(fam_props.queueFlags, vk::QueueFlagBits::eCompute) ? "true" : "false", + test_bit(fam_props.queueFlags, vk::QueueFlagBits::eTransfer) ? "true" : "false" + ); + } + + uint32_t queue_fam_index = 0; + + // test for support for swapchain + if (selected_phys_dev.getSurfaceSupportKHR(queue_fam_index, surface) != VK_TRUE) { + SPDLOG_ERROR("selected device does not support the surface"); + return false; + } + + const float queue_prio = 1.f; // hmmmm + vk::DeviceQueueCreateInfo graphics_queue_create_info { + {}, + queue_fam_index, // just pick the first one for now + 1, // count + &queue_prio + }; + + vk::PhysicalDeviceFeatures device_features { + }; + + // do i need this? + std::vector device_extentions{ + VK_KHR_SWAPCHAIN_EXTENSION_NAME + }; + + vk::DeviceCreateInfo device_create_info { + {}, + 1, + &graphics_queue_create_info, + // layers + 0, + nullptr, + // extensions + static_cast(device_extentions.size()), + device_extentions.data(), + &device_features + }; + vk::Device device = selected_phys_dev.createDevice(device_create_info, nullptr); + _device = device; + + // function pointer specialization for device + VULKAN_HPP_DEFAULT_DISPATCHER.init(device); + + //_present_queue = device.getQueue(0, 0); + // we assume it also does present + _graphics_queue = device.getQueue(0, 0); + + + return true; +} + +bool VulkanRenderer::createSwapchain(Engine& engine) { + assert(_physical_device); + vk::PhysicalDevice physical_device {_physical_device}; + assert(_device); + vk::Device device {_device}; + + vk::SurfaceFormatKHR swap_surf_format { + vk::Format::eB8G8R8A8Srgb, + vk::ColorSpaceKHR::eSrgbNonlinear, + }; + { // select format + //for (const auto& format : selected_phys_dev.getSurfaceFormatsKHR(surface)) { + //if (format.colorSpace == vk::ColorSpaceKHR::eSrgbNonlinear) { + //if (format.format == vk::Format::eB8G8R8A8Srgb) { + + //} + //} + //} + } + + vk::Extent2D surface_extent {}; + { + int w, h; + SDL_Vulkan_GetDrawableSize(engine.getService().win, &w, &h); + surface_extent.width = w; + surface_extent.height = h; + } + + auto phys_surf_caps = physical_device.getSurfaceCapabilitiesKHR(_surface); + + // flush all loggers + spdlog::apply_all([](const auto& logger) { logger->flush(); }); + + assert(VULKAN_HPP_DEFAULT_DISPATCHER.vkCreateSwapchainKHR); + + // create the swapchain + _swapchain = device.createSwapchainKHR({ + {}, + _surface, + phys_surf_caps.minImageCount, + swap_surf_format.format, + swap_surf_format.colorSpace, + surface_extent, + 1, // imageArrayLayers + vk::ImageUsageFlagBits::eColorAttachment, + vk::SharingMode::eExclusive, + // TODO: fill in rest + }); + + { + _swapchain_images.clear(); + auto images = device.getSwapchainImagesKHR(_swapchain); + for (const auto& img : images) { + _swapchain_images.push_back(img); + } + } + SPDLOG_INFO("have {} swapchain images", _swapchain_images.size()); + + _swapchain_image_views.clear(); + for (const auto& img : _swapchain_images) { + _swapchain_image_views.push_back(device.createImageView({ + {}, + img, + vk::ImageViewType::e2D, + swap_surf_format.format, + {}, // comp mapping + { // subres + vk::ImageAspectFlagBits::eColor, + 0, + 1, + 0, + 1, + }, + })); + } + + + // TODO: move + + // TODO: refactor, provide "primitive" wrapper like opengl + auto create_shader_module = [&](const uint8_t* data, const size_t size) -> vk::ShaderModule { + return device.createShaderModule(vk::ShaderModuleCreateInfo{ + {}, + size, + reinterpret_cast(data) + }); + }; + + using namespace entt::literals; + + auto vert_module = create_shader_module(tut1_vert_spv, tut1_vert_spv_len); + _r_shader_module["tut1_vert"_hs] = vert_module; + auto frag_module = create_shader_module(tut1_frag_spv, tut1_frag_spv_len); + _r_shader_module["tut1_frag"_hs] = frag_module; + + std::vector pl_shader_ci { + { + {}, + vk::ShaderStageFlagBits::eVertex, + vert_module, + "main", + }, + { + {}, + vk::ShaderStageFlagBits::eFragment, + frag_module, + "main", + } + }; + + std::vector pl_vertex_input_ci { + // hardcoded in shader, so no actual data here + {}, + {}, // do i need two? + }; + + vk::PipelineInputAssemblyStateCreateInfo pl_input_asm_ci { + {}, + vk::PrimitiveTopology::eTriangleList, + VK_FALSE + }; + + // rn whole screen + vk::Viewport viewport { + 0.f, // x + 0.f, // y + static_cast(surface_extent.width), + static_cast(surface_extent.height), + 0.f, // min depth + 1.f, // max depth + }; + + // whole screen + vk::Rect2D scissor { + {0, 0}, // offset + surface_extent + }; + + vk::PipelineViewportStateCreateInfo pl_viewport_state_ci { + {}, + 1, + &viewport, + 1, + &scissor, + }; + + vk::PipelineRasterizationStateCreateInfo pl_raster_state_ci { + {}, + VK_FALSE, // depth clamp + VK_FALSE, // discard + vk::PolygonMode::eFill, + //vk::CullModeFlagBits::eBack, + vk::CullModeFlagBits::eNone, // TODO: enable, just debug now + vk::FrontFace::eClockwise, // TODO: determain what the engine uses normally + VK_FALSE, + 0.f, 0.f, 0.f, + 1.f, // line width + }; + + // default for vkhpp is disabled + vk::PipelineMultisampleStateCreateInfo pl_ms_state_ci {}; + + vk::PipelineColorBlendAttachmentState pl_color_blend_attachment_state { + VK_FALSE, + + vk::BlendFactor::eOne, + vk::BlendFactor::eZero, + + vk::BlendOp::eAdd, + + vk::BlendFactor::eOne, + vk::BlendFactor::eZero, + + vk::BlendOp::eAdd, + + vk::ColorComponentFlagBits::eR + | vk::ColorComponentFlagBits::eG + | vk::ColorComponentFlagBits::eB + | vk::ColorComponentFlagBits::eA, + }; + + vk::PipelineColorBlendStateCreateInfo pl_color_blend_state_ci { + {}, + VK_FALSE, + vk::LogicOp::eCopy, + 1, + &pl_color_blend_attachment_state, + { 0.f, 0.f, 0.f, 0.f }, + }; + + //std::vector pl_dyn_states { + //vk::DynamicState::eViewport, + //vk::DynamicState::eLineWidth, + //}; + + vk::PipelineLayout pl_layout = device.createPipelineLayout({ + {}, + + 0, + {}, + 0, + {} + }); + + device.createGraphicsPipeline({}, { + {}, + static_cast(pl_shader_ci.size()), + pl_shader_ci.data(), + pl_vertex_input_ci.data(), + &pl_input_asm_ci, + {}, + &pl_viewport_state_ci, + &pl_raster_state_ci, + &pl_ms_state_ci, + {}, // d'n's + &pl_color_blend_state_ci, + {}, // dyn + pl_layout, + }); + + _swapchain_framebuffers.clear(); + for (const auto& img_view : _swapchain_image_views) { + vk::ImageView tmp_img_view = img_view; + _swapchain_framebuffers.push_back(device.createFramebuffer({ + {}, + {}, // rend + 1, + &tmp_img_view, + surface_extent.width, + surface_extent.height, + 1 + })); + } + + // TODO: max simultanious frames + _swapchain_sem_image_available.clear(); + _swapchain_sem_render_finished.clear(); + _swapchain_fence_in_flight.clear(); + for (size_t i = 0; i < _swapchain_images.size(); i++) { + _swapchain_sem_image_available.push_back(device.createSemaphore(vk::SemaphoreCreateInfo{})); + _swapchain_sem_render_finished.push_back(device.createSemaphore(vk::SemaphoreCreateInfo{})); + _swapchain_fence_in_flight.push_back(device.createFence({vk::FenceCreateFlagBits::eSignaled})); + } + + return true; +} + +} // MM::Services + diff --git a/framework/vulkan_renderer/src/mm/services/vulkan_renderer.hpp b/framework/vulkan_renderer/src/mm/services/vulkan_renderer.hpp new file mode 100644 index 0000000..964e08d --- /dev/null +++ b/framework/vulkan_renderer/src/mm/services/vulkan_renderer.hpp @@ -0,0 +1,93 @@ +#pragma once + +#include "entt/core/hashed_string.hpp" +#include +#include +#include + +// fwd vk stuff + +#define MM_VK_DEFINE_HANDLE(object) typedef struct object##_T* object; +// TODO: determain what we use +//#ifndef VK_DEFINE_NON_DISPATCHABLE_HANDLE + //#if (VK_USE_64_BIT_PTR_DEFINES==1) + #define MM_VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object; + //#else + //#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object; + //#endif +//#endif + +MM_VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBuffer) +MM_VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImage) +MM_VK_DEFINE_HANDLE(VkInstance) +MM_VK_DEFINE_HANDLE(VkPhysicalDevice) +MM_VK_DEFINE_HANDLE(VkDevice) +MM_VK_DEFINE_HANDLE(VkQueue) +MM_VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSemaphore) +MM_VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFence) +MM_VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImageView) +MM_VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFramebuffer) +MM_VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkShaderModule) + +// extensions +MM_VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugUtilsMessengerEXT) +MM_VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR) +MM_VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSwapchainKHR) + +namespace MM::Services { + +class VulkanRenderer : public Service { + private: + // lets use the c-api types + VkInstance _instance{}; + VkDebugUtilsMessengerEXT _debug_messenger{}; + + VkSurfaceKHR _surface{}; + + VkPhysicalDevice _physical_device{}; + VkDevice _device{}; + + VkQueue _graphics_queue{}; + //VkQueue _present_queue{}; + + VkSwapchainKHR _swapchain{}; + uint32_t _swapchain_curr_idx{}; + std::vector _swapchain_images{}; + std::vector _swapchain_image_views{}; + std::vector _swapchain_framebuffers{}; + + std::vector _swapchain_sem_image_available{}; + std::vector _swapchain_sem_render_finished{}; + std::vector _swapchain_fence_in_flight{}; + + // resource cache + std::unordered_map _r_shader_module{}; + + public: + VulkanRenderer(void); + ~VulkanRenderer(void); + + private: // Service interface + bool enable(Engine& engine, std::vector& task_array) override; + void disable(Engine& engine) override; + + const char* name(void) override { return "VulkanRenderer"; } + + void render(Engine& engine); + + public: + bool createDevice(Engine& engine); + + bool createSwapchain(Engine& engine); + + //VkShaderModule getR_shader_module(const entt::hashed_string::value_type key) { + //return _r_shader_module.at(key); + //} + + //VkShaderModule getR_shader_module(const char* key) { + //return getR_shader_module(entt::hashed_string::value(key)); + //} +}; + +} // MM::Services + diff --git a/framework/vulkan_renderer/src/mm/vulkan/res/tut1.frag b/framework/vulkan_renderer/src/mm/vulkan/res/tut1.frag new file mode 100644 index 0000000..76bdf57 --- /dev/null +++ b/framework/vulkan_renderer/src/mm/vulkan/res/tut1.frag @@ -0,0 +1,10 @@ +#version 450 + +layout(location = 0) in vec3 fragColor; + +layout(location = 0) out vec4 outColor; + +void main() { + outColor = vec4(fragColor, 1.0); +} + diff --git a/framework/vulkan_renderer/src/mm/vulkan/res/tut1.frag.spv b/framework/vulkan_renderer/src/mm/vulkan/res/tut1.frag.spv new file mode 100644 index 0000000..a94fd39 Binary files /dev/null and b/framework/vulkan_renderer/src/mm/vulkan/res/tut1.frag.spv differ diff --git a/framework/vulkan_renderer/src/mm/vulkan/res/tut1.frag.spv.h b/framework/vulkan_renderer/src/mm/vulkan/res/tut1.frag.spv.h new file mode 100644 index 0000000..800a5a5 --- /dev/null +++ b/framework/vulkan_renderer/src/mm/vulkan/res/tut1.frag.spv.h @@ -0,0 +1,45 @@ +alignas(uint32_t) unsigned char tut1_frag_spv[] = { + 0x03, 0x02, 0x23, 0x07, 0x00, 0x03, 0x01, 0x00, 0x0a, 0x00, 0x08, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, + 0x02, 0x00, 0x00, 0x00, 0xc2, 0x01, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00, 0x00, 0x6f, 0x75, 0x74, 0x43, + 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x66, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, + 0x72, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, + 0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00 +}; +unsigned int tut1_frag_spv_len = 500; diff --git a/framework/vulkan_renderer/src/mm/vulkan/res/tut1.vert b/framework/vulkan_renderer/src/mm/vulkan/res/tut1.vert new file mode 100644 index 0000000..f8a9a20 --- /dev/null +++ b/framework/vulkan_renderer/src/mm/vulkan/res/tut1.vert @@ -0,0 +1,21 @@ +#version 450 + +layout(location = 0) out vec3 fragColor; + +vec2 positions[3] = vec2[]( + vec2(0.0, -0.5), + vec2(0.5, 0.5), + vec2(-0.5, 0.5) +); + +vec3 colors[3] = vec3[]( + vec3(1.0, 0.0, 0.0), + vec3(0.0, 1.0, 0.0), + vec3(0.0, 0.0, 1.0) +); + +void main() { + gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0); + fragColor = colors[gl_VertexIndex]; +} + diff --git a/framework/vulkan_renderer/src/mm/vulkan/res/tut1.vert.spv b/framework/vulkan_renderer/src/mm/vulkan/res/tut1.vert.spv new file mode 100644 index 0000000..3f0f5fe Binary files /dev/null and b/framework/vulkan_renderer/src/mm/vulkan/res/tut1.vert.spv differ diff --git a/framework/vulkan_renderer/src/mm/vulkan/res/tut1.vert.spv.h b/framework/vulkan_renderer/src/mm/vulkan/res/tut1.vert.spv.h new file mode 100644 index 0000000..727df2d --- /dev/null +++ b/framework/vulkan_renderer/src/mm/vulkan/res/tut1.vert.spv.h @@ -0,0 +1,123 @@ +alignas(uint32_t) unsigned char tut1_vert_spv[] = { + 0x03, 0x02, 0x23, 0x07, 0x00, 0x03, 0x01, 0x00, 0x0a, 0x00, 0x08, 0x00, + 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, + 0x22, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc2, 0x01, 0x00, 0x00, + 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x04, 0x00, 0x17, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x73, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x67, 0x6c, 0x5f, 0x50, 0x65, 0x72, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x00, 0x06, 0x00, 0x07, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x69, 0x6e, 0x74, + 0x53, 0x69, 0x7a, 0x65, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x07, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x43, + 0x6c, 0x69, 0x70, 0x44, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x00, + 0x06, 0x00, 0x07, 0x00, 0x20, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x67, 0x6c, 0x5f, 0x43, 0x75, 0x6c, 0x6c, 0x44, 0x69, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x00, 0x05, 0x00, 0x03, 0x00, 0x22, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x26, 0x00, 0x00, 0x00, + 0x67, 0x6c, 0x5f, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x49, 0x6e, 0x64, + 0x65, 0x78, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x31, 0x00, 0x00, 0x00, + 0x66, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x05, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x05, 0x00, 0x20, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, + 0x26, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, + 0x47, 0x00, 0x04, 0x00, 0x31, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x16, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0x2c, 0x00, 0x05, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x2c, 0x00, 0x05, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x2c, 0x00, 0x06, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, + 0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x2c, 0x00, 0x06, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x06, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x06, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x06, 0x00, + 0x15, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, + 0x1d, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x04, 0x00, 0x1f, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x06, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x1f, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, + 0x21, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x21, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, + 0x23, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x04, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x23, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x25, 0x00, 0x00, 0x00, + 0x26, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, + 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x04, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x1d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x04, 0x00, 0x33, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0xf8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x17, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x23, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x28, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, + 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, + 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00, 0x1d, 0x00, 0x00, 0x00, + 0x2d, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x2e, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, + 0x24, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x2f, 0x00, 0x00, 0x00, + 0x2d, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, + 0x32, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x33, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, + 0x32, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x35, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, + 0x38, 0x00, 0x01, 0x00 +}; +unsigned int tut1_vert_spv_len = 1432; diff --git a/framework/vulkan_renderer/test/CMakeLists.txt b/framework/vulkan_renderer/test/CMakeLists.txt new file mode 100644 index 0000000..cb88cf3 --- /dev/null +++ b/framework/vulkan_renderer/test/CMakeLists.txt @@ -0,0 +1,13 @@ +add_executable(vulkan_renderer_test + ./vulkan_test.cpp +) + +target_include_directories(vulkan_renderer_test PRIVATE ".") + +target_link_libraries(vulkan_renderer_test + vulkan_renderer + gtest_main +) + +add_test(NAME vulkan_renderer_test COMMAND vulkan_renderer_test) + diff --git a/framework/vulkan_renderer/test/vulkan_test.cpp b/framework/vulkan_renderer/test/vulkan_test.cpp new file mode 100644 index 0000000..19cb05d --- /dev/null +++ b/framework/vulkan_renderer/test/vulkan_test.cpp @@ -0,0 +1,37 @@ +#include + +#include +#include +#include + +#include + +TEST(sdl_service, window_vulkan) { + MM::Engine engine; + + engine.addService(); + ASSERT_TRUE(engine.enableService()); + + auto* sdl_ss_ptr = engine.tryService(); + ASSERT_NE(sdl_ss_ptr, nullptr); + + // create window + ASSERT_EQ(sdl_ss_ptr->win, nullptr); + ASSERT_TRUE(sdl_ss_ptr->createWindow("test vulkan window", 800, 600, SDL_WINDOW_VULKAN)); + ASSERT_NE(sdl_ss_ptr->win, nullptr); + + engine.addService(); + ASSERT_TRUE(engine.enableService()); + + auto& vk_rend = engine.getService(); + ASSERT_TRUE(vk_rend.createDevice(engine)); + ASSERT_TRUE(vk_rend.createSwapchain(engine)); + + //engine.run(); + + engine.disableService(); + engine.disableService(); + + ASSERT_EQ(sdl_ss_ptr->win, nullptr); +} +