summaryrefslogtreecommitdiffstatsci
path: root/samples/SampleApp.cpp
diff options
context:
space:
mode:
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>2025-06-22 12:06:15 +0200
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>2025-06-22 12:06:15 +0200
commit0ca30a2d019ec31459a571dd82a36dad140df49b (patch)
tree3bb6aad41a6d518f04b72e09b98f0ff7c7abfef0 /samples/SampleApp.cpp
parent86ff26b3787c09b2e9a321d944af312b49041f08 (diff)
unified samples app in c++, unit testing wip
Diffstat (limited to 'samples/SampleApp.cpp')
-rw-r--r--samples/SampleApp.cpp253
1 files changed, 253 insertions, 0 deletions
diff --git a/samples/SampleApp.cpp b/samples/SampleApp.cpp
new file mode 100644
index 0000000..392c446
--- /dev/null
+++ b/samples/SampleApp.cpp
@@ -0,0 +1,253 @@
+#include <iostream>
+#include <stdio.h>
+
+#include "vkvg.h"
+#include "vkh.h"
+#include "vkh_phyinfo.h"
+
+#include <GLFW/glfw3.h>
+
+#include "SampleApp.hpp"
+#include "VkvgTest.hpp"
+
+
+
+bool SampleApp::try_get_phyinfo(VkhPhyInfo *phys, uint32_t phyCount, VkPhysicalDeviceType gpuType, VkhPhyInfo *phy) {
+ for (uint32_t i = 0; i < phyCount; i++) {
+ if (phys[i]->properties.deviceType == gpuType) {
+ *phy = phys[i];
+ return true;
+ }
+ }
+ return false;
+}
+
+static void glfw_error_callback(int error, const char *description) {
+ fprintf(stderr, "vkengine: GLFW error %d: %s\n", error, description);
+}
+void SampleApp::key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) {
+ if (action != GLFW_PRESS)
+ return;
+ switch (key) {
+ case GLFW_KEY_SPACE:
+ //paused = !paused;
+ break;
+ case GLFW_KEY_ESCAPE:
+ glfwSetWindowShouldClose(window, GLFW_TRUE);
+ break;
+ }
+}
+static void char_callback(GLFWwindow *window, uint32_t c) {}
+static void mouse_move_callback(GLFWwindow *window, double x, double y) {}
+static void scroll_callback(GLFWwindow *window, double x, double y) {}
+static void mouse_button_callback(GLFWwindow *window, int but, int state, int modif) {}
+
+
+void SampleApp::Init() {
+ glfwSetErrorCallback(glfw_error_callback);
+
+ if (!glfwInit()) {
+ perror("glfwInit failed");
+ exit(-1);
+ }
+
+ if (!glfwVulkanSupported()) {
+ perror("glfwVulkanSupported return false.");
+ exit(-1);
+ }
+ const char *enabledLayers[10];
+ const char *enabledExts[10];
+ uint32_t enabledExtsCount = 0, enabledLayersCount = 0, phyCount = 0;
+
+ vkh_layers_check_init();
+#ifdef VKVG_USE_VALIDATION
+ if (vkh_layer_is_present("VK_LAYER_KHRONOS_validation"))
+ enabledLayers[enabledLayersCount++] = "VK_LAYER_KHRONOS_validation";
+#endif
+#ifdef VKVG_USE_MESA_OVERLAY
+ if (vkh_layer_is_present("VK_LAYER_MESA_overlay"))
+ enabledLayers[enabledLayersCount++] = "VK_LAYER_MESA_overlay";
+#endif
+
+#ifdef VKVG_USE_RENDERDOC
+ if (vkh_layer_is_present("VK_LAYER_RENDERDOC_Capture"))
+ enabledLayers[enabledLayersCount++] = "VK_LAYER_RENDERDOC_Capture";
+#endif
+ vkh_layers_check_release();
+
+ uint32_t glfwReqExtsCount = 0;
+ const char **gflwExts = glfwGetRequiredInstanceExtensions(&glfwReqExtsCount);
+
+ vkvg_get_required_instance_extensions(enabledExts, &enabledExtsCount);
+
+ for (uint32_t i = 0; i < glfwReqExtsCount; i++)
+ enabledExts[i + enabledExtsCount] = gflwExts[i];
+
+ enabledExtsCount += glfwReqExtsCount;
+
+ app = vkh_app_create(1, 2, "vkvg", enabledLayersCount, enabledLayers, enabledExtsCount, enabledExts);
+
+#if defined(DEBUG) && defined(VKVG_DBG_UTILS)
+ uint32_t severity = 0;
+ for(const uint32_t& s : logSeverity)
+ severity += pow(16, s);
+
+ vkh_app_enable_debug_messenger(app,
+ (VkDebugUtilsMessageTypeFlagBitsEXT)logType,
+ (VkDebugUtilsMessageSeverityFlagBitsEXT)severity,
+ NULL);
+#endif
+ glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
+ glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
+ glfwWindowHint(GLFW_FLOATING, GLFW_FALSE);
+ glfwWindowHint(GLFW_DECORATED, GLFW_TRUE);
+
+ win = glfwCreateWindow((int)width, (int)height, "Window Title", NULL, NULL);
+
+ glfwCreateWindowSurface(vkh_app_get_inst(app), win, NULL, &vkSurf);
+
+ VkhPhyInfo *phys = vkh_app_get_phyinfos(app, &phyCount, vkSurf);
+
+ if (listGpus) {
+ std::cout << "Available GPU's:" << std::endl;
+ std::cout << "================" << std::endl;
+ for (uint32_t i = 0; i < phyCount; i++) {
+ std::cout << "\t" << i << ": " << phys[i]->properties.deviceName << std::endl;
+ }
+ vkh_app_free_phyinfos(phyCount, phys);
+ vkDestroySurfaceKHR(vkh_app_get_inst(app), vkSurf, NULL);
+ glfwDestroyWindow(win);
+ vkh_app_destroy(app);
+ glfwTerminate();
+ exit(0);
+ }
+
+ VkhPhyInfo pi = 0;
+ if (gpuIndex > 0 && gpuIndex < phyCount) {
+ pi = phys[gpuIndex];
+ } else {
+ if (!try_get_phyinfo(phys, phyCount, preferedGPU, &pi) &&
+ !try_get_phyinfo(phys, phyCount, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, &pi) &&
+ !try_get_phyinfo(phys, phyCount, VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, &pi))
+ pi = phys[0];
+ }
+ assert(pi && "No vulkan physical device found.");
+
+ memory_properties = pi->memProps;
+ gpu_props = pi->properties;
+
+ uint32_t qCount = 0;
+ float qPriorities[] = {0.0};
+
+ VkDeviceQueueCreateInfo pQueueInfos[] = {{}, {}, {}};
+ if (vkh_phyinfo_create_presentable_queues(pi, 1, qPriorities, &pQueueInfos[qCount]))
+ qCount++;
+ /*if (vkh_phyinfo_create_compute_queues (pi, 1, qPriorities, &pQueueInfos[qCount]))
+ qCount++;
+ if (vkh_phyinfo_create_transfer_queues (pi, 1, qPriorities, &pQueueInfos[qCount]))
+ qCount++;*/
+
+ enabledExtsCount = 0;
+
+ if (vkvg_get_required_device_extensions(pi->phy, enabledExts, &enabledExtsCount) != VKVG_STATUS_SUCCESS) {
+ perror("vkvg_get_required_device_extensions failed, enable log for details.\n");
+ exit(-1);
+ }
+ TRY_LOAD_DEVICE_EXT(VK_KHR_swapchain)
+
+ VkPhysicalDeviceFeatures enabledFeatures{};
+ const void *pNext = vkvg_get_device_requirements(&enabledFeatures);
+
+ VkDeviceCreateInfo device_info = {.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
+ .pNext = pNext,
+ .queueCreateInfoCount = qCount,
+ .pQueueCreateInfos = (VkDeviceQueueCreateInfo *)&pQueueInfos,
+ .enabledExtensionCount = enabledExtsCount,
+ .ppEnabledExtensionNames = enabledExts,
+ .pEnabledFeatures = &enabledFeatures,
+ };
+
+ vkhDev = vkh_device_create(app, pi, &device_info);
+ presentQIndex = (uint32_t)pi->pQueue;
+ renderer =
+ vkh_presenter_create(vkhDev, presentQIndex, vkSurf, width, height, VK_FORMAT_B8G8R8A8_SRGB, presentMode);
+
+
+ vkh_app_free_phyinfos(phyCount, phys);
+
+ glfwSetKeyCallback(win, key_callback);
+ glfwSetMouseButtonCallback(win, mouse_button_callback);
+ glfwSetCursorPosCallback(win, mouse_move_callback);
+
+}
+
+void SampleApp::Run() {
+ uint32_t curIter = 0;
+
+ if (VkvgTest::tests.empty())
+ return;
+
+ int testIdx = 0;
+ auto it = VkvgTest::tests.begin();
+ VkvgTest* curTest = NULL;
+
+ if (testsToRun.empty()) {
+ curTest = (*it);
+ } else {
+ curTest = VkvgTest::tests[testsToRun[testIdx]];
+ }
+
+ glfwSetWindowTitle(win, curTest->name.c_str());
+ curTest->initTest(this);
+
+ while (!glfwWindowShouldClose(win)) {
+ glfwPollEvents();
+
+ curTest->performTest();
+
+ if (!vkh_presenter_draw(renderer)) {
+ vkh_presenter_get_size(renderer, &width, &height);
+ curTest->cleanTest();
+ curTest->initTest(this);
+ continue;
+ }
+
+ if (iterations > 0) {
+ if (++curIter == iterations) {
+ testIdx++;
+ curTest->cleanTest();
+ if (testsToRun.empty()) {
+ if (++it == VkvgTest::tests.end()){
+ curTest = NULL;
+ break;
+ }
+ curTest = (*it);
+ } else {
+ if (testIdx == testsToRun.size()) {
+ curTest = NULL;
+ break;
+ }
+ curTest = VkvgTest::tests[testsToRun[testIdx]];
+ }
+
+ curIter = 0;
+ glfwSetWindowTitle(win, curTest->name.c_str());
+ curTest->initTest(this);
+ }
+ }
+ }
+ if (curTest != NULL)
+ curTest->cleanTest();
+}
+
+void SampleApp::CleanUp() {
+ vkDeviceWaitIdle(vkh_device_get_vkdev(vkhDev));
+ vkh_presenter_destroy(renderer);
+ vkDestroySurfaceKHR(vkh_app_get_inst(app), vkSurf, NULL);
+
+ vkh_device_destroy(vkhDev);
+ glfwDestroyWindow(win);
+ vkh_app_destroy(app);
+
+ glfwTerminate();
+}