Skip to content

Commit 0ca30a2

Browse files
committed
unified samples app in c++, unit testing wip
1 parent 86ff26b commit 0ca30a2

37 files changed

+3991
-15
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ IF(GLSLC AND XXD)
224224
GET_FILENAME_COMPONENT(SPV ${shad_spv} NAME)
225225
ADD_CUSTOM_COMMAND (
226226
TARGET BuildShadersHeader
227+
PRE_BUILD
227228
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${SHADER_DIR}
228229
COMMAND ${XXD} -i ${SPV} >> ${SHADERS_H}
229230
)
@@ -328,6 +329,7 @@ INSTALL(TARGETS "${PROJECT_NAME}" "${PROJECT_NAME}"
328329

329330
IF (VKVG_BUILD_TESTS)
330331
ADD_SUBDIRECTORY(tests)
332+
ADD_SUBDIRECTORY(samples)
331333
ELSEIF (VKVG_BUILD_OFFSCREEN_TEST)
332334
ADD_EXECUTABLE(test_offscreen "${CMAKE_CURRENT_SOURCE_DIR}/tests/offscreen.c")
333335
TARGET_INCLUDE_DIRECTORIES(test_offscreen PRIVATE

gunit_tests/drawTestBase.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ void DrawTestBase::compareWithRefImage() {
6767

6868
if (totDiff > 0) {
6969
fs::path diffPath = diffDir / ::testing::UnitTest::GetInstance()->current_test_info()->name();
70-
targetPath.replace_extension(".png");
70+
diffPath.replace_extension(".png");
7171
stbi_write_png((char*)diffPath.c_str(), (int32_t)w, (int32_t)h, 4, diffImg, (int32_t)(4 * w));
7272
}
7373

gunit_tests/imageDraw.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
class ImageDrawTest : public DrawTestBase {
44

55
protected:
6-
fs::path imgPath = fs::path(GTEST_DATA_ROOT) / "miroir2.png";
6+
fs::path imgPath = fs::path(GTEST_DATA_ROOT) / "mirror2.png";
77
VkvgSurface imgSurf;
88

99
void SetUp() override {
@@ -100,7 +100,7 @@ TEST_F(ImageDrawTest, PaintImageTransform) {
100100
vkvg_set_source_rgb(ctx, 0.5f, 0.5f, 0.5f);
101101
vkvg_paint(ctx);
102102

103-
fs::path imgPath = fs::path(GTEST_DATA_ROOT) / "miroir2-64.png";
103+
fs::path imgPath = fs::path(GTEST_DATA_ROOT) / "mirror2-64.png";
104104
VkvgSurface imgSurf = vkvg_surface_create_from_image(dev, (char*)imgPath.c_str());
105105

106106
vkvg_translate(ctx, 10, 10);

gunit_tests/patternDraw.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
class PatternDrawTest : public DrawTestBase {
44

55
protected:
6-
fs::path imgPath = fs::path(GTEST_DATA_ROOT) / "miroir2.png";
6+
fs::path imgPath = fs::path(GTEST_DATA_ROOT) / "mirror2.png";
77
VkvgSurface imgSurf;
88

99
void SetUp() override {

samples/CMakeLists.txt

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
cmake_minimum_required(VERSION 3.14)
2+
project(samples)
3+
4+
# GoogleTest requires at least C++14
5+
set(CMAKE_CXX_STANDARD 17)
6+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
7+
8+
include(FetchContent)
9+
10+
FetchContent_Declare(
11+
argparse
12+
GIT_REPOSITORY https://github.com/p-ranav/argparse
13+
GIT_TAG 3eda91b2e1ce7d569f84ba295507c4cd8fd96910 #v3.2
14+
)
15+
16+
FetchContent_MakeAvailable(argparse)
17+
18+
set(SAMPLES_DATA_ROOT "${CMAKE_SOURCE_DIR}/tests/data" CACHE STRING "Data path for samples")
19+
20+
file(GLOB SAMPLES_SRC "*.cpp" "tests/*.cpp")
21+
22+
add_executable("${PROJECT_NAME}" ${SAMPLES_SRC})
23+
24+
target_compile_definitions("${PROJECT_NAME}" PUBLIC
25+
SAMPLES_DATA_ROOT="${GTEST_DATA_ROOT}"
26+
)
27+
target_include_directories("${PROJECT_NAME}" PUBLIC
28+
"${CMAKE_CURRENT_SOURCE_DIR}"
29+
"${CMAKE_SOURCE_DIR}/include"
30+
${GLFW3_INCLUDE_DIR}
31+
${Vulkan_INCLUDE_DIRS}
32+
"${CMAKE_SOURCE_DIR}/vkh/include"
33+
"${CMAKE_SOURCE_DIR}/vkh/src"
34+
)
35+
target_link_libraries("${PROJECT_NAME}"
36+
vkvg
37+
${Vulkan_LIBRARIES}
38+
${GLFW3_LIBRARY}
39+
argparse
40+
)
41+
42+
43+
44+
45+

samples/SampleApp.cpp

Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
#include <iostream>
2+
#include <stdio.h>
3+
4+
#include "vkvg.h"
5+
#include "vkh.h"
6+
#include "vkh_phyinfo.h"
7+
8+
#include <GLFW/glfw3.h>
9+
10+
#include "SampleApp.hpp"
11+
#include "VkvgTest.hpp"
12+
13+
14+
15+
bool SampleApp::try_get_phyinfo(VkhPhyInfo *phys, uint32_t phyCount, VkPhysicalDeviceType gpuType, VkhPhyInfo *phy) {
16+
for (uint32_t i = 0; i < phyCount; i++) {
17+
if (phys[i]->properties.deviceType == gpuType) {
18+
*phy = phys[i];
19+
return true;
20+
}
21+
}
22+
return false;
23+
}
24+
25+
static void glfw_error_callback(int error, const char *description) {
26+
fprintf(stderr, "vkengine: GLFW error %d: %s\n", error, description);
27+
}
28+
void SampleApp::key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) {
29+
if (action != GLFW_PRESS)
30+
return;
31+
switch (key) {
32+
case GLFW_KEY_SPACE:
33+
//paused = !paused;
34+
break;
35+
case GLFW_KEY_ESCAPE:
36+
glfwSetWindowShouldClose(window, GLFW_TRUE);
37+
break;
38+
}
39+
}
40+
static void char_callback(GLFWwindow *window, uint32_t c) {}
41+
static void mouse_move_callback(GLFWwindow *window, double x, double y) {}
42+
static void scroll_callback(GLFWwindow *window, double x, double y) {}
43+
static void mouse_button_callback(GLFWwindow *window, int but, int state, int modif) {}
44+
45+
46+
void SampleApp::Init() {
47+
glfwSetErrorCallback(glfw_error_callback);
48+
49+
if (!glfwInit()) {
50+
perror("glfwInit failed");
51+
exit(-1);
52+
}
53+
54+
if (!glfwVulkanSupported()) {
55+
perror("glfwVulkanSupported return false.");
56+
exit(-1);
57+
}
58+
const char *enabledLayers[10];
59+
const char *enabledExts[10];
60+
uint32_t enabledExtsCount = 0, enabledLayersCount = 0, phyCount = 0;
61+
62+
vkh_layers_check_init();
63+
#ifdef VKVG_USE_VALIDATION
64+
if (vkh_layer_is_present("VK_LAYER_KHRONOS_validation"))
65+
enabledLayers[enabledLayersCount++] = "VK_LAYER_KHRONOS_validation";
66+
#endif
67+
#ifdef VKVG_USE_MESA_OVERLAY
68+
if (vkh_layer_is_present("VK_LAYER_MESA_overlay"))
69+
enabledLayers[enabledLayersCount++] = "VK_LAYER_MESA_overlay";
70+
#endif
71+
72+
#ifdef VKVG_USE_RENDERDOC
73+
if (vkh_layer_is_present("VK_LAYER_RENDERDOC_Capture"))
74+
enabledLayers[enabledLayersCount++] = "VK_LAYER_RENDERDOC_Capture";
75+
#endif
76+
vkh_layers_check_release();
77+
78+
uint32_t glfwReqExtsCount = 0;
79+
const char **gflwExts = glfwGetRequiredInstanceExtensions(&glfwReqExtsCount);
80+
81+
vkvg_get_required_instance_extensions(enabledExts, &enabledExtsCount);
82+
83+
for (uint32_t i = 0; i < glfwReqExtsCount; i++)
84+
enabledExts[i + enabledExtsCount] = gflwExts[i];
85+
86+
enabledExtsCount += glfwReqExtsCount;
87+
88+
app = vkh_app_create(1, 2, "vkvg", enabledLayersCount, enabledLayers, enabledExtsCount, enabledExts);
89+
90+
#if defined(DEBUG) && defined(VKVG_DBG_UTILS)
91+
uint32_t severity = 0;
92+
for(const uint32_t& s : logSeverity)
93+
severity += pow(16, s);
94+
95+
vkh_app_enable_debug_messenger(app,
96+
(VkDebugUtilsMessageTypeFlagBitsEXT)logType,
97+
(VkDebugUtilsMessageSeverityFlagBitsEXT)severity,
98+
NULL);
99+
#endif
100+
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
101+
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
102+
glfwWindowHint(GLFW_FLOATING, GLFW_FALSE);
103+
glfwWindowHint(GLFW_DECORATED, GLFW_TRUE);
104+
105+
win = glfwCreateWindow((int)width, (int)height, "Window Title", NULL, NULL);
106+
107+
glfwCreateWindowSurface(vkh_app_get_inst(app), win, NULL, &vkSurf);
108+
109+
VkhPhyInfo *phys = vkh_app_get_phyinfos(app, &phyCount, vkSurf);
110+
111+
if (listGpus) {
112+
std::cout << "Available GPU's:" << std::endl;
113+
std::cout << "================" << std::endl;
114+
for (uint32_t i = 0; i < phyCount; i++) {
115+
std::cout << "\t" << i << ": " << phys[i]->properties.deviceName << std::endl;
116+
}
117+
vkh_app_free_phyinfos(phyCount, phys);
118+
vkDestroySurfaceKHR(vkh_app_get_inst(app), vkSurf, NULL);
119+
glfwDestroyWindow(win);
120+
vkh_app_destroy(app);
121+
glfwTerminate();
122+
exit(0);
123+
}
124+
125+
VkhPhyInfo pi = 0;
126+
if (gpuIndex > 0 && gpuIndex < phyCount) {
127+
pi = phys[gpuIndex];
128+
} else {
129+
if (!try_get_phyinfo(phys, phyCount, preferedGPU, &pi) &&
130+
!try_get_phyinfo(phys, phyCount, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, &pi) &&
131+
!try_get_phyinfo(phys, phyCount, VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, &pi))
132+
pi = phys[0];
133+
}
134+
assert(pi && "No vulkan physical device found.");
135+
136+
memory_properties = pi->memProps;
137+
gpu_props = pi->properties;
138+
139+
uint32_t qCount = 0;
140+
float qPriorities[] = {0.0};
141+
142+
VkDeviceQueueCreateInfo pQueueInfos[] = {{}, {}, {}};
143+
if (vkh_phyinfo_create_presentable_queues(pi, 1, qPriorities, &pQueueInfos[qCount]))
144+
qCount++;
145+
/*if (vkh_phyinfo_create_compute_queues (pi, 1, qPriorities, &pQueueInfos[qCount]))
146+
qCount++;
147+
if (vkh_phyinfo_create_transfer_queues (pi, 1, qPriorities, &pQueueInfos[qCount]))
148+
qCount++;*/
149+
150+
enabledExtsCount = 0;
151+
152+
if (vkvg_get_required_device_extensions(pi->phy, enabledExts, &enabledExtsCount) != VKVG_STATUS_SUCCESS) {
153+
perror("vkvg_get_required_device_extensions failed, enable log for details.\n");
154+
exit(-1);
155+
}
156+
TRY_LOAD_DEVICE_EXT(VK_KHR_swapchain)
157+
158+
VkPhysicalDeviceFeatures enabledFeatures{};
159+
const void *pNext = vkvg_get_device_requirements(&enabledFeatures);
160+
161+
VkDeviceCreateInfo device_info = {.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
162+
.pNext = pNext,
163+
.queueCreateInfoCount = qCount,
164+
.pQueueCreateInfos = (VkDeviceQueueCreateInfo *)&pQueueInfos,
165+
.enabledExtensionCount = enabledExtsCount,
166+
.ppEnabledExtensionNames = enabledExts,
167+
.pEnabledFeatures = &enabledFeatures,
168+
};
169+
170+
vkhDev = vkh_device_create(app, pi, &device_info);
171+
presentQIndex = (uint32_t)pi->pQueue;
172+
renderer =
173+
vkh_presenter_create(vkhDev, presentQIndex, vkSurf, width, height, VK_FORMAT_B8G8R8A8_SRGB, presentMode);
174+
175+
176+
vkh_app_free_phyinfos(phyCount, phys);
177+
178+
glfwSetKeyCallback(win, key_callback);
179+
glfwSetMouseButtonCallback(win, mouse_button_callback);
180+
glfwSetCursorPosCallback(win, mouse_move_callback);
181+
182+
}
183+
184+
void SampleApp::Run() {
185+
uint32_t curIter = 0;
186+
187+
if (VkvgTest::tests.empty())
188+
return;
189+
190+
int testIdx = 0;
191+
auto it = VkvgTest::tests.begin();
192+
VkvgTest* curTest = NULL;
193+
194+
if (testsToRun.empty()) {
195+
curTest = (*it);
196+
} else {
197+
curTest = VkvgTest::tests[testsToRun[testIdx]];
198+
}
199+
200+
glfwSetWindowTitle(win, curTest->name.c_str());
201+
curTest->initTest(this);
202+
203+
while (!glfwWindowShouldClose(win)) {
204+
glfwPollEvents();
205+
206+
curTest->performTest();
207+
208+
if (!vkh_presenter_draw(renderer)) {
209+
vkh_presenter_get_size(renderer, &width, &height);
210+
curTest->cleanTest();
211+
curTest->initTest(this);
212+
continue;
213+
}
214+
215+
if (iterations > 0) {
216+
if (++curIter == iterations) {
217+
testIdx++;
218+
curTest->cleanTest();
219+
if (testsToRun.empty()) {
220+
if (++it == VkvgTest::tests.end()){
221+
curTest = NULL;
222+
break;
223+
}
224+
curTest = (*it);
225+
} else {
226+
if (testIdx == testsToRun.size()) {
227+
curTest = NULL;
228+
break;
229+
}
230+
curTest = VkvgTest::tests[testsToRun[testIdx]];
231+
}
232+
233+
curIter = 0;
234+
glfwSetWindowTitle(win, curTest->name.c_str());
235+
curTest->initTest(this);
236+
}
237+
}
238+
}
239+
if (curTest != NULL)
240+
curTest->cleanTest();
241+
}
242+
243+
void SampleApp::CleanUp() {
244+
vkDeviceWaitIdle(vkh_device_get_vkdev(vkhDev));
245+
vkh_presenter_destroy(renderer);
246+
vkDestroySurfaceKHR(vkh_app_get_inst(app), vkSurf, NULL);
247+
248+
vkh_device_destroy(vkhDev);
249+
glfwDestroyWindow(win);
250+
vkh_app_destroy(app);
251+
252+
glfwTerminate();
253+
}

0 commit comments

Comments
 (0)