From 802e5aeed730c800924906525a1e23187d908d71 Mon Sep 17 00:00:00 2001
From: Tobias Frisch <tfrisch@uni-koblenz.de>
Date: Fri, 23 Apr 2021 17:54:55 +0200
Subject: [PATCH] Added basic cmake configuration and dummy Context class

---
 .gitignore                             |  7 ++++
 .gitmodules                            |  3 ++
 CMakeLists.txt                         | 44 ++++++++++++++++++++
 config/Libraries.cmake                 | 32 +++++++++++++++
 config/Sources.cmake                   |  5 +++
 config/ext/CheckLibraries.cmake        | 53 ++++++++++++++++++++++++
 config/lib/GLFW.cmake                  | 18 +++++++++
 config/lib/Vulkan.cmake                |  9 +++++
 lib/glfw                               |  1 +
 projects/CMakeLists.txt                |  2 +
 projects/first_triangle/CMakeLists.txt | 10 +++++
 projects/first_triangle/src/main.cpp   | 14 +++++++
 src/vkcv/Context.cpp                   | 56 ++++++++++++++++++++++++++
 src/vkcv/Context.hpp                   | 28 +++++++++++++
 14 files changed, 282 insertions(+)
 create mode 100644 .gitignore
 create mode 100644 .gitmodules
 create mode 100644 CMakeLists.txt
 create mode 100644 config/Libraries.cmake
 create mode 100644 config/Sources.cmake
 create mode 100644 config/ext/CheckLibraries.cmake
 create mode 100644 config/lib/GLFW.cmake
 create mode 100644 config/lib/Vulkan.cmake
 create mode 160000 lib/glfw
 create mode 100644 projects/CMakeLists.txt
 create mode 100644 projects/first_triangle/CMakeLists.txt
 create mode 100644 projects/first_triangle/src/main.cpp
 create mode 100644 src/vkcv/Context.cpp
 create mode 100644 src/vkcv/Context.hpp

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..9cbe5077
--- /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 00000000..b44e4738
--- /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 00000000..5ebce0ba
--- /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 00000000..3b4c75ea
--- /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 00000000..f25104e9
--- /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 00000000..97950d11
--- /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 00000000..1b68d8aa
--- /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 00000000..e8fe4aee
--- /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 00000000..0e9ec778
--- /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 00000000..27305956
--- /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 00000000..c5a90468
--- /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 00000000..25e26a68
--- /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 00000000..bfad8c96
--- /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 00000000..f3736276
--- /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);
+		
+	};
+
+}
-- 
GitLab