diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..9cbe5077139237928e7d6c2a843526b547ec5282 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.project +.cproject +.idea/ + +build/ +cmake-build-debug/ +cmake-build-release/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000000000000000000000000000000000..b44e47387fc30a41c3f5c8d09b5ad525b354f233 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "lib/glfw"] + path = lib/glfw + url = https://github.com/glfw/glfw.git diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..5ebce0ba8054e3fcce8be4f9c7299038422e5c73 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,44 @@ +cmake_minimum_required(VERSION 3.16) +project(vkcv) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +message("-- Language: [ C++ " ${CMAKE_CXX_STANDARD} " ]") + +set(vkcv_config ${PROJECT_SOURCE_DIR}/config) +set(vkcv_config_ext ${vkcv_config}/ext) + +set(vkcv_lib lib) + +set(vkcv_source ${PROJECT_SOURCE_DIR}/src) + +set(vkcv_flags ${CMAKE_CXX_FLAGS}) + +include(${vkcv_config}/Sources.cmake) +include(${vkcv_config}/Libraries.cmake) + +set(CMAKE_CXX_FLAGS ${vkcv_flags}) + +message("-- Flags: [ ${CMAKE_CXX_FLAGS} ]") + +add_compile_definitions(${vkcv_definitions}) + +if (vkcv_directories) + include_directories(${vkcv_directories}) +endif() + +add_library(vkcv SHARED ${vkcv_sources}) + +if(MSVC) + #enable multicore compilation on visual studio + target_compile_options(vkcv PRIVATE "/MP" "/openmp") + + #set source groups to create proper filters in visual studio + source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${vkcv_sources}) +endif() + +target_include_directories(vkcv SYSTEM BEFORE PRIVATE ${vkcv_includes}) +target_link_libraries(vkcv ${vkcv_libraries}) + +add_subdirectory(projects) diff --git a/config/Libraries.cmake b/config/Libraries.cmake new file mode 100644 index 0000000000000000000000000000000000000000..3b4c75ead3998641e3868ade305f281b3ce1bd93 --- /dev/null +++ b/config/Libraries.cmake @@ -0,0 +1,32 @@ +set(vkcv_config_lib ${vkcv_config}/lib) + +set(vkcv_lib_path ${PROJECT_SOURCE_DIR}/${vkcv_lib}) + +if(NOT WIN32) + set(vkcv_libraries stdc++fs) + + # optimization for loading times + list(APPEND vkcv_flags -pthread) + list(APPEND vkcv_flags -fopenmp) +endif() + +set(vkcv_config_msg " - Library: ") + +include(${vkcv_config_lib}/GLFW.cmake) # glfw-x11 / glfw-wayland # libglfw3-dev +include(${vkcv_config_lib}/Vulkan.cmake) # vulkan-intel / vulkan-radeon / nvidia # libvulkan-dev + +if (vkcv_flags) + list(REMOVE_DUPLICATES vkcv_flags) +endif() + +if (vkcv_includes) + list(REMOVE_DUPLICATES vkcv_includes) +endif () + +include(${vkcv_config_ext}/CheckLibraries.cmake) + +if (vkcv_definitions) + list(REMOVE_DUPLICATES vkcv_definitions) +endif () + +list(JOIN vkcv_flags " " vkcv_flags) diff --git a/config/Sources.cmake b/config/Sources.cmake new file mode 100644 index 0000000000000000000000000000000000000000..f25104e9df248d07dd0cd864d56645db8ed422d7 --- /dev/null +++ b/config/Sources.cmake @@ -0,0 +1,5 @@ + +set(vkcv_sources + ${vkcv_source}/vkcv/Context.hpp + ${vkcv_source}/vkcv/Context.cpp +) diff --git a/config/ext/CheckLibraries.cmake b/config/ext/CheckLibraries.cmake new file mode 100644 index 0000000000000000000000000000000000000000..97950d1123f126cc555f376b86c90ed1acb2628e --- /dev/null +++ b/config/ext/CheckLibraries.cmake @@ -0,0 +1,53 @@ + +list(REMOVE_DUPLICATES vkcv_libraries) + +foreach (a_lib IN LISTS vkcv_libraries) + if (NOT EXISTS "${a_lib}") + string(REGEX MATCH ^/usr/lib/x86_64-linux-gnu/.*$ vkcv_usr_lib_u_match ${a_lib}) + + if (vkcv_usr_lib_u_match) + string(SUBSTRING ${vkcv_usr_lib_u_match} 26 -1 a_lib) + + list(REMOVE_ITEM vkcv_libraries ${vkcv_usr_lib_u_match}) + list(APPEND vkcv_libraries_ext ${a_lib}) + else () + string(REGEX MATCH ^/usr/lib/.*$ vkcv_usr_lib_match ${a_lib}) + string(REGEX MATCH ^/lib/.*$ a_lib_match ${a_lib}) + + if (vkcv_usr_lib_match) + list(REMOVE_ITEM vkcv_libraries ${a_lib}) + + string(SUBSTRING ${vkcv_usr_lib_match} 8 -1 a_lib) + set(a_lib "/usr/lib/x86_64-linux-gnu${a_lib}") + + if (EXISTS ${a_lib}) + list(APPEND vkcv_libraries_ext ${a_lib}) + endif () + elseif (a_lib_match) + list(REMOVE_ITEM vkcv_libraries ${a_lib}) + + string(SUBSTRING ${a_lib_match} 4 -1 a_lib) + set(a_lib "/usr/lib/x86_64-linux-gnu${a_lib}") + + if (EXISTS ${a_lib}) + list(APPEND vkcv_libraries_ext ${a_lib}) + endif () + else () + string(REGEX MATCH ^-l.*$ a_lib_match ${a_lib}) + + if (a_lib_match) + string(SUBSTRING ${a_lib_match} 2 -1 a_lib) + + list(REMOVE_ITEM vkcv_libraries ${a_lib_match}) + list(APPEND vkcv_libraries_ext ${a_lib}) + endif () + endif () + endif () + endif () +endforeach () + +foreach (a_lib IN LISTS vkcv_libraries_ext) + list(APPEND vkcv_libraries ${a_lib}) +endforeach () + + diff --git a/config/lib/GLFW.cmake b/config/lib/GLFW.cmake new file mode 100644 index 0000000000000000000000000000000000000000..1b68d8aa97ba59158a7bd805ab2470f554f705aa --- /dev/null +++ b/config/lib/GLFW.cmake @@ -0,0 +1,18 @@ + +find_package(glfw3 QUIET) + +if (glfw3_FOUND) + list(APPEND vkcv_libraries glfw) + + message(${vkcv_config_msg} " GLFW - " ${glfw3_VERSION}) +else() + if (EXISTS "${vkcv_lib_path}/glfw") + add_subdirectory(${vkcv_lib}/glfw) + + list(APPEND vkcv_libraries glfw) + + message(${vkcv_config_msg} " GLFW - " ${glfw3_VERSION}) + else() + message(WARNING "GLFW is required..! Update the submodules!") + endif () +endif () diff --git a/config/lib/Vulkan.cmake b/config/lib/Vulkan.cmake new file mode 100644 index 0000000000000000000000000000000000000000..e8fe4aee3a949fa7bf9906558f8a0c558eb47cf2 --- /dev/null +++ b/config/lib/Vulkan.cmake @@ -0,0 +1,9 @@ + +find_package(Vulkan REQUIRED) + +if (Vulkan_FOUND) + list(APPEND vkcv_includes ${Vulkan_INCLUDE_DIR}) + list(APPEND vkcv_libraries ${Vulkan_LIBRARIES}) + + message(${vkcv_config_msg} " Vulkan - ") +endif () diff --git a/lib/glfw b/lib/glfw new file mode 160000 index 0000000000000000000000000000000000000000..0e9ec7788b4985a0df698080258e4091d18dcc3b --- /dev/null +++ b/lib/glfw @@ -0,0 +1 @@ +Subproject commit 0e9ec7788b4985a0df698080258e4091d18dcc3b diff --git a/projects/CMakeLists.txt b/projects/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..27305956cac6670331096364a6658a90efcc831b --- /dev/null +++ b/projects/CMakeLists.txt @@ -0,0 +1,2 @@ + +add_subdirectory(first_triangle) diff --git a/projects/first_triangle/CMakeLists.txt b/projects/first_triangle/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..c5a9046881dbab737b357b8a3cd875a9c6b284ae --- /dev/null +++ b/projects/first_triangle/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 3.16) +project(first_triangle) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +add_executable(first_triangle src/main.cpp) + +target_include_directories(first_triangle SYSTEM BEFORE PRIVATE ${vkcv_source} ${vkcv_includes}) +target_link_libraries(first_triangle vkcv ${vkcv_libraries}) diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..25e26a682943f4b095b647034eb7aaa18342a3af --- /dev/null +++ b/projects/first_triangle/src/main.cpp @@ -0,0 +1,14 @@ + +#include <iostream> +#include <vkcv/Context.hpp> + +int main(int argc, const char** argv) { + vkcv::Context context = vkcv::Context::create( + "First Triangle", + VK_MAKE_VERSION(0, 0, 1) + ); + + std::cout << "Hello world" << std::endl; + + return 0; +} diff --git a/src/vkcv/Context.cpp b/src/vkcv/Context.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bfad8c96c322f8004c26dd7f7f0e9ba50b65aab3 --- /dev/null +++ b/src/vkcv/Context.cpp @@ -0,0 +1,56 @@ + +#include "Context.hpp" + +namespace vkcv { + + Context::Context(vk::Instance instance, vk::PhysicalDevice physicalDevice, vk::Device device) + : m_instance(instance), m_physicalDevice(physicalDevice), m_device(device) + {} + + Context::~Context() { + m_device.destroy(); + m_instance.destroy(); + } + + Context Context::create(const char* applicationName, uint32_t applicationVersion) { + const vk::ApplicationInfo applicationInfo ( + applicationName, + applicationVersion, + "vkCV", + VK_MAKE_VERSION(0, 0, 1), + VK_HEADER_VERSION_COMPLETE + ); + + // TODO: enable validation layers in debug build and add required extensions + const vk::InstanceCreateInfo instanceCreateInfo ( + vk::InstanceCreateFlags(), + &applicationInfo, + 0, + nullptr, + 0, + nullptr + ); + + vk::Instance instance = vk::createInstance(instanceCreateInfo); + + // TODO: search for the best physical device (discrete GPU) + vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices()[0]; + + // TODO: create required queues, add validation layers and required extensions + const vk::DeviceCreateInfo deviceCreateInfo ( + vk::DeviceCreateFlags(), + 0, + nullptr, + 0, + nullptr, + 0, + nullptr, + nullptr + ); + + vk::Device device = physicalDevice.createDevice(deviceCreateInfo); + + return Context(instance, physicalDevice, device); + } + +} diff --git a/src/vkcv/Context.hpp b/src/vkcv/Context.hpp new file mode 100644 index 0000000000000000000000000000000000000000..f3736276770af720442452a66708a2bbcd58fd04 --- /dev/null +++ b/src/vkcv/Context.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include <vulkan/vulkan.hpp> + +namespace vkcv { + + class Context final { + private: + vk::Instance m_instance; + vk::PhysicalDevice m_physicalDevice; + vk::Device m_device; + + Context(vk::Instance instance, vk::PhysicalDevice physicalDevice, vk::Device device); + + public: + Context(const Context &other) = delete; + Context(Context &&other) = default; + + virtual ~Context(); + + Context& operator=(const Context &other) = delete; + Context& operator=(Context &&other) = default; + + static Context create(const char* applicationName, uint32_t applicationVersion); + + }; + +}